AWS CDKの入門として、「AWS CDKをゼロから始めて、API Gateway+Lambda+DynamoDBのリソース群をパッと作るまでの流れ」をまとめました。
手順通り実行すれば1時間ほどで試せるハンズオンになっているので、試してみてください。
AWS CDK(Cloud Development Kit)とは?
AWSのリソース群を、より簡単に定義し作成できるフレームワークです。
AWS CDKのメリット
AWS CDKのメリットは、入門的な観点では特に、以下2点が挙げられます。
- IDE(統合開発環境)の補完機能が使える
- 少ない記述量で、必要なリソース群を生成できる
今までは、リソースの生成・管理はCloudFormationのテンプレートファイルをJSONかYAMLの形式で全て自分で記述する必要がありました。
CDKでは、TypeScriptやPythonなどのプログラミング言語でリソースを定義するので、アプリケーションのコーディングと同様にIDEで補完機能を使いながら記述することができます。
また、リソースの定義も大部分をデフォルト値で設定できるため、多くの定義を省略することができます。そのため、記述量を少なく済ませることができます。
ハンズオンをやってみよう
以降は、AWS CDKを体感するためのハンズオンの手順です!
手順に沿っていくと、以下の構成のAPI Gateway+Lambda+DynamoDBを作成できます。
この構成のためにCloudFormationでは以下のようなリソース群を生成します。
環境
OS: macOS Mojave 10.14.6
CDK CLI: 1.25.0
TypeScript: 3.7.3
Node: 10.17.0
インストール
AWS CDKを利用するために、コマンドラインツールをインストールします。
$ npm install -g aws-cdk
インストールされているか確認するために、バージョン確認をします。
$ cdk --version
1.25.0 (build 309ac1b)
プロジェクトの作成
CDKのプロジェクトを作成します。
$ mkdir cdk-test
$ cd cdk-test
$ cdk init app --language=typescript
//npm installなどが実行された後、以下が表示されます。
# Welcome to your CDK TypeScript project!
This is a blank project for TypeScript development with CDK.
The `cdk.json` file tells the CDK Toolkit how to execute your app.
## Useful commands
* `npm run build` compile typescript to js
* `npm run watch` watch for changes and compile
* `npm run test` perform the jest unit tests
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk synth` emits the synthesized CloudFormation template
ここまで実行すると、プロジェクト内に以下のような構造が出来上がります。(1階層のみ表示しています。)
$ tree -L 1
.
├── README.md
├── bin
├── cdk.json
├── jest.config.js
├── lib
├── node_modules
├── package-lock.json
├── package.json
├── test
└── tsconfig.json
CDKで生成したいリソースは基本的にlib
フォルダの中にあるcdk-test-stack.ts
にコードを書いて定義していくことになります。
必要なリソースのライブラリのインストール
生成したいリソースに応じて、使用するライブラリをインストールします。
今回は、Lambda、DynamoDB、API Gateway、IAMが必要になるので、それぞれインストールします。
$ npm install @aws-cdk/aws-lambda @aws-cdk/aws-dynamodb @aws-cdk/aws-apigateway @aws-cdk/aws-iam
コード
生成したいリソースをcdk-test-stack.ts
に定義していきます。
ちなみにプロジェクトを作成した初期状態ではcdk-test-stack.ts
は以下のようになっていますが、
コメントが書いてあるところにコードを追記することで、生成するリソースを定義することができます。
import * as cdk from '@aws-cdk/core';
// ここに使用するライブラリを追記する
export class CdkTestStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// The code that defines your stack goes here
// ここに生成するリソースを定義する
}
}
今回は以下のように定義します。(クリックして表示)
import * as cdk from '@aws-cdk/core'
// ここに使用するライブラリを追記する
import * as lambda from '@aws-cdk/aws-lambda'
import * as apigateway from '@aws-cdk/aws-apigateway'
import * as dynamodb from '@aws-cdk/aws-dynamodb'
import * as iam from '@aws-cdk/aws-iam'
export class CdkTestStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// The code that defines your stack goes here
// ここに生成するリソースを定義する
cdk.Tag.add(this, 'use-case', 'workshop')
const tableName = 'cdk-test-table'
// Lambdaの定義
const cdkTestFunction = new lambda.Function(this, 'cdk-test-function', {
// 必須の項目
runtime: lambda.Runtime.NODEJS_12_X,
handler: 'index.handler',
code: lambda.Code.asset('lambda'),
// オプション項目
functionName: 'cdk-test-function',
environment:{
'TABLE_NAME': tableName
}
})
// API Gatewayの定義
const cdkTestApi = new apigateway.RestApi(this, 'cdk-test-api', {
// オプション項目
restApiName: 'cdk-test-api',
deployOptions: {
stageName: 'test'
}
})
// DynamoDBの定義
const cdkTestTable = new dynamodb.Table(this, 'cdk-test-table', {
// 必須の項目
partitionKey: { name: 'user_id', type: dynamodb.AttributeType.NUMBER },
// オプション項目
sortKey: { name: 'created_at', type: dynamodb.AttributeType.STRING },
tableName: tableName
})
//Lambda→DynamoDBのアクセスポリシーの定義
cdkTestFunction.addToRolePolicy(new iam.PolicyStatement({
resources: [cdkTestTable.tableArn],
actions: [
'dynamodb:PutItem'
]
}
))
// API gateway→Lambdaの接続定義
const integration = new apigateway.LambdaIntegration(cdkTestFunction)
cdkTestApi.root.addMethod('POST', integration)
}
}
コードの中身の説明
上記のcdk-test-stack.ts
のコードの内容について、例を取り上げて説明します。
リソースの定義方法について
上記コードの中で、Lambdaの定義方法を例に、リソースの定義方法について解説します。
Lambdaの定義は公式のリファレンスに沿ってlambda.Function()
を使用しています。
lambda.Function()
は3つ目の引数にFunctionProps
がありますが、この中がLambdaの定義になります。
lambda.Function()
のリファレンスページをみると、以下のようなprops
を定義できるようになっています。(一部抜粋)
この中で、定義が必須なものは「Name」列の項目で「?」がついていないもの。
この中でいうとcode
、handler
、runtime
の3つのみが必須です。
最低限3つのprops
を定義すればLambdaが生成できちゃうということになります!
ちなみに今回のLambdaは、必須の3項目に加えてfunctionName
とenvironment
を定義しています。
// Lambdaの定義
const cdkTestFunction = new lambda.Function(this, 'cdk-test-function', {
// 必須の項目
runtime: lambda.Runtime.NODEJS_12_X,
handler: 'index.handler',
code: lambda.Code.asset('lambda'),
// オプション項目
functionName: 'cdk-test-function',
environment:{
"TABLE_NAME": tableName
}
})
その他のリソースについても同様に定義することで生成できます。
定義の追加方法
定義したリソースは、その後methods
を利用することで追加の定義を入れることができます。
例えばLambdaでは、以下のようなmethods
を利用できます。(一部抜粋)
今回のLambdaでは、addToRolePolicy()
を使用して、DynamoDBへのアクセスポリシーを追加しています。
cdkTestFunction.addToRolePolicy(new iam.PolicyStatement({
resources: [cdkTestTable.tableArn],
actions: [
'dynamodb:PutItem'
]
}
))
Lambdaの関数の作成
Lambdaの中身の関数を作成していきます。
cdk-test-stack.ts
内でLambdaは以下のような定義を指定していましたが、それぞれの定義は、横に記述したコメントの通りとなります。
// 必須の項目
runtime: lambda.Runtime.NODEJS_12_X, //LambdaはNode.js(12.X)で動作します
handler: 'index.handler', //Lambdaは"index.~"というファイルの"handler"という関数を使用します
code: lambda.Code.asset('lambda'), //関数が記述されているファイルは"lambda"ディレクトリに格納しています
上記のように定義しているので、今回Lambdaで使用する関数は、以下の手順で作成していきます。
①プロジェクト直下にlambda
ディレクトリを作成する
②lambdaディレクトリ内にindex.js
を作成する
③index.js
内にhandler
という関数を作成する
以下は、①~③でやったことです。
①②:まず必要なディレクトリをファイルを作成するために以下コマンドを実行します。
$ mkdir lambda
$ cd ./lambda
$ touch index.js
$ cd ..
以下のような構成になっていればOKです!
$ tree -L 1
.
├── README.md
├── bin
├── cdk.json
├── jest.config.js
├── lambda //この中にindex.jsがあればOK!
├── lib
├── node_modules
├── package-lock.json
├── package.json
├── test
└── tsconfig.json
③:handler関数を定義します。
`index.js`には以下のようなプログラムを書きました。(クリックして表示)
const AWS = require('aws-sdk')
const client = new AWS.DynamoDB.DocumentClient()
const tableName = process.env.TABLE_NAME
let items = {}
const get_time = () => {
let dt = new Date()
dt.setTime(dt.getTime() + 32400000)
let year = dt.getFullYear()
let month = dt.getMonth()+1
let day = dt.getDate()
let hour = dt.getHours()
let min = dt.getMinutes()
let sec = dt.getSeconds()
if (month < 10) {
month = '0' + month
}
if (day < 10) {
day = '0' + day
}
if (hour < 10) {
hour = '0' + hour
}
if (min < 10) {
min = '0' + min
}
if (sec < 10) {
sec = '0' + sec
}
let Date_now = year + '/' + month + '/' + day + '-' + hour + ':' + min + ':' + sec
return Date_now
}
exports.handler = async (event) => {
if (typeof(event.body) === 'string') {
items = JSON.parse(event.body)
} else {
items = event.body
}
const params = {
TableName: tableName,
Item: {
user_id: items.user_id,
created_at: get_time(),
amount: items.amount
}
}
console.log(params)
await client.put(params).promise()
return {
statusCode: 200,
body: 'Put Success: ' + JSON.stringify(items)
}
}
ここまで定義した内容で、どのようなCloudFormationテンプレートが生成されるかを確認するために、以下のコマンドを実行します。
$ cdk synth
このコマンドを実行すると、YAML形式のCloudFormationテンプレートがコマンドラインに表示されます。
同時にcdk.out
というディレクトリが生成され、その中にCdkTestStack.template.json
というJSON形式のCloudFormationテンプレートも生成されます。
コマンドラインに表示されるYAML形式のテンプレートは、以下のようになりました。(クリックして展開)
Resources:
cdktestfunctionServiceRole4CE3A73D:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Version: "2012-10-17"
ManagedPolicyArns:
- Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Tags:
- Key: use-case
Value: workshop
Metadata:
aws:cdk:path: CdkTestStack/cdk-test-function/ServiceRole/Resource
cdktestfunctionServiceRoleDefaultPolicy070552D2:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action: dynamodb:PutItem
Effect: Allow
Resource:
Fn::GetAtt:
- cdktesttableB0274F47
- Arn
Version: "2012-10-17"
PolicyName: cdktestfunctionServiceRoleDefaultPolicy070552D2
Roles:
- Ref: cdktestfunctionServiceRole4CE3A73D
Metadata:
aws:cdk:path: CdkTestStack/cdk-test-function/ServiceRole/DefaultPolicy/Resource
cdktestfunction799CDE6C:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket:
Ref: AssetParameters008187cf4b97caf9f33bda82c0b2bf2d0cbdb4f5e4a1f8a81f97d02c6424b1d1S3Bucket612EC6C8
S3Key:
Fn::Join:
- ""
- - Fn::Select:
- 0
- Fn::Split:
- "||"
- Ref: AssetParameters008187cf4b97caf9f33bda82c0b2bf2d0cbdb4f5e4a1f8a81f97d02c6424b1d1S3VersionKeyE312B4F3
- Fn::Select:
- 1
- Fn::Split:
- "||"
- Ref: AssetParameters008187cf4b97caf9f33bda82c0b2bf2d0cbdb4f5e4a1f8a81f97d02c6424b1d1S3VersionKeyE312B4F3
Handler: index.handler
Role:
Fn::GetAtt:
- cdktestfunctionServiceRole4CE3A73D
- Arn
Runtime: nodejs12.x
Environment:
Variables:
TABLE_NAME: cdk-test-table
FunctionName: cdk-test-function
Tags:
- Key: use-case
Value: workshop
DependsOn:
- cdktestfunctionServiceRoleDefaultPolicy070552D2
- cdktestfunctionServiceRole4CE3A73D
Metadata:
aws:cdk:path: CdkTestStack/cdk-test-function/Resource
aws:asset:path: asset.008187cf4b97caf9f33bda82c0b2bf2d0cbdb4f5e4a1f8a81f97d02c6424b1d1
aws:asset:property: Code
cdktestapi858A14F7:
Type: AWS::ApiGateway::RestApi
Properties:
Name: cdk-test-api
Tags:
- Key: use-case
Value: workshop
Metadata:
aws:cdk:path: CdkTestStack/cdk-test-api/Resource
cdktestapiDeploymentAB660FEA292ba9738d8401cffa10885c9e10869a:
Type: AWS::ApiGateway::Deployment
Properties:
RestApiId:
Ref: cdktestapi858A14F7
Description: Automatically created by the RestApi construct
DependsOn:
- cdktestapiPOST9C619890
Metadata:
aws:cdk:path: CdkTestStack/cdk-test-api/Deployment/Resource
cdktestapiDeploymentStagetest9C960D82:
Type: AWS::ApiGateway::Stage
Properties:
RestApiId:
Ref: cdktestapi858A14F7
DeploymentId:
Ref: cdktestapiDeploymentAB660FEA292ba9738d8401cffa10885c9e10869a
StageName: test
Tags:
- Key: use-case
Value: workshop
Metadata:
aws:cdk:path: CdkTestStack/cdk-test-api/DeploymentStage.test/Resource
cdktestapiCloudWatchRoleA4E10D45:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: apigateway.amazonaws.com
Version: "2012-10-17"
ManagedPolicyArns:
- Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- :iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs
Tags:
- Key: use-case
Value: workshop
Metadata:
aws:cdk:path: CdkTestStack/cdk-test-api/CloudWatchRole/Resource
cdktestapiAccountF8B5456F:
Type: AWS::ApiGateway::Account
Properties:
CloudWatchRoleArn:
Fn::GetAtt:
- cdktestapiCloudWatchRoleA4E10D45
- Arn
DependsOn:
- cdktestapi858A14F7
Metadata:
aws:cdk:path: CdkTestStack/cdk-test-api/Account
cdktestapiPOSTApiPermissionCdkTestStackcdktestapiB9D3D388POST29D4184B:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName:
Fn::GetAtt:
- cdktestfunction799CDE6C
- Arn
Principal: apigateway.amazonaws.com
SourceArn:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":execute-api:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- ":"
- Ref: cdktestapi858A14F7
- /
- Ref: cdktestapiDeploymentStagetest9C960D82
- /POST/
Metadata:
aws:cdk:path: CdkTestStack/cdk-test-api/Default/POST/ApiPermission.CdkTestStackcdktestapiB9D3D388.POST..
cdktestapiPOSTApiPermissionTestCdkTestStackcdktestapiB9D3D388POSTAD710B52:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName:
Fn::GetAtt:
- cdktestfunction799CDE6C
- Arn
Principal: apigateway.amazonaws.com
SourceArn:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":execute-api:"
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- ":"
- Ref: cdktestapi858A14F7
- /test-invoke-stage/POST/
Metadata:
aws:cdk:path: CdkTestStack/cdk-test-api/Default/POST/ApiPermission.Test.CdkTestStackcdktestapiB9D3D388.POST..
cdktestapiPOST9C619890:
Type: AWS::ApiGateway::Method
Properties:
HttpMethod: POST
ResourceId:
Fn::GetAtt:
- cdktestapi858A14F7
- RootResourceId
RestApiId:
Ref: cdktestapi858A14F7
AuthorizationType: NONE
Integration:
IntegrationHttpMethod: POST
Type: AWS_PROXY
Uri:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":apigateway:"
- Ref: AWS::Region
- :lambda:path/2015-03-31/functions/
- Fn::GetAtt:
- cdktestfunction799CDE6C
- Arn
- /invocations
Metadata:
aws:cdk:path: CdkTestStack/cdk-test-api/Default/POST/Resource
cdktesttableB0274F47:
Type: AWS::DynamoDB::Table
Properties:
KeySchema:
- AttributeName: user_id
KeyType: HASH
- AttributeName: created_at
KeyType: RANGE
AttributeDefinitions:
- AttributeName: user_id
AttributeType: "N"
- AttributeName: created_at
AttributeType: S
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
TableName: cdk-test-table
Tags:
- Key: use-case
Value: workshop
UpdateReplacePolicy: Retain
DeletionPolicy: Retain
Metadata:
aws:cdk:path: CdkTestStack/cdk-test-table/Resource
CDKMetadata:
Type: AWS::CDK::Metadata
Properties:
Modules: aws-cdk=1.25.0,@aws-cdk/assets=1.23.0,@aws-cdk/aws-apigateway=1.23.0,@aws-cdk/aws-applicationautoscaling=1.23.0,@aws-cdk/aws-autoscaling-common=1.23.0,@aws-cdk/aws-cloudwatch=1.23.0,@aws-cdk/aws-dynamodb=1.23.0,@aws-cdk/aws-ec2=1.23.0,@aws-cdk/aws-events=1.23.0,@aws-cdk/aws-iam=1.23.0,@aws-cdk/aws-kms=1.23.0,@aws-cdk/aws-lambda=1.23.0,@aws-cdk/aws-logs=1.23.0,@aws-cdk/aws-s3=1.23.0,@aws-cdk/aws-s3-assets=1.23.0,@aws-cdk/aws-sqs=1.23.0,@aws-cdk/aws-ssm=1.23.0,@aws-cdk/core=1.23.0,@aws-cdk/cx-api=1.23.0,@aws-cdk/region-info=1.23.0,jsii-runtime=node.js/v10.17.0
Condition: CDKMetadataAvailable
Parameters:
AssetParameters008187cf4b97caf9f33bda82c0b2bf2d0cbdb4f5e4a1f8a81f97d02c6424b1d1S3Bucket612EC6C8:
Type: String
Description: S3 bucket for asset "008187cf4b97caf9f33bda82c0b2bf2d0cbdb4f5e4a1f8a81f97d02c6424b1d1"
AssetParameters008187cf4b97caf9f33bda82c0b2bf2d0cbdb4f5e4a1f8a81f97d02c6424b1d1S3VersionKeyE312B4F3:
Type: String
Description: S3 key for asset version "008187cf4b97caf9f33bda82c0b2bf2d0cbdb4f5e4a1f8a81f97d02c6424b1d1"
AssetParameters008187cf4b97caf9f33bda82c0b2bf2d0cbdb4f5e4a1f8a81f97d02c6424b1d1ArtifactHash93D2A514:
Type: String
Description: Artifact hash for asset "008187cf4b97caf9f33bda82c0b2bf2d0cbdb4f5e4a1f8a81f97d02c6424b1d1"
Outputs:
cdktestapiEndpoint867D566B:
Value:
Fn::Join:
- ""
- - https://
- Ref: cdktestapi858A14F7
- .execute-api.
- Ref: AWS::Region
- "."
- Ref: AWS::URLSuffix
- /
- Ref: cdktestapiDeploymentStagetest9C960D82
- /
Conditions:
CDKMetadataAvailable:
Fn::Or:
- Fn::Or:
- Fn::Equals:
- Ref: AWS::Region
- ap-east-1
- Fn::Equals:
- Ref: AWS::Region
- ap-northeast-1
- Fn::Equals:
- Ref: AWS::Region
- ap-northeast-2
- Fn::Equals:
- Ref: AWS::Region
- ap-south-1
- Fn::Equals:
- Ref: AWS::Region
- ap-southeast-1
- Fn::Equals:
- Ref: AWS::Region
- ap-southeast-2
- Fn::Equals:
- Ref: AWS::Region
- ca-central-1
- Fn::Equals:
- Ref: AWS::Region
- cn-north-1
- Fn::Equals:
- Ref: AWS::Region
- cn-northwest-1
- Fn::Equals:
- Ref: AWS::Region
- eu-central-1
- Fn::Or:
- Fn::Equals:
- Ref: AWS::Region
- eu-north-1
- Fn::Equals:
- Ref: AWS::Region
- eu-west-1
- Fn::Equals:
- Ref: AWS::Region
- eu-west-2
- Fn::Equals:
- Ref: AWS::Region
- eu-west-3
- Fn::Equals:
- Ref: AWS::Region
- me-south-1
- Fn::Equals:
- Ref: AWS::Region
- sa-east-1
- Fn::Equals:
- Ref: AWS::Region
- us-east-1
- Fn::Equals:
- Ref: AWS::Region
- us-east-2
- Fn::Equals:
- Ref: AWS::Region
- us-west-1
- Fn::Equals:
- Ref: AWS::Region
- us-west-2
デプロイ
いよいよAWS上にリソースを生成していきます。
以下のコマンドを実行します。
$ cdk deploy --profile [your profile]
// 変更点が表示される
Do you wish to deploy these changes (y/n)? //デプロイする場合は"y"を押してEnter
[your profile]
にはCDKをデプロイしたいAWSのプロファイルを入れます。
そうするとリソースが生成されて、最終的に以下のような表示が出ます。
✅ CdkTestStack
Outputs:
CdkTestStack.cdktestapiEndpointXXXXXXXX = https://YYYYYYYYYY.execute-api.[region name].amazonaws.com/test/
Stack ARN:
arn:aws:cloudformation:[cdk stack's arn]
※XXXや、YYYや[]の中は人それぞれになります。
実行確認
自分のターミナルからApiのエンドポイントにPOSTリクエストをして、DynamoDBのテーブルにリクエストした内容が追加されているか確認します。
$ curl -X POST -d '{"user_id": 333, "amount":1000}' https://XXXXXXXXXX.execute-api.[region name].amazonaws.com/test/
Put Success: {"user_id":333,"amount":1000}
$ aws dynamodb scan --table-name cdk-test-table --profile [your profile]
//DynamoDBの中身を確認
{
"Count": 1,
"Items": [
{
"amount": {
"N": "1000"
},
"user_id": {
"N": "333"
},
"created_at": {
"S": "2020/02/20-20:57:51"
}
}
],
"ScannedCount": 1,
"ConsumedCapacity": null
}
上記のように中身にリクエスト内容が追加されていれば成功です!
削除
生成したリソース群を削除する場合は、以下のコマンドを使用します。
$ cdk destroy --profile [your profile]
Are you sure you want to delete: CdkTestStack (y/n)? //削除する場合は"y"を押してEnter
S3やDynamoDB等このコマンドでは削除されないリソースがあります。こういったリソースは、同じリソース名を指定してデプロイしようとすると、リソース名重複のエラーが出てデプロイできないので注意です。
その他のコマンド:変更の確認
CDKのコードを変更し、生成するリソースの差分をみるときは、以下のコマンドを使います。
$ cdk diff --profile [your profile]
おわりに
CDKの入門的な説明から、ハンズオンの内容までをまとめました。
初めてCDKに触れる方は、CDKで簡単にリソースが生成できることが体感できるかと思います。
便利に使いこなして、素敵なAWSライフを過ごしましょう!
それでは!
参考
https://dev.classmethod.jp/server-side/serverless/aws-cdk-lambda/
https://qiita.com/yhsmt/items/80916a13b3d7ae8adc7f