CloudFront+S3構成の静的ファイル配信をCDKだけで構築する
背景
単純なHTMLファイルや、画像ファイル、JSONファイルなどを公開したい時ってありますよね〜(唐突
そんな時にS3バケットをPUBLIC設定にして、ファイルをアップロードすれば公開することは可能ですが、S3バケットのPUBLIC設定はセキュリティ観点で非推奨だったりしますし、カスタムドメインをつけたいケースも多いかと思います。
構築するAWSリソース、アーキテクチャはこのようなものです。
CDKで実装
CDKのプロジェクト全体はこちらにあります。
S3バケット作成
ここは特に特別なことはしていません。
const bucket = new s3.Bucket(this, 'S3Bucket', {
bucketName: 'cdk-staticfile-deploy-202307',
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
※RemovelPolicyはこちらが参考になります。
CloudFront作成
CloudFrontでは、Origin Access Identity (OAI)という機能が提供されていましたが、セキュリティ面の機能強化や細かいポリシー設定ができる Origin Access Control (OAC)が2022年8月に発表されてからは、OACの利用が推奨されています。
以下のブログでわかりやすく解説されています。
CloudFrontのOAC機能をCDKで実装していけばいいのですが、このissueにあるように、OACのL2コンストラクタはまだ実装されていません。
そのため、このissueを参考にして、OAC版CloudFrontを実装していきます。
// OAC
const cfnOriginAccessControl = new cloudfront.CfnOriginAccessControl(this, 'OriginAccessControl', {
originAccessControlConfig: {
name: 'OriginAccessControlForContentsBucket',
originAccessControlOriginType: 's3',
signingBehavior: 'always',
signingProtocol: 'sigv4',
description: 'Access Control',
},
});
// Cloudfront(distribution)
const origin = new cloudfront_origins.S3Origin(bucket);
const distribution = new cloudfront.Distribution(this, 'DistributionId', {
defaultRootObject: 'index.html',
defaultBehavior: {
origin: origin,
},
});
// Policy
const bucketPolicyStatement = new iam.PolicyStatement({
actions: ['s3:GetObject'],
effect: iam.Effect.ALLOW,
principals: [
new iam.ServicePrincipal('cloudfront.amazonaws.com')
],
resources: [`${bucket.bucketArn}/*`]
});
bucketPolicyStatement.addCondition('StringEquals', {
'AWS:SourceArn': `arn:aws:cloudfront::${cdk.Stack.of(this).account}:distribution/${distribution.distributionId}`
});
bucket.addToResourcePolicy(bucketPolicyStatement);
const cfnDistribution = distribution.node.defaultChild as cloudfront.CfnDistribution;
cfnDistribution.addPropertyOverride('DistributionConfig.Origins.0.OriginAccessControlId', cfnOriginAccessControl.getAtt('Id'));
cfnDistribution.addPropertyOverride('DistributionConfig.Origins.0.DomainName', bucket.bucketRegionalDomainName);
cfnDistribution.addOverride('Properties.DistributionConfig.Origins.0.S3OriginConfig.OriginAccessIdentity', "");
cfnDistribution.addPropertyDeletionOverride('DistributionConfig.Origins.0.CustomOriginConfig');
S3へ配信するファイルをアップロード
BucketDeploymentを使うと、sourcesで指定したディレクトリ以下のファイルをdestinationBucketにアップロードします。こういったメソッドがあるので、AWSリソースだけCDKで定義してファイルはCLIやスクリプトでアップロードというような歯痒い状態にならず、CDKだけで全てを完結させることができます。
new s3_deployment.BucketDeployment(this, 'S3Deployment', {
sources: [s3_deployment.Source.asset('./static_files/')],
destinationBucket: bucket,
distribution,
distributionPaths: ['/*']
});
まとめ
基礎的な内容に留まってしましましたが、静的ファイル配信をCDKだけで行うことができるイメージが湧いたり、実装する際の参考になれば幸いです。
次回、「CloudFront+S3での静的ファイル配信にCloudFront Functionsでアレコレする」を書きたいと思います。
Discussion