AWS CDKで独自ドメインホスティング環境構築を自動化してみました
以前の記事内容をAWS CDKで実現する方法をためしてみました!
今回の作成したテンプレートをGitHubで公開したのでぜひご利用ください!
/lib/unique-domain-hosting-stack.ts
import { Stack, StackProps, RemovalPolicy, CfnOutput } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as cdk from 'aws-cdk-lib';
import * as acm from 'aws-cdk-lib/aws-certificatemanager';
import * as route53 from 'aws-cdk-lib/aws-route53';
import * as targets 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 * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
export class UniqueDomainHostingStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// ドメイン名取得
const domainName = this.node.tryGetContext('domainName');
// 擬似パラメータ取得
const {
accountId,
region,
} = new cdk.ScopedAws(this);
// ホストゾーンID取得
const hostedZoneId = route53.HostedZone.fromLookup(this, 'HostedZoneId', {
domainName: domainName
});
// Certificate Manager設定
const certificateManagerCertificate = new acm.DnsValidatedCertificate(this, 'CertificateManagerCertificate', {
// ドメイン指定
domainName: domainName,
// ホストゾーンID指定
hostedZone: hostedZoneId,
// リージョン指定 (CloudFront固定)
region: 'us-east-1',
// 検証方法指定
validation: acm.CertificateValidation.fromDns(),
});
// S3バケット作成
const s3Bucket = new s3.Bucket(this, 'S3Bucket', {
// バケット名指定
bucketName: `${domainName}-${region}-${accountId}`,
// ブロックパブリックアクセスをすべてON
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
// リソース削除時にバケット削除
removalPolicy: RemovalPolicy.DESTROY,
autoDeleteObjects: true,
});
// CloudFrontOAI設定
const cloudFrontOAI = new cloudfront.OriginAccessIdentity(this, 'CloudFrontOriginAccessIdentityy', {
comment: 'Unique Domain Hosting Environment',
})
// CloudFront設定
const cloudFrontDistribution = new cloudfront.Distribution(this, 'CloudFrontDistribution', {
// ドメイン指定
domainNames: [domainName],
// キャッシュビヘイビア設定
defaultBehavior: {
// オリジンID指定
origin: new origins.S3Origin(s3Bucket, {
originAccessIdentity: cloudFrontOAI
}),
// 自動圧縮有無指定
compress: true,
// HTTPメソッド指定
allowedMethods: cloudfront.AllowedMethods.ALLOW_GET_HEAD,
cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD,
// ビューアプロトコルポリシー指定
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
// キャッシュポリシー指定 (CachingOptimized)
cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
},
// SPA対応設定
errorResponses: [
{
httpStatus: 403,
responsePagePath: '/index.html',
responseHttpStatus: 200,
ttl: cdk.Duration.minutes(0),
},
{
httpStatus: 404,
responsePagePath: '/index.html',
responseHttpStatus: 200,
ttl: cdk.Duration.minutes(0),
},
],
// 料金クラス指定
priceClass: cloudfront.PriceClass.PRICE_CLASS_ALL,
// ディストリビューション有効無効指定
enabled: true,
// SSL証明書設定
certificate: certificateManagerCertificate,
// セキュリティポリシー指定
minimumProtocolVersion: cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021,
// HTTPバージョン指定
httpVersion: cloudfront.HttpVersion.HTTP2,
// ルートURL指定
defaultRootObject: 'index.html',
// IPv6有無指定
enableIpv6: true,
})
// Route53レコード設定
new route53.ARecord(this, 'Route53RecordSet', {
// ドメイン指定
recordName: domainName,
// ホストゾーンID指定
zone: hostedZoneId,
// エイリアスターゲット設定
target: route53.RecordTarget.fromAlias(
new targets.CloudFrontTarget(cloudFrontDistribution)
),
});
// S3バケットにデプロイ
new s3deploy.BucketDeployment(this, 'S3BucketDeploy', {
// 対象ディレクトリ指定
sources: [s3deploy.Source.asset('./dist')],
// S3バケット指定
destinationBucket: s3Bucket,
// CloudFront指定
distribution: cloudFrontDistribution,
distributionPaths: ['/*'],
});
// デプロイ先URL表示
new CfnOutput(this, 'DeployURL', {
value: `https://${domainName}`,
})
}
}
/bin/unique-domain-hosting.ts
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { UniqueDomainHostingStack } from '../lib/unique-domain-hosting-stack';
const app = new cdk.App();
new UniqueDomainHostingStack(app, 'UniqueDomainHostingStack', {
// アカウント情報設定
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION
},
});
cdk.json
{
"app": "npx ts-node --prefer-ts-exts bin/unique-domain-hosting.ts",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"**/*.d.ts",
"**/*.js",
"tsconfig.json",
"package*.json",
"yarn.lock",
"node_modules",
"test"
]
},
"context": {
"@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
"@aws-cdk/core:stackRelativeExports": true,
"@aws-cdk/aws-rds:lowercaseDbIdentifier": true,
"@aws-cdk/aws-lambda:recognizeVersionProps": true,
"@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true,
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
"@aws-cdk/core:target-partitions": [
"aws",
"aws-cn"
],
"domainName": "ドメイン名設定"
}
}
package.json
{
"name": "unique-domain-hosting",
"version": "0.1.0",
"bin": {
"unique-domain-hosting": "bin/unique-domain-hosting.js"
},
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"test": "jest",
"cdk": "cdk"
},
"keywords": [],
"author": "Yasunori Kirimoto",
"license": "ISC",
"devDependencies": {
"@types/jest": "^26.0.10",
"@types/node": "10.17.27",
"jest": "^26.4.2",
"ts-jest": "^26.2.0",
"aws-cdk": "2.15.0",
"ts-node": "^9.0.0",
"typescript": "~3.9.7"
},
"dependencies": {
"aws-cdk-lib": "2.15.0",
"constructs": "^10.0.0",
"source-map-support": "^0.5.16"
}
}
事前準備
- AWS CLIのインストールと設定
- AWS CDK #001 - TypeScript環境構築
- Amazon Route 53による独自ドメインの取得
実行環境
- node v16.10.0
- npm v7.24.0
構築の流れ
各ファイル配置と設定ファイル更新
はじめに、各ファイル配置と設定ファイルを更新します。
「aws-cdk-templates-showcase」リポジトリ内の「unique-domain-hosting」ディレクトリをそのまま利用するか任意の場所にコピーします。
「cdk.json」にAmazon Route 53で取得した独自ドメイン名を設定します。
"domainName": "ドメイン名設定"
「dist」ディレクトリにデプロイしたいアプリケーションファイル一式をコピーします。
独自ドメインホスティング環境を自動デプロイ
最後に、独自ドメインホスティング環境を自動デプロイします。
パッケージをインストールします。
npm install
デプロイ前に初回のみ下記コマンドを実行します。リージョンを変更した時にも実行します。
cdk bootstrap
プロジェクトをデプロイします。
cdk deploy
スタックが作成されたのを確認。各サービスも自動作成されているのを確認できます。
独自ドメインにアクセスするとデプロイしたWebSiteが表示されます。
AWS CDKを利用することで、独自ドメインホスティング等のさまざまなリソース構築を自動化することが可能です。今回は、ACMを固定リージョンで作成やCloudFront用のS3バケットポリシー自動生成やデプロイしたいアプリケーションをコード内で定義する等がコード量も少なく実装可能でした。各機能定義は、AWS CloudFormationと同様にドキュメントで学習する必要はありますが、すごく将来性を感じるツールで構築するのが楽しいです
今後も色々と自動化していければと思います!
AWS CDKについて、他にも記事を書いています。よろしければぜひ
tags - AWS CDK
やってみたシリーズ
tags - Try