118 lines
3.9 KiB
Go
118 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cloudfront"
|
|
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
|
)
|
|
|
|
const originId = "encoded-bucket-origin"
|
|
|
|
// AWS managed "CachingOptimized" cache policy (same ID in every account/region).
|
|
const cachingOptimizedPolicyId = "658327ea-f89d-4fab-a63d-7e88639e58f6"
|
|
|
|
func main() {
|
|
pulumi.Run(func(ctx *pulumi.Context) error {
|
|
// Create an AWS resource (S3 Bucket) that holds encoded assets
|
|
bucket, err := s3.NewBucket(ctx, "encoded-bucket", nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Keep the bucket private; CloudFront reaches it via Origin Access Control.
|
|
_, err = s3.NewBucketPublicAccessBlock(ctx, "encoded-bucket-public-access-block", &s3.BucketPublicAccessBlockArgs{
|
|
Bucket: bucket.ID(),
|
|
BlockPublicAcls: pulumi.Bool(true),
|
|
BlockPublicPolicy: pulumi.Bool(true),
|
|
IgnorePublicAcls: pulumi.Bool(true),
|
|
RestrictPublicBuckets: pulumi.Bool(true),
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
oac, err := cloudfront.NewOriginAccessControl(ctx, "encoded-bucket-oac", &cloudfront.OriginAccessControlArgs{
|
|
Description: pulumi.String("OAC for encoded-bucket assets"),
|
|
OriginAccessControlOriginType: pulumi.String("s3"),
|
|
SigningBehavior: pulumi.String("always"),
|
|
SigningProtocol: pulumi.String("sigv4"),
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
distribution, err := cloudfront.NewDistribution(ctx, "encoded-bucket-cdn", &cloudfront.DistributionArgs{
|
|
Enabled: pulumi.Bool(true),
|
|
Comment: pulumi.String("Edge caching for encoded-bucket assets"),
|
|
Origins: cloudfront.DistributionOriginArray{
|
|
&cloudfront.DistributionOriginArgs{
|
|
DomainName: bucket.BucketRegionalDomainName,
|
|
OriginId: pulumi.String(originId),
|
|
OriginAccessControlId: oac.ID(),
|
|
S3OriginConfig: &cloudfront.DistributionOriginS3OriginConfigArgs{
|
|
OriginAccessIdentity: pulumi.String(""),
|
|
},
|
|
},
|
|
},
|
|
DefaultCacheBehavior: &cloudfront.DistributionDefaultCacheBehaviorArgs{
|
|
TargetOriginId: pulumi.String(originId),
|
|
ViewerProtocolPolicy: pulumi.String("redirect-to-https"),
|
|
AllowedMethods: pulumi.ToStringArray([]string{"GET", "HEAD"}),
|
|
CachedMethods: pulumi.ToStringArray([]string{"GET", "HEAD"}),
|
|
Compress: pulumi.Bool(true),
|
|
CachePolicyId: pulumi.String(cachingOptimizedPolicyId),
|
|
},
|
|
Restrictions: &cloudfront.DistributionRestrictionsArgs{
|
|
GeoRestriction: &cloudfront.DistributionRestrictionsGeoRestrictionArgs{
|
|
RestrictionType: pulumi.String("none"),
|
|
},
|
|
},
|
|
ViewerCertificate: &cloudfront.DistributionViewerCertificateArgs{
|
|
CloudfrontDefaultCertificate: pulumi.Bool(true),
|
|
},
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Allow only this distribution to read objects from the bucket.
|
|
policy := pulumi.All(bucket.Arn, distribution.Arn).ApplyT(func(args []interface{}) (string, error) {
|
|
bucketArn := args[0].(string)
|
|
distributionArn := args[1].(string)
|
|
|
|
doc := map[string]interface{}{
|
|
"Version": "2012-10-17",
|
|
"Statement": []map[string]interface{}{
|
|
{
|
|
"Sid": "AllowCloudFrontServicePrincipal",
|
|
"Effect": "Allow",
|
|
"Principal": map[string]string{"Service": "cloudfront.amazonaws.com"},
|
|
"Action": "s3:GetObject",
|
|
"Resource": bucketArn + "/*",
|
|
"Condition": map[string]interface{}{
|
|
"StringEquals": map[string]string{"AWS:SourceArn": distributionArn},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
b, err := json.Marshal(doc)
|
|
return string(b), err
|
|
}).(pulumi.StringOutput)
|
|
|
|
_, err = s3.NewBucketPolicy(ctx, "encoded-bucket-policy", &s3.BucketPolicyArgs{
|
|
Bucket: bucket.ID(),
|
|
Policy: policy,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Export the name of the bucket
|
|
ctx.Export("bucketName", bucket.ID())
|
|
ctx.Export("cdnDomainName", distribution.DomainName)
|
|
return nil
|
|
})
|
|
}
|