概要
すでに稼働しているCloudFrontに、新しくCDKでデプロイをする構成を行った。
バケット名、CloudFrontのIDが分かれば問題なくデプロイ可能であった。
環境
-
aws-cdk-lib
:2.16.0
ソース
cdk/lib/cdk-stack.ts
import * as core from 'aws-cdk-lib'
import * as s3 from 'aws-cdk-lib/aws-s3'
import * as cf from 'aws-cdk-lib/aws-cloudfront'
import * as iam from 'aws-cdk-lib/aws-iam'
import * as s3deploy from 'aws-cdk-lib/aws-s3-deployment'
import { basePath } from '../constants/paths'
import { Construct } from 'constructs'
interface Props extends core.StackProps {
bucketName: string
identityName: string
distributionId: string
domainName: string
projectNameTag: string
}
export class AWSCarTaGraphEditorClientStack extends core.Stack {
constructor(scope: Construct, id: string, props: Props) {
super(scope, id, props)
// CloudFront オリジン用のS3バケットを作成
const bucket = s3.Bucket.fromBucketName(
this,
props.bucketName,
props.bucketName,
)
// CloudFront で設定する オリジンアクセスアイデンティティ を作成
const identity = this.createIdentity(bucket, props.identityName)
// S3バケットポリシーで、CloudFrontのオリジンアクセスアイデンティティを許可
this.createPolicy(bucket, identity)
// CloudFrontディストリビューションを作成
const distribution = cf.Distribution.fromDistributionAttributes(
this,
props.distributionId,
{
domainName: '',
distributionId: props.distributionId,
},
)
// 指定したディレクトリをデプロイ
this.deployS3(bucket, distribution, '../client/build', props.bucketName)
// 確認用にCloudFrontのURLに整形して出力
new core.CfnOutput(this, `${props.distributionId}-top-url`, {
value: `https://${distribution.distributionDomainName}/`,
})
core.Tags.of(this).add('Project', props.projectNameTag)
}
private createIdentity(bucket: s3.IBucket, identityName: string) {
const identity = new cf.OriginAccessIdentity(this, identityName, {
comment: `${bucket.bucketName} access identity`,
})
return identity
}
private createPolicy(bucket: s3.IBucket, identity: cf.OriginAccessIdentity) {
const myBucketPolicy = new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['s3:GetObject', 's3:ListBucket'],
principals: [
new iam.CanonicalUserPrincipal(
identity.cloudFrontOriginAccessIdentityS3CanonicalUserId,
),
],
resources: [bucket.bucketArn + '/*', bucket.bucketArn],
})
bucket.addToResourcePolicy(myBucketPolicy)
}
private deployS3(
siteBucket: s3.IBucket,
distribution: cf.IDistribution,
sourcePath: string,
bucketName: string,
) {
new s3deploy.BucketDeployment(
this,
`${bucketName}-deploy-with-invalidation`,
{
sources: [s3deploy.Source.asset(sourcePath)],
destinationBucket: siteBucket,
distribution,
distributionPaths: [`/${basePath}/*`],
destinationKeyPrefix: basePath,
},
)
}
}
cdk/bin/cdk.ts
#!/usr/bin/env node
import 'source-map-support/register'
import * as cdk from 'aws-cdk-lib'
import { AWSCarTaGraphEditorClientStack } from '../lib/cdk-stack'
import * as dotenv from 'dotenv'
dotenv.config()
const envList = [
'PROJECT_ID',
'BUCKET_NAME',
'DISTRIBUTION_ID',
'TAG_PROJECT_NAME',
'DOMAIN_NAME',
] as const
for (const key of envList) {
if (!process.env[key]) throw new Error(`please add ${key} to .env`)
}
const processEnv = process.env as Record<typeof envList[number], string>
const app = new cdk.App()
const env = {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION,
}
const projectId = processEnv.PROJECT_ID
new AWSCarTaGraphEditorClientStack(app, `${projectId}-stack`, {
bucketName: processEnv.BUCKET_NAME,
identityName: `${projectId}-origin-access-identity-to-s3-bucket`,
distributionId: processEnv.DISTRIBUTION_ID,
domainName: processEnv.DOMAIN_NAME,
projectNameTag: processEnv.TAG_PROJECT_NAME,
env,
})
.env
PROJECT_ID=hogefuga
TAG_PROJECT_NAME=hogehoge
BUCKET_NAME=fuga-s3-bucket
DISTRIBUTION_ID=hoge
DOMAIN_NAME=piyo.cloudfront.net
バケット名はS3のバケット名。
DistributionIdとドメイン名はCloudFrontのIdとドメイン名を入力する。
参考
AWS CDK v2を使ってSPA用のCloudFrontをデプロイしたメモ
aws-cdkのv2が来たのでドキュメントを読んでみたメモ
aws-cdk - BucketDeployment
aws-cdk - Distribution