AWS CDK V2でCloudFront+S3の静的サイトホスティングを構築してみた
こんにちは、CX事業本部 IoT事業部の若槻です。
昨年末にAWS CDK V2がデプロイされました。
V2では、CDK Constructの構成で必要となるパッケージが1つに集約されるなど、V1と比べてよりよい開発体験が提供されるようになりました。
また、V1は2022/6/1以降はメンテナンスモードに移行してしまうので、今後新規のCDKプロジェクトを作る際には必然的にV2を使うこととなりそうです。
今回は、そんなAWS CDK V2の肩慣らしとして、CloudFront+S3の静的サイトホスティングを構築してみました。
やってみた
CDKアプリ初回作成
cdk init
でCDKアプリを初回作成します。
$ npx cdk init --language typescript
作成されたディレクトリの構成です。V1とほぼ同じに見えます。
package.json
を見ると、CDKパッケージのバージョンが2.14.0
とあり、CDKアプリがV2で作成されていることが分かります。
{ "name": "aws-cdk-v2-app", "version": "0.1.0", "bin": { "aws-cdk-v2-app": "bin/aws-cdk-v2-app.js" }, "scripts": { "build": "tsc", "watch": "tsc -w", "test": "jest", "cdk": "cdk" }, "devDependencies": { "@types/jest": "^26.0.10", "@types/node": "10.17.27", "jest": "^26.4.2", "ts-jest": "^26.2.0", "aws-cdk": "2.14.0", "ts-node": "^9.0.0", "typescript": "~3.9.7" }, "dependencies": { "aws-cdk-lib": "2.14.0", "constructs": "^10.0.0", "source-map-support": "^0.5.16" } }
あとは必要に応じてcdk bootstrap
を行ってください。
CloudFront+S3静的サイトホスティングの構成
今回作りたかったCloudFront+S3静的サイトホスティングを構成してみます。
やはり注目すべきはaws-cdk-lib
という1つのパッケージからすべてのConstructのクラスをImportできている点です。これにより作りたいサービスやリソース毎にパッケージを追加したり、すべてのパッケージのバージョンを揃えたりする手間が省けるのが何より嬉しいです。
また、StackのコードはCDK V1で同様の構成を作った際のコードをほぼそのまま流用できました。Importしたクラスの使用はV1とV2でほぼ互換性があるようです。
- CloudFront DistributionのCDK Constructの新しいクラスを使って静的サイトホスティング(Amazon S3)の配信を構築してみた | DevelopersIO
- [AWS CDK] 静的サイトホスティング(CloudFront + S3)でfavicon.icoの読み込みエラーを抑制する | DevelopersIO
import { Construct } from 'constructs'; import { Stack, StackProps, aws_s3, aws_cloudfront, aws_cloudfront_origins, aws_s3_deployment, aws_iam, RemovalPolicy, Duration, } from 'aws-cdk-lib'; export class AwsCdkV2AppStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const websiteBucket = new aws_s3.Bucket(this, 'WebsiteBucket', { removalPolicy: RemovalPolicy.DESTROY, }); const originAccessIdentity = new aws_cloudfront.OriginAccessIdentity( this, 'OriginAccessIdentity', { comment: 'website-distribution-originAccessIdentity', } ); const webSiteBucketPolicyStatement = new aws_iam.PolicyStatement({ actions: ['s3:GetObject'], effect: aws_iam.Effect.ALLOW, principals: [ new aws_iam.CanonicalUserPrincipal( originAccessIdentity.cloudFrontOriginAccessIdentityS3CanonicalUserId ), ], resources: [`${websiteBucket.bucketArn}/*`], }); websiteBucket.addToResourcePolicy(webSiteBucketPolicyStatement); const distribution = new aws_cloudfront.Distribution(this, 'distribution', { comment: 'website-distribution', defaultRootObject: 'index.html', errorResponses: [ { ttl: Duration.seconds(300), httpStatus: 403, responseHttpStatus: 403, responsePagePath: '/error.html', }, { ttl: Duration.seconds(300), httpStatus: 404, responseHttpStatus: 404, responsePagePath: '/error.html', }, ], defaultBehavior: { allowedMethods: aws_cloudfront.AllowedMethods.ALLOW_GET_HEAD, cachedMethods: aws_cloudfront.CachedMethods.CACHE_GET_HEAD, cachePolicy: aws_cloudfront.CachePolicy.CACHING_OPTIMIZED, viewerProtocolPolicy: aws_cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, origin: new aws_cloudfront_origins.S3Origin(websiteBucket, { originAccessIdentity, }), }, priceClass: aws_cloudfront.PriceClass.PRICE_CLASS_ALL, }); new aws_s3_deployment.BucketDeployment(this, 'WebsiteDeploy', { sources: [ aws_s3_deployment.Source.data( '/index.html', '<html><body><h1>Hello World</h1></body></html>' ), aws_s3_deployment.Source.data( '/error.html', '<html><body><h1>Error!!!!!!!!!!!!!</h1></body></html>' ), aws_s3_deployment.Source.data('/favicon.ico', ''), ], destinationBucket: websiteBucket, distribution: distribution, distributionPaths: ['/*'], }); } }
cdk deploy
を実行してStackをデプロイします。
ディストリビューションドメインにアクセスすると、サイトにアクセスできました!
おわりに
AWS CDK V2でCloudFront+S3の静的サイトホスティングを構築してみました。
V1を使っていた時にインストールされるCDKパッケージのバージョンの固定を忘れてパッケージ間で不整合が起きデプロイが失敗するが原因がなかなか分からないというトラウマな経験があったのですが、V2となり今後そのような悲劇が誰かに降りかかることは無いと思うと隔世の感です。
参考
以上