【AWS CDK】CloudFrontとS3で静的ホスティングサイト(SPA)をサッと作る
はじめに
AWSの勉強会や新人教育の講師を担当していますが、講義中に急遽ハンズオン環境が必要になったり、解説のための環境が必要になるケースがあります。そんな場面で、素早くサッとS3静的ホスティングサイト(SPA)を用意するための記事となります。個人的なメモとして、対処法を書き留めておきたいと思います。
個人的備忘が強いためコードの注釈などは薄いですが、
とりあえずCDKで動くものを体験したいという方に有用ではないかと思います。
構成
AWS CDKを使って以下のようなS3静的ホスティングサイトを作ります。
CDK準備
CDKのバージョンは2です。cdk bootstrap済みを想定しています。
$ mkdir teststatic && cd teststatic
$ cdk init app --language typescript
AWS CDK (Typescript)
/lib/teststatic-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as s3deploy from 'aws-cdk-lib/aws-s3-deployment';
import * as path from 'path';
export class TeststaticStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// 静的ホスティング用S3バケットを作成
const bucket = new s3.Bucket(this, 'SampleBucket', {
versioned: true,
publicReadAccess: false,
});
// CloudFront Origin Access Identity (OAI) を作成
const cloudfrontOai = new cloudfront.OriginAccessIdentity(this, 'CloudFrontOAI');
// 静的ホスティング用S3バケットに対して必要なアクセスポリシーを作成
const bucketPolicy = new s3.BucketPolicy(this, 'WebsiteBucketPolicy', {
bucket: bucket,
});
bucketPolicy.document.addStatements(
new iam.PolicyStatement({
actions: ['s3:GetObject'],
effect: iam.Effect.ALLOW,
principals: [new iam.CanonicalUserPrincipal(cloudfrontOai.cloudFrontOriginAccessIdentityS3CanonicalUserId)],
resources: [`${bucket.bucketArn}/*`],
})
);
// 静的ホスティング用S3バケットにOAIのアクセスを許可
bucket.grantRead(cloudfrontOai);
// CloudFrontディストリビューションを作成
const distribution = new cloudfront.Distribution(this, 'WebsiteDistribution', {
defaultBehavior: {
origin: new origins.S3Origin(bucket, {
originAccessIdentity: cloudfrontOai,
}),
},
defaultRootObject: 'index.html',
enableLogging: true, // ログ出力設定
logBucket: new s3.Bucket(this, 'LogBucket', {
objectOwnership: s3.ObjectOwnership.OBJECT_WRITER,
}),
logFilePrefix: 'distribution-access-logs/',
logIncludesCookies: true,
});
// index.htmlを静的ホスティング用S3バケットにアップロード
const indexHtmlPath = path.resolve(__dirname, './source/index.html');
new s3deploy.BucketDeployment(this, 'DeployIndexHtml', {
sources: [s3deploy.Source.asset(path.dirname(indexHtmlPath))],
destinationBucket: bucket,
destinationKeyPrefix: '/',
});
// CloudFrontディストリビューションのDNS名を出力
new cdk.CfnOutput(this, 'DistributionURL', {
value: distribution.distributionDomainName,
});
}
}
構成のポイント
いくつかポイントをあげると、CloudFront - S3間はOAIを利用してます。
本来なら、OACが推奨されるのですが、
執筆時点(2023/06/18)でOACはL1コンストラクトしかないため、L2利用ができるOAIの設定にしています。
さらに、CloudFrontの標準ログが有効化されてます。その標準ログ用のS3バケットも作成されます。
「index.html」ファイルを、lib/source/配下に用意します。
簡素ですが、、以下のような感じで適宜。
<html>
Hello World!
</html>
デプロイ
$ cdk synth
$ cdk deploy
まとめ
今回は、短時間でサッと静的Webホスティング環境(SPA)を作るということにフォーカスしています。 学習用やサンドボックスとして使用するため、用が済んだら全てcdk destroyで消してしまう想定です。
CDKを少し離れると忘れてしまうので、個人的な備忘のため書き残したいと思います。
本番環境用として使うにはさらにセキュリティ面、認証やWAFの実装、CICDなど追加検討する必要があります。
この記事が気に入ったらサポートをしてみませんか?