AWS CDK チュートリアル with TypeScript
AWS CDK を長らく使っているけど、改めてゼロからプロジェクトを作る手順を整理したいと思う。
とりあえず API Gateway + Lambda で Web API を作るまで。以下構成図。
ここを読んで参考にしながら進めて行く。
Node.js のバージョンを確認し、プロジェクトを作成する。cdk
コマンドを別途インストールするのは面倒なので npx
を使って実行する。
$ node --version
v22.9.0
$ mkdir aws-cdk-example && cd aws-cdk-example
$ npx cdk init --language typescript
特に何も入力を求められることなく cdk init
は終了する。作成された package.json
の中身はこんなカンジ。
{
"name": "aws-cdk-example",
"version": "0.1.0",
"bin": {
"aws-cdk-example": "bin/aws-cdk-example.js"
},
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"test": "jest",
"cdk": "cdk"
},
"devDependencies": {
"@types/jest": "^29.5.12",
"@types/node": "22.5.4",
"jest": "^29.7.0",
"ts-jest": "^29.2.5",
"aws-cdk": "2.162.0",
"ts-node": "^10.9.2",
"typescript": "~5.6.2"
},
"dependencies": {
"aws-cdk-lib": "2.162.0",
"constructs": "^10.0.0",
"source-map-support": "^0.5.21"
}
}
おもしろいのは最初から git リポジトリとして作成されており、最初のコミット(Initial commit)が既にされている点。
jest
ではなく vitest
を使いたいので jest
関連パッケージを削除して vitest
を追加する。
$ npm uninstall jest ts-jest @types/jest
removed 287 packages, and audited 68 packages in 501ms
3 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
$ npm install --save-dev vitest
added 40 packages, and audited 108 packages in 2s
15 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
npm test
で vitest
が実行されるように package.json
を書き換える。
- "test": "jest",
+ "test": "vitest run",
+ "test:watch": "vitest watch",
.env
を使いたいので dotenv
をインストールする。
$ npm install --save dotenv
added 2 packages, and audited 110 packages in 396ms
16 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
※ node.js v20.6.0 以降は node.js 単体で .env
の読み込みに対応しているっぽいが node
コマンドのコマンドラインオプションの指定が必要など AWS CDK との相性が悪そうなので dotenv
を用いることにした。
AWS CDK を使う場合 npm run build
で .ts
ファイルがビルドされて .js
や .d.ts
ファイルが生成される。
これらを一括削除したい場合があるので rimraf
を導入し、npm run clean
で生成したファイルを削除できるようにする。
$ npm install --save-dev rimraf
added 41 packages, and audited 151 packages in 1s
29 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
package.json
の scripts
に以下を追加する。
"scripts": {
"build": "tsc",
"cdk": "cdk",
+ "clean": "rimraf {bin,lib}/*.{d.ts,js}",
"test": "vitest",
"watch": "tsc -w"
},
せっかくだから eslint
や prettier
じゃなくて biome
を使ってみたいのでインストールする。
$ npm install --save-dev --save-exact @biomejs/biome
added 2 packages, and audited 153 packages in 471ms
30 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
biome init
を実行すると設定ファイルが生成される。--jsonc
オプションを指定することで biome.json
の代わりに biome.jsonc
が生成される。
$ npx biome init --jsonc
Welcome to Biome! Let's get you started...
Files created
- biome.jsonc
Your project configuration. See https://biomejs.dev/reference/configuration
Next Steps
1. Setup an editor extension
Get live errors as you type and format when you save.
Learn more at https://biomejs.dev/guides/integrate-in-editor/
2. Try a command
biome check checks formatting, import sorting, and lint rules.
biome --help displays the available commands.
3. Migrate from ESLint and Prettier
biome migrate eslint migrates your ESLint configuration to Biome.
biome migrate prettier migrates your Prettier configuration to Biome.
4. Read the documentation
Find guides and documentation at https://biomejs.dev/guides/getting-started/
5. Get involved with the community
Ask questions and contribute on GitHub: https://github.com/biomejs/biome
Seek for help on Discord: https://discord.gg/BypW39g6Yc
生成される biome.jsonc
の内容は以下の通り。
{
"$schema": "https://biomejs.dev/schemas/1.9.3/schema.json",
"vcs": {
"enabled": false,
"clientKind": "git",
"useIgnoreFile": false
},
"files": {
"ignoreUnknown": false,
"ignore": []
},
"formatter": {
"enabled": true,
"indentStyle": "tab"
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
}
}
今回は以下のように設定した。
{
"$schema": "https://biomejs.dev/schemas/1.9.3/schema.json",
"vcs": {
// Biome の VCS 統合を有効にする
"enabled": true,
"clientKind": "git",
// .gitignore に記述されたファイルを無視する
"useIgnoreFile": true
},
"files": {
"include": ["bin/**/*.ts", "lib/**/*.ts", "test/**/*.ts", "*.json", "*.jsonc"],
"ignore": ["**/*.d.ts"]
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 120
},
"organizeImports": {
"enabled": true
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"semicolons": "asNeeded"
}
}
}
最後に npm run check
で biome check
が実行されるようにする。
"cdk": "cdk",
+ "check": "biome check --write",
+ "check:dry-run": "biome check",
"clean": "rimraf {bin,lib}/*.{d.ts,js}",
husky
+ lint-staged
を導入してコミット時に biome check
が行われるようにする。
$ npm install --save-dev husky lint-staged
added 49 packages, and audited 202 packages in 3s
58 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
.lintstagedrc.yaml
を以下の通り作成する。
---
'*.{js,ts,json,jsonc}':
- npm run check
husky init
を実行し、生成された .husky/pre-commit
を以下の通り編集する。
-npm test
+npx lint-staged
いよいよ本題。まずは Route53 の Hosted Zone(ホストゾーン)を追加する。
まず最初に lib/aws-cdk-example-stack.ts
を削除し、新たに lib/lambda-api-stack.ts
を以下の通り作成する。
import * as cdk from 'aws-cdk-lib'
import type { Construct } from 'constructs'
interface LambdaApiStackProps extends cdk.StackProps {
hostedZoneName: string
}
export class LambdaApiStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: LambdaApiStackProps) {
super(scope, id, props)
// TODO: 実装する
}
}
続いてテストを書く。先程同様に test/aws-cdk-example.test.ts
を削除し test/lambda-api-stack.test.ts
を以下の通り作成する。
import * as cdk from 'aws-cdk-lib'
import { Template } from 'aws-cdk-lib/assertions'
import { beforeAll, describe, it } from 'vitest'
import { LambdaApiStack } from '../lib/lambda-api-stack'
describe('LambdaApiStack', () => {
let template: Template
beforeAll(() => {
const app = new cdk.App()
const stack = new LambdaApiStack(app, 'TestStack', {
hostedZoneName: 'example.org',
})
template = Template.fromStack(stack)
})
it('has hosted zone', () => {
template.resourceCountIs('AWS::Route53::HostedZone', 1)
})
it('has hosted zone with the specified name', () => {
template.hasResourceProperties('AWS::Route53::HostedZone', {
Name: 'example.org.',
})
})
})
npm test
を実行し、テストが落ちることを確認する。
$ npm test
> aws-cdk-example@0.1.0 test
> vitest run
RUN v2.1.2 /Users/shogogg/work/aws-cdk-example
❯ test/lambda-api-stack.test.ts (2)
❯ LambdaApiStack (2)
× has hosted zone
× has hosted zone with the specified name
準備が整ったので LambdaApiStack
に Hosted Zone を追加する。lib/lambda-api-stack.ts
に以下の記述を追加する。
export class LambdaApiStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: LambdaApiStackProps) {
super(scope, id, props)
+ const { hostedZoneName } = props
+
+ // Route 53: Hosted Zone
+ new route53.HostedZone(this, 'HostedZone', {
+ zoneName: hostedZoneName,
+ })
}
}
改めてテストを実行すると今度は無事に通過する。
$ npm test
> aws-cdk-example@0.1.0 test
> vitest run
RUN v2.1.2 /Users/shogogg/work/aws-cdk-example
✓ test/lambda-api-stack.test.ts (2)
✓ LambdaApiStack (2)
✓ has hosted zone
✓ has hosted zone with the specified name
続いて bin/lambda-api-app.ts
を以下の通り作成する。
#!/usr/bin/env node
import 'source-map-support/register'
import * as cdk from 'aws-cdk-lib'
import * as dotenv from 'dotenv'
import { LambdaApiStack } from '../lib/lambda-api-stack'
// Load environment variables from .env file
dotenv.config()
const account = process.env.APP_AWS_ACCOUNT ?? process.env.CDK_DEFAULT_ACCOUNT
const region = process.env.APP_AWS_REGION ?? process.env.CDK_DEFAULT_REGION
const appName = process.env.APP_NAME ?? 'ExampleApp'
const hostedZoneName = process.env.APP_HOSTED_ZONE_NAME ?? 'example.com'
const app = new cdk.App()
new LambdaApiStack(app, `${appName}LambdaApiStack`, {
env: {
account,
region,
},
hostedZoneName,
})
環境変数 CDK_DEFAULT_ACCOUNT と CDK_DEFAULT_REGION について
これらの環境変数は AWS CDK が「用意している」としている環境変数。今回は自前の環境変数が未定義の場合はそちらを参照するようにしている。
以下の通り .env
ファイルを作成する。APP_HOSTED_ZONE_NAME
には自身で DNS の設定が可能な適当なドメインを、APP_AWS_ACCOUNT
には実際の AWS アカウント ID(12桁の数字)を指定する。
APP_NAME=ExampleApp
APP_HOSTED_ZONE_NAME=************
APP_AWS_ACCOUNT=************
APP_AWS_REGION=ap-northeast-1
これで準備は完了。長くなったのでいったんここまで。
前回作成したものをデプロイしていく。
まず最初に cdk bootstrap
を実行し、AWS 環境に CDK を使ったデプロイに必要なリソース等を準備する。
cdk bootstrap
$ npx cdk bootstrap
MFA token for arn:aws:iam::************:mfa/********: ******
⏳ Bootstrapping environment aws://************/ap-northeast-1...
Trusted accounts for deployment: (none)
Trusted accounts for lookup: (none)
Using default execution policy of 'arn:aws:iam::aws:policy/AdministratorAccess'. Pass '--cloudformation-execution-policies' to customize.
CDKToolkit: creating CloudFormation changeset...
✅ Environment aws://************/ap-northeast-1 bootstrapped.
cdk bootstrap
については以下の記事を読むと色々と詳しく書いてある。
build
続いてチュートリアルに従ってビルドを行う、と言いたいところだけど、その前に tsconfig.json
をちょっといじる。
今回の構成ではテストに vitest
を用いているため、test
以下のコードをビルドされると百害あって一利なし。なので exclude
に test
を追加する。
- "exclude": ["node_modules", "cdk.out"]
+ "exclude": ["node_modules", "cdk.out", "test"]
tsconfig.json
の編集が済んだら今度こそビルドを行う。
$ npm run build
> aws-cdk-example@0.1.0 build
> tsc
cdk list
ビルドすると cdk list
コマンドでスタックの一覧が表示できるようになる。
$ npx cdk list
ExampleAppLambdaApiStack
cdk synth
ビルド後に cdk synth
を実行すると CloudFormation のテンプレートが cdk.out
以下に生成される。
$ npx cdk synth
Resources:
HostedZoneDB99F866:
Type: AWS::Route53::HostedZone
Properties:
Name: ****************.
Metadata:
aws:cdk:path: ExampleAppLambdaApiStack/HostedZone/Resource
CDKMetadata:
Type: AWS::CDK::Metadata
Properties:
Analytics: v2:deflate64:H4sIAAAAAAAA/zPSMzQz0jNUTCwv1k1OydbNyUzSqw4uSUzO1kksL44vyi8tSTU11qv2yC8uSU2Jys9L1XFOy0PwakHcoNTi/NKi5NRanbz8lFS9rGL9MiMjPUs9A8Ws4sxM3aLSvJLM3FS9IAgNAJXDNSNzAAAA
Metadata:
aws:cdk:path: ExampleAppLambdaApiStack/CDKMetadata/Default
Parameters:
BootstrapVersion:
Type: AWS::SSM::Parameter::Value<String>
Default: /cdk-bootstrap/hnb659fds/version
Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]
この cdk list
や cdk synth
はデプロイするだけなら都度実行する必要はないんだけど、触ってみると CDK が何をしているのかがわかってちょっと面白い。
cdk deploy
いよいよデプロイ。cdk deploy
コマンドを実行してデプロイを行う。
$ npx cdk deploy
MFA token for arn:aws:iam::************:mfa/********: ******
✨ Synthesis time: 7.22s
ExampleAppLambdaApiStack: start: Building 2ee87e0922900ea69049ccf5eda7714689d8af4fd6f998a367e8125exxxxxxxx:************-ap-northeast-1
ExampleAppLambdaApiStack: success: Built 2ee87e0922900ea69049ccf5eda7714689d8af4fd6f998a367e8125exxxxxxxx:************-ap-northeast-1
ExampleAppLambdaApiStack: start: Publishing 2ee87e0922900ea69049ccf5eda7714689d8af4fd6f998a367e8125exxxxxxxx:************-ap-northeast-1
ExampleAppLambdaApiStack: success: Published 2ee87e0922900ea69049ccf5eda7714689d8af4fd6f998a367e8125exxxxxxxx:************-ap-northeast-1
Stack undefined
ExampleAppLambdaApiStack: deploying... [1/1]
ExampleAppLambdaApiStack: creating CloudFormation changeset...
✅ ExampleAppLambdaApiStack
✨ Deployment time: 72.56s
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:************:stack/ExampleAppLambdaApiStack/635d3fb0-xxxx-xxxx-xxxx-0ad8feee2f63
✨ Total time: 79.78s
無事にデプロイが完了した。AWS マネジメントコンソール から、以下を確認できる。
- CloudFormation に
ExampleAppLambdaApiStack
が追加されていること。 - Route 53 に指定した Hosted Zone が追加されていること。
cdk destroy
気軽にデプロイできる&破棄できるのが IaC のいいところ。という訳で今デプロイしたものを早速破棄してみる。
$ npx cdk destroy
MFA token for arn:aws:iam::************:mfa/********: ******
Are you sure you want to delete: ExampleAppLambdaApiStack (y/n)? y
ExampleAppLambdaApiStack: destroying... [1/1]
✅ ExampleAppLambdaApiStack: destroyed
これできれいさっぱり消えたはず。
続いて Lambda 関数を追加する。まずはテスト。
+ it('has lambda function', () => {
+ template.resourceCountIs('AWS::Lambda::Function', 1)
+ })
+
+ it('has lambda function with the specified runtime', () => {
+ template.hasResourceProperties('AWS::Lambda::Function', {
+ Runtime: 'nodejs20.x',
+ })
+ })
テストが落ちることを確認したら LambdaApiStack
に Lambda 関数を追加していく。まずは追加する関数本体を TypeScript で記述するため、@types/aws-lambda
を依存パッケージに追加する。
$ npm install --save-dev @types/aws-lambda
added 1 package, and audited 203 packages in 449ms
58 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
次に lib/lambda-api-stack.app.ts
を以下の通り作成。
import type { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'
export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
// クエリパラメータで指定された挨拶を用いる
const greeting = event.queryStringParameters?.greeting ?? 'Hello'
// 環境変数で指定された名前を用いる
const name = process.env.APP_GREETING_NAME ?? 'World'
return {
statusCode: 200,
body: JSON.stringify({
message: `${greeting}, ${name}!`,
}),
}
}
最後に LambdaApiStack
に Lambda 関数の定義を追加する。
export class LambdaApiStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: LambdaApiStackProps) {
super(scope, id, props)
const { hostedZoneName } = props
+ // Lambda: Function
+ new lambdaNodejs.NodejsFunction(this, 'app', {
+ runtime: lambda.Runtime.NODEJS_20_X,
+ })
+
// Route 53: Hosted Zone
new route53.HostedZone(this, 'HostedZone', {
zoneName: hostedZoneName,
})
}
}
ここまで来ればテストが通るようになる。
$ npm test
API Gateway の定義を追加する。まずはテスト。
+ it('has API Gateway REST API', () => {
+ template.resourceCountIs('AWS::ApiGateway::RestApi', 1)
+ })
+
+ it('has API Gateway Resource', () => {
+ template.resourceCountIs('AWS::ApiGateway::Resource', 1)
+ })
+
+ it('has API Gateway Resource with the specified path', () => {
+ template.hasResourceProperties('AWS::ApiGateway::Resource', {
+ PathPart: 'example',
+ })
+ })
テストが落ちることを確認したら LambdaApiStack
に API Gateway の定義を追加していく。
// Lambda: Function
- lambdaNodejs.NodejsFunction(this, 'app', {
+ const apiFunction = new lambdaNodejs.NodejsFunction(this, 'app', {
runtime: lambda.Runtime.NODEJS_20_X,
})
+
+ // API Gateway: Routing
+ const api = new apiGateway.RestApi(this, 'ApiGateway')
+ api.root.addResource('example').addMethod('GET', new apiGateway.LambdaIntegration(apiFunction))
テストの通過を確認したら次へ。
API で用いるサーバー証明書を追加する。まずは Hosted Zone に追加する API 用のドメイン名を設定できるようにする。
interface LambdaApiStackProps extends cdk.StackProps {
hostedZoneName: string
+ domainName: string
}
型定義の変更に伴い、bin/lambda-api-app.ts
および test/lambda-api-stack.test.ts
にも修正を加える。
const hostedZoneName = process.env.APP_HOSTED_ZONE_NAME ?? 'example.com'
+const domainName = process.env.APP_DOMAIN_NAME ?? 'api.example.com'
const app = new cdk.App()
new LambdaApiStack(app, `${appName}LambdaApiStack`, {
env: {
account,
region
},
hostedZoneName,
+ domainName
})
beforeAll(() => {
const app = new cdk.App()
const stack = new LambdaApiStack(app, 'TestStack', {
hostedZoneName: 'example.org',
+ domainName: 'api.example.org',
})
template = Template.fromStack(stack)
})
準備が整ったので、まずはテストを追加する。
+ it('has ACM certificate', () => {
+ template.resourceCountIs('AWS::CertificateManager::Certificate', 1)
+ })
+
+ it('has ACM certificate with the specified domain name', () => {
+ template.hasResourceProperties('AWS::CertificateManager::Certificate', {
+ DomainName: 'api.example.org',
+ })
+ })
テストが落ちることを確認したら、LambdaApiStack
に証明書の定義を追加していく。
super(scope, id, props)
+ const { hostedZoneName, domainName } = props
// Lambda: Function
const apiFunction = new lambdaNodejs.NodejsFunction(this, 'app', {
runtime: lambda.Runtime.NODEJS_20_X,
})
// API Gateway: Routing
const api = new apiGateway.RestApi(this, 'ApiGateway')
api.root.addResource('example').addMethod('GET', new apiGateway.LambdaIntegration(apiFunction))
// Route 53: Hosted Zone
- new route53.HostedZone(this, 'HostedZone', {
+ const hostedZone = new route53.HostedZone(this, 'HostedZone', {
zoneName: hostedZoneName,
})
+
+ // ACM: Certificate
+ new certificationManager.Certificate(this, 'Certificate', {
+ domainName,
+ validation: certificationManager.CertificateValidation.fromDns(hostedZone),
+ })
テストの通過を確認したら次へ。
次に API Gateway へカスタムドメインの設定を行う。まずはテストから。
+ it('has API Gateway Custom Domain', () => {
+ template.resourceCountIs('AWS::ApiGateway::DomainName', 1)
+ })
+
+ it('has API Gateway Custom Domain with the specified domain name', () => {
+ template.hasResourceProperties('AWS::ApiGateway::DomainName', {
+ DomainName: 'api.example.org',
+ })
+ })
テストが落ちることを確認したら LambdaApiStack
を修正する。
// ACM: Certificate
- new certificationManager.Certificate(this, 'Certificate', {
+ const certificate = new certificationManager.Certificate(this, 'Certificate', {
domainName,
validation: certificationManager.CertificateValidation.fromDns(hostedZone),
})
+
+ // API Gateway: Custom Domain
+ const customDomain = new apiGateway.DomainName(this, 'CustomDomain', {
+ domainName,
+ certificate,
+ securityPolicy: apiGateway.SecurityPolicy.TLS_1_2,
+ endpointType: apiGateway.EndpointType.REGIONAL,
+ })
+ customDomain.addBasePathMapping(api)
テストの通過を確認したら次へ。
定義はこれでラスト。Route 53 の Hosted Zone に API Gateway 用のレコードを追加する。まずはテスト。
+ it('has Route 53 RecordSet', () => {
+ template.resourceCountIs('AWS::Route53::RecordSet', 1)
+ })
+
+ it('has Route 53 RecordSet with the specified domain name', () => {
+ template.hasResourceProperties('AWS::Route53::RecordSet', {
+ Name: 'api.example.org.',
+ })
+ })
+
+ it('has Route 53 RecordSet with the specified type', () => {
+ template.hasResourceProperties('AWS::Route53::RecordSet', {
+ Type: 'A',
+ })
+ })
テストが落ちることを確認し、LambdaApiStack
に定義を追加する。
customDomain.addBasePathMapping(api)
+
+ // Route 53: Record
+ new route53.ARecord(this, 'ARecord', {
+ zone: hostedZone,
+ recordName: domainName,
+ target: route53.RecordTarget.fromAlias(new route53Targets.ApiGatewayDomain(customDomain)),
+ })
テストの通過を確認したら次へ。
一通りリソースの定義ができたのでデプロイして動作を確認する。
$ npx cdk deploy
(略)
$ curl "https://api.example.com/example"
{"message": "Hello, World!"}
$ curl "https://api.example.com/example?greeting=Hi"
{"message": "Hi, World!"}
今回作成した Lambda 関数は環境変数でメッセージを変更できるようになっているので、変更してみる。LambdaApiStack
に以下の通り追記。
// Lambda: Function
const apiFunction = new lambdaNodejs.NodejsFunction(this, 'app', {
runtime: lambda.Runtime.NODEJS_20_X,
+ environment: {
+ APP_GREETING_NAME: 'Lambda',
+ },
})
再度デプロイ、実行してみる。
$ npx cdk deploy
(略)
$ curl "https://api.example.com/example"
{"message": "Hello, Lambda!"}
$ curl "https://api.example.com/example?greeting=Hi"
{"message": "Hi, Lambda!"}
期待通り動いた。今回はここまで。
最終的な LambdaApiStack
の全貌はこちら。
import * as cdk from 'aws-cdk-lib'
import * as apiGateway from 'aws-cdk-lib/aws-apigateway'
import * as certificationManager from 'aws-cdk-lib/aws-certificatemanager'
import * as lambda from 'aws-cdk-lib/aws-lambda'
import * as lambdaNodejs from 'aws-cdk-lib/aws-lambda-nodejs'
import * as route53 from 'aws-cdk-lib/aws-route53'
import * as route53Targets from 'aws-cdk-lib/aws-route53-targets'
import type { Construct } from 'constructs'
interface LambdaApiStackProps extends cdk.StackProps {
hostedZoneName: string
domainName: string
}
export class LambdaApiStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: LambdaApiStackProps) {
super(scope, id, props)
const { hostedZoneName, domainName } = props
// Lambda: Function
const apiFunction = new lambdaNodejs.NodejsFunction(this, 'app', {
runtime: lambda.Runtime.NODEJS_20_X,
environment: {
APP_GREETING_NAME: 'Lambda',
},
})
// API Gateway: Routing
const api = new apiGateway.RestApi(this, 'ApiGateway')
api.root.addResource('example').addMethod('GET', new apiGateway.LambdaIntegration(apiFunction))
// Route 53: Hosted Zone
const hostedZone = new route53.HostedZone(this, 'HostedZone', {
zoneName: hostedZoneName,
})
// ACM: Certificate
const certificate = new certificationManager.Certificate(this, 'Certificate', {
domainName,
validation: certificationManager.CertificateValidation.fromDns(hostedZone),
})
// API Gateway: Custom Domain
const customDomain = new apiGateway.DomainName(this, 'CustomDomain', {
domainName,
certificate,
securityPolicy: apiGateway.SecurityPolicy.TLS_1_2,
endpointType: apiGateway.EndpointType.REGIONAL,
})
customDomain.addBasePathMapping(api)
// Route 53: Record
new route53.ARecord(this, 'ARecord', {
zone: hostedZone,
recordName: domainName,
target: route53.RecordTarget.fromAlias(new route53Targets.ApiGatewayDomain(customDomain)),
})
}
}
GitHub にリポジトリを作成して一連のコードを公開した、