Open1
CDKでNextjsをSSGしたやつホスティング

import * as cdk from "aws-cdk-lib";
import * as acm from "aws-cdk-lib/aws-certificatemanager";
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 route53 from "aws-cdk-lib/aws-route53";
import * as route53Targets from "aws-cdk-lib/aws-route53-targets";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as s3deploy from "aws-cdk-lib/aws-s3-deployment";
import { Construct } from "constructs";
export class CdnStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const originDomainName = "example.com";
const domainName = `hello.${originDomainName}`;
const myHostedZone = route53.HostedZone.fromLookup(this, "MyZone", {
domainName: originDomainName,
});
const myCertificate = new acm.Certificate(this, "mySiteCert", {
domainName,
validation: acm.CertificateValidation.fromDns(myHostedZone),
});
const accessLogsBucket = new s3.Bucket(this, "AccessLogsBucket", {
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
});
const myBucket = new s3.Bucket(this, "MyBucket", {
serverAccessLogsBucket: accessLogsBucket,
serverAccessLogsPrefix: "logs",
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
});
const cloudfrontOai = new cloudfront.OriginAccessIdentity(
this,
"CloudFrontOAI",
);
// 静的ホスティング用S3バケットに対して必要なアクセスポリシーを作成
const bucketPolicy = new s3.BucketPolicy(this, "WebsiteBucketPolicy", {
bucket: myBucket,
});
bucketPolicy.document.addStatements(
new iam.PolicyStatement({
actions: ["s3:GetObject"],
effect: iam.Effect.ALLOW,
principals: [
new iam.CanonicalUserPrincipal(
cloudfrontOai.cloudFrontOriginAccessIdentityS3CanonicalUserId,
),
],
resources: [`${myBucket.bucketArn}/*`],
}),
);
const script: string = `
function handler(event) {
var request = event.request;
var uri = request.uri;
// URIが '/app' または '/web' で始まる場合、何も変更せずにそのままリクエストを処理する
if (uri.startsWith('/app') || uri.startsWith('/web')) {
return request;
}
// URIが '/' の場合、'/web/index.html'にリダイレクトする
if (uri === '/') {
request.uri = '/web/index.html';
} else {
// それ以外のURIには '/web' をプレフィックスとして追加する
request.uri = '/web' + uri;
}
return request;
}
`;
const cfFunction = new cloudfront.Function(this, "Function", {
code: cloudfront.FunctionCode.fromInline(script),
});
const distribution = new cloudfront.Distribution(this, "myDist", {
defaultBehavior: {
origin: new origins.S3Origin(myBucket),
functionAssociations: [
{
function: cfFunction,
eventType: cloudfront.FunctionEventType.VIEWER_REQUEST,
},
],
},
domainNames: [`${domainName}`],
certificate: myCertificate,
});
new s3deploy.BucketDeployment(this, "DeployWebsite", {
sources: [s3deploy.Source.asset("next/out")],
destinationBucket: myBucket,
destinationKeyPrefix: "web", // optional prefix in destination bucket
});
new route53.ARecord(this, "cdnRecord", {
zone: myHostedZone,
target: route53.RecordTarget.fromAlias(
new route53Targets.CloudFrontTarget(distribution),
),
recordName: domainName,
});
}
}