Skip to content

Commit 0798eab

Browse files
authored
gov2: create example code for cloudfront (#5156)
1 parent 518ee6d commit 0798eab

File tree

4 files changed

+348
-0
lines changed

4 files changed

+348
-0
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
// snippet-start:[cloudfront.go-v2.CreateDistribution]
5+
6+
package main
7+
8+
import (
9+
"context"
10+
"errors"
11+
"flag"
12+
"fmt"
13+
"log"
14+
15+
"github.com/aws/aws-sdk-go-v2/aws"
16+
"github.com/aws/aws-sdk-go-v2/config"
17+
"github.com/aws/aws-sdk-go-v2/service/cloudfront"
18+
cloudfrontTypes "github.com/aws/aws-sdk-go-v2/service/cloudfront/types"
19+
"github.com/aws/aws-sdk-go-v2/service/s3"
20+
)
21+
22+
// CFDistributionAPI defines the interface for the CreateDistribution function.
23+
// We use this interface to test the function using a mocked service.
24+
type CFDistributionAPI interface {
25+
CreateDistribution(bucketName, certificateSSLArn, domain string) (*cloudfront.CreateDistributionOutput, error)
26+
createoriginAccessIdentity(domainName string) (string, error)
27+
}
28+
29+
type CFDistributionAPIImpl struct {
30+
s3Client *s3.Client
31+
cloudfrontClient *cloudfront.Client
32+
}
33+
34+
func createCFDistribution(s3client *s3.Client, cloudfront *cloudfront.Client) CFDistributionAPI {
35+
return &CFDistributionAPIImpl{
36+
s3Client: s3client,
37+
cloudfrontClient: cloudfront,
38+
}
39+
}
40+
41+
func (c *CFDistributionAPIImpl) CreateDistribution(bucketName, certificateSSLArn, domain string) (*cloudfront.CreateDistributionOutput, error) {
42+
locationOutput, err := c.s3Client.GetBucketLocation(context.Background(), &s3.GetBucketLocationInput{Bucket: aws.String(bucketName)})
43+
44+
if err != nil {
45+
return nil, err
46+
}
47+
originDomain := bucketName + ".s3." + string(locationOutput.LocationConstraint) + ".amazonaws.com"
48+
49+
if err != nil {
50+
return nil, err
51+
}
52+
53+
originAccessIdentityID, err := c.createoriginAccessIdentity(domain)
54+
if err != nil {
55+
return nil, err
56+
}
57+
58+
cloudfrontResponse, err := c.cloudfrontClient.CreateDistribution(context.TODO(), &cloudfront.CreateDistributionInput{
59+
DistributionConfig: &cloudfrontTypes.DistributionConfig{
60+
Enabled: aws.Bool(true),
61+
CallerReference: &originDomain,
62+
Comment: &originDomain,
63+
IsIPV6Enabled: aws.Bool(false),
64+
PriceClass: cloudfrontTypes.PriceClassPriceClass100,
65+
HttpVersion: cloudfrontTypes.HttpVersionHttp11,
66+
DefaultRootObject: aws.String("index.html"),
67+
Aliases: &cloudfrontTypes.Aliases{
68+
Quantity: aws.Int32(1),
69+
Items: []string{domain},
70+
},
71+
ViewerCertificate: &cloudfrontTypes.ViewerCertificate{
72+
ACMCertificateArn: aws.String(certificateSSLArn),
73+
SSLSupportMethod: cloudfrontTypes.SSLSupportMethodSniOnly,
74+
},
75+
CustomErrorResponses: &cloudfrontTypes.CustomErrorResponses{
76+
Quantity: aws.Int32(1),
77+
Items: []cloudfrontTypes.CustomErrorResponse{
78+
{
79+
ErrorCode: aws.Int32(403),
80+
ResponseCode: aws.String("200"),
81+
ErrorCachingMinTTL: aws.Int64(10),
82+
ResponsePagePath: aws.String("/index.html"),
83+
},
84+
},
85+
},
86+
Origins: &cloudfrontTypes.Origins{
87+
Quantity: aws.Int32(1),
88+
Items: []cloudfrontTypes.Origin{
89+
{
90+
DomainName: aws.String(originDomain),
91+
Id: aws.String(originDomain),
92+
S3OriginConfig: &cloudfrontTypes.S3OriginConfig{
93+
OriginAccessIdentity: aws.String("origin-access-identity/cloudfront/" + originAccessIdentityID),
94+
},
95+
},
96+
},
97+
},
98+
CacheBehaviors: nil,
99+
DefaultCacheBehavior: &cloudfrontTypes.DefaultCacheBehavior{
100+
TargetOriginId: aws.String(originDomain),
101+
Compress: aws.Bool(true),
102+
ViewerProtocolPolicy: cloudfrontTypes.ViewerProtocolPolicyRedirectToHttps,
103+
AllowedMethods: &cloudfrontTypes.AllowedMethods{
104+
Quantity: aws.Int32(2),
105+
Items: []cloudfrontTypes.Method{
106+
cloudfrontTypes.MethodGet,
107+
cloudfrontTypes.MethodHead,
108+
},
109+
},
110+
},
111+
},
112+
})
113+
114+
if err != nil {
115+
return nil, err
116+
}
117+
118+
return cloudfrontResponse, nil
119+
}
120+
121+
func (c *CFDistributionAPIImpl) createoriginAccessIdentity(domainName string) (string, error) {
122+
ctx := context.Background()
123+
oai, err := c.cloudfrontClient.CreateCloudFrontOriginAccessIdentity(ctx, &cloudfront.CreateCloudFrontOriginAccessIdentityInput{
124+
CloudFrontOriginAccessIdentityConfig: &cloudfrontTypes.CloudFrontOriginAccessIdentityConfig{
125+
CallerReference: aws.String(domainName),
126+
Comment: aws.String(domainName),
127+
},
128+
})
129+
if err != nil {
130+
return "", err
131+
}
132+
return *oai.CloudFrontOriginAccessIdentity.Id, nil
133+
}
134+
135+
var (
136+
// bucketName is the name of the S3 bucket to create a CloudFront distribution for.
137+
bucketName = ""
138+
// certificateSSLArn is the ARN value of the certificate issued by the AWS Certificate Manager (ACM).
139+
// When testing, please check and copy and paste the ARN of the pre-issued certificate.
140+
// If you don't know how to create a TLS/SSL certificate using ACM, follow the link below.
141+
// https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html
142+
certificateSSLArn = ""
143+
// domain refers to the domain that will be used in conjunction with CloudFront and Amazon Route 53.
144+
// For testing, please enter a domain that is registered in Route 53 and will be used in conjunction with CloudFront.
145+
domain = ""
146+
)
147+
148+
// main uses the AWS SDK for Go V2 to create an Amazon CloudFront distribution.
149+
// This example uses the default settings specified in your shared credentials
150+
// and config files.
151+
func main() {
152+
153+
flag.StringVar(&bucketName, "bucket", "", "<EXAMPLE-BUCKET-NAME>")
154+
flag.StringVar(&certificateSSLArn, "cert", "", "<AWS CERTIFICATE MANGER ARN>")
155+
flag.StringVar(&domain, "domain", "", "<YOUR DOMAIN>")
156+
flag.Parse()
157+
if bucketName == "" {
158+
log.Println(errors.New("please setup bucket name"))
159+
return
160+
}
161+
162+
if certificateSSLArn == "" {
163+
log.Println(errors.New("please setup certificate ARN"))
164+
return
165+
}
166+
167+
if domain == "" {
168+
log.Println(errors.New("please setup your domain"))
169+
return
170+
}
171+
172+
sdkConfig, err := config.LoadDefaultConfig(context.TODO())
173+
174+
if err != nil {
175+
fmt.Println("Couldn't load default configuration. Have you set up your AWS account?")
176+
fmt.Println(err)
177+
return
178+
}
179+
180+
s3Client := s3.NewFromConfig(sdkConfig)
181+
cloudfrontClient := cloudfront.NewFromConfig(sdkConfig)
182+
183+
cfDistribution := createCFDistribution(s3Client, cloudfrontClient)
184+
185+
result, err := cfDistribution.CreateDistribution(bucketName, certificateSSLArn, domain)
186+
if err != nil {
187+
fmt.Println("Couldn't create distribution. Please check error message and try again.")
188+
fmt.Println(err)
189+
return
190+
}
191+
fmt.Println(result.Distribution.ARN)
192+
}
193+
194+
// snippet-end:[cloudfront.go-v2.CreateDistribution]
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
package main
4+
5+
import (
6+
"context"
7+
"errors"
8+
"testing"
9+
"time"
10+
11+
"github.com/aws/aws-sdk-go-v2/aws"
12+
"github.com/aws/aws-sdk-go-v2/config"
13+
"github.com/aws/aws-sdk-go-v2/service/cloudfront"
14+
"github.com/aws/aws-sdk-go-v2/service/cloudfront/types"
15+
"github.com/aws/aws-sdk-go-v2/service/s3"
16+
)
17+
18+
type MockCFDistributionAPI struct {
19+
s3Client *s3.Client
20+
cloudfrontClient *cloudfront.Client
21+
}
22+
23+
func (m *MockCFDistributionAPI) CreateDistribution(bucketName, certificateSSLArn, domain string) (*cloudfront.CreateDistributionOutput, error) {
24+
if bucketName == "" || certificateSSLArn == "" || domain == "" {
25+
return nil, errors.New("bucket name, certificate SSL ARN, and domain are required")
26+
}
27+
return &cloudfront.CreateDistributionOutput{
28+
Distribution: &types.Distribution{
29+
ARN: aws.String("arn:aws:cloudfront::1234567890:distribution/AAAAAAAAAAAA"),
30+
DomainName: aws.String(domain),
31+
DistributionConfig: &types.DistributionConfig{
32+
ViewerCertificate: &types.ViewerCertificate{
33+
ACMCertificateArn: aws.String(certificateSSLArn),
34+
},
35+
},
36+
},
37+
}, nil
38+
}
39+
40+
func (m *MockCFDistributionAPI) createoriginAccessIdentity(domainName string) (string, error) {
41+
return domainName, nil
42+
}
43+
44+
func createMockCFDistribution(s3client *s3.Client, cloudfront *cloudfront.Client) CFDistributionAPI {
45+
return &MockCFDistributionAPI{
46+
s3Client: s3client,
47+
cloudfrontClient: cloudfront,
48+
}
49+
}
50+
51+
func TestCreateDistribution(t *testing.T) {
52+
thisTime := time.Now()
53+
nowString := thisTime.Format("2006-01-02 15:04:05 Monday")
54+
t.Log("Starting integration test at " + nowString)
55+
56+
sdkConfig, err := config.LoadDefaultConfig(context.TODO())
57+
58+
if err != nil {
59+
t.Log("Got an error ...:")
60+
t.Log(err)
61+
return
62+
}
63+
64+
s3Client := s3.NewFromConfig(sdkConfig)
65+
cloudfrontClient := cloudfront.NewFromConfig(sdkConfig)
66+
67+
mockCFDistribution := createMockCFDistribution(s3Client, cloudfrontClient)
68+
69+
bucketName := "example-com"
70+
certificateSSLArn := "arn:aws:acm:ap-northeast-2:123456789000:certificate/000000000-0000-0000-0000-000000000000"
71+
domain := "example.com"
72+
73+
result, err := mockCFDistribution.CreateDistribution(bucketName, certificateSSLArn, domain)
74+
75+
if err != nil {
76+
t.Error(err)
77+
return
78+
}
79+
80+
t.Log("Created Distribution with ARN: " + *result.Distribution.ARN + " for name: " + *result.Distribution.DomainName)
81+
}

gov2/cloudfront/go.mod

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module example.aws/go-v2/examples/cloudfront
2+
3+
go 1.18
4+
5+
require (
6+
github.com/aws/aws-sdk-go-v2 v1.17.4 // indirect
7+
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
8+
github.com/aws/aws-sdk-go-v2/config v1.18.12 // indirect
9+
github.com/aws/aws-sdk-go-v2/credentials v1.13.12 // indirect
10+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.22 // indirect
11+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28 // indirect
12+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.22 // indirect
13+
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.29 // indirect
14+
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.19 // indirect
15+
github.com/aws/aws-sdk-go-v2/service/cloudfront v1.24.1 // indirect
16+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
17+
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.23 // indirect
18+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.22 // indirect
19+
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.22 // indirect
20+
github.com/aws/aws-sdk-go-v2/service/s3 v1.30.2 // indirect
21+
github.com/aws/aws-sdk-go-v2/service/sso v1.12.1 // indirect
22+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.1 // indirect
23+
github.com/aws/aws-sdk-go-v2/service/sts v1.18.3 // indirect
24+
github.com/aws/smithy-go v1.13.5 // indirect
25+
github.com/jmespath/go-jmespath v0.4.0 // indirect
26+
)

gov2/cloudfront/go.sum

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
github.com/aws/aws-sdk-go-v2 v1.17.4 h1:wyC6p9Yfq6V2y98wfDsj6OnNQa4w2BLGCLIxzNhwOGY=
2+
github.com/aws/aws-sdk-go-v2 v1.17.4/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
3+
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs=
4+
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10/go.mod h1:VeTZetY5KRJLuD/7fkQXMU6Mw7H5m/KP2J5Iy9osMno=
5+
github.com/aws/aws-sdk-go-v2/config v1.18.12 h1:fKs/I4wccmfrNRO9rdrbMO1NgLxct6H9rNMiPdBxHWw=
6+
github.com/aws/aws-sdk-go-v2/config v1.18.12/go.mod h1:J36fOhj1LQBr+O4hJCiT8FwVvieeoSGOtPuvhKlsNu8=
7+
github.com/aws/aws-sdk-go-v2/credentials v1.13.12 h1:Cb+HhuEnV19zHRaYYVglwvdHGMJWbdsyP4oHhw04xws=
8+
github.com/aws/aws-sdk-go-v2/credentials v1.13.12/go.mod h1:37HG2MBroXK3jXfxVGtbM2J48ra2+Ltu+tmwr/jO0KA=
9+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.22 h1:3aMfcTmoXtTZnaT86QlVaYh+BRMbvrrmZwIQ5jWqCZQ=
10+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.22/go.mod h1:YGSIJyQ6D6FjKMQh16hVFSIUD54L4F7zTGePqYMYYJU=
11+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28 h1:r+XwaCLpIvCKjBIYy/HVZujQS9tsz5ohHG3ZIe0wKoE=
12+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28/go.mod h1:3lwChorpIM/BhImY/hy+Z6jekmN92cXGPI1QJasVPYY=
13+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.22 h1:7AwGYXDdqRQYsluvKFmWoqpcOQJ4bH634SkYf3FNj/A=
14+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.22/go.mod h1:EqK7gVrIGAHyZItrD1D8B0ilgwMD1GiWAmbU4u/JHNk=
15+
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.29 h1:J4xhFd6zHhdF9jPP0FQJ6WknzBboGMBNjKOv4iTuw4A=
16+
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.29/go.mod h1:TwuqRBGzxjQJIwH16/fOZodwXt2Zxa9/cwJC5ke4j7s=
17+
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.19 h1:FGvpyTg2LKEmMrLlpjOgkoNp9XF5CGeyAyo33LdqZW8=
18+
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.19/go.mod h1:8W88sW3PjamQpKFUQvHWWKay6ARsNvZnzU7+a4apubw=
19+
github.com/aws/aws-sdk-go-v2/service/cloudfront v1.24.1 h1:+JyTKAmvtszyz+LH0ag+Jm1BdcjfyXK3O2KJKSHIXtM=
20+
github.com/aws/aws-sdk-go-v2/service/cloudfront v1.24.1/go.mod h1:SJRh4g8v7lNgjBVlSalPRp7Vfi2PU0LZN0PNEPjm9qk=
21+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 h1:y2+VQzC6Zh2ojtV2LoC0MNwHWc6qXv/j2vrQtlftkdA=
22+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11/go.mod h1:iV4q2hsqtNECrfmlXyord9u4zyuFEJX9eLgLpSPzWA8=
23+
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.23 h1:c5+bNdV8E4fIPteWx4HZSkqI07oY9exbfQ7JH7Yx4PI=
24+
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.23/go.mod h1:1jcUfF+FAOEwtIcNiHPaV4TSoZqkUIPzrohmD7fb95c=
25+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.22 h1:LjFQf8hFuMO22HkV5VWGLBvmCLBCLPivUAmpdpnp4Vs=
26+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.22/go.mod h1:xt0Au8yPIwYXf/GYPy/vl4K3CgwhfQMYbrH7DlUUIws=
27+
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.22 h1:ISLJ2BKXe4zzyZ7mp5ewKECiw0U7KpLgS3S6OxY9Cm0=
28+
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.22/go.mod h1:QFVbqK54XArazLvn2wvWMRBi/jGrWii46qbr5DyPGjc=
29+
github.com/aws/aws-sdk-go-v2/service/s3 v1.30.2 h1:5EQWIFO+Hc8E2hFcXQJ1vm6ufl/PMt/6RVRDZRju2vM=
30+
github.com/aws/aws-sdk-go-v2/service/s3 v1.30.2/go.mod h1:SXDHd6fI2RhqB7vmAzyYQCTQnpZrIprVJvYxpzW3JAM=
31+
github.com/aws/aws-sdk-go-v2/service/sso v1.12.1 h1:lQKN/LNa3qqu2cDOQZybP7oL4nMGGiFqob0jZJaR8/4=
32+
github.com/aws/aws-sdk-go-v2/service/sso v1.12.1/go.mod h1:IgV8l3sj22nQDd5qcAGY0WenwCzCphqdbFOpfktZPrI=
33+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.1 h1:0bLhH6DRAqox+g0LatcjGKjjhU6Eudyys6HB6DJVPj8=
34+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.1/go.mod h1:O1YSOg3aekZibh2SngvCRRG+cRHKKlYgxf/JBF/Kr/k=
35+
github.com/aws/aws-sdk-go-v2/service/sts v1.18.3 h1:s49mSnsBZEXjfGBkRfmK+nPqzT7Lt3+t2SmAKNyHblw=
36+
github.com/aws/aws-sdk-go-v2/service/sts v1.18.3/go.mod h1:b+psTJn33Q4qGoDaM7ZiOVVG8uVjGI6HaZ8WBHdgDgU=
37+
github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8=
38+
github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
39+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
40+
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
41+
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
42+
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
43+
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
44+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
45+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
46+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
47+
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

0 commit comments

Comments
 (0)