【ハンズオン】コードでAWS環境を管理しよう! AWS CDKハンズオン #AWSSummit
今回は、コードでAWS環境を管理しよう! AWS CDKハンズオンに参加したのでレポートします。
セッション概要
スピーカー
内田 大樹 氏
アマゾン ウェブサービス ジャパン インダストリソリューション部
ソリューションアーキテクト
セッション
HOL-10:コードでAWS環境を管理しよう! AWS CDKハンズオン
1時間程度の動画ですが丁寧に説明がされているため、CloudFormationやCDKを利用したことがない方でも問題なく進められると思います。
目的
AWS CDK (TypeScript)を利用したAWS環境の構築方法を学ぶ
ハンズオンの大まかな流れ
本ハンズオンは、適宜詳細な解説を交えながら以下の流れで進行していきます。
- ハンズオンで利用するサービス紹介
- 環境構築
- SNS + SQS
- まずはリソースだけでAWS CDKの記載方法、デプロイ方法を学ぶ
- Lambda
- ソースコードの解説およびAWS CDKの記載方法、デプロイを学ぶ
- Lambdaの動作確認
- API Gateway + Lambda
- AWS CDKの記載方法を学ぶ
- 完成したAPIの動作確認
最終的な目標は、AWS CDKを用いてAPI Gateway + LambdaのAPIを構築し動作を確認することです。
前提条件
下記がインストールされていることが前提条件となります。
本記事では、インストール方法については割愛させていただきます。
- Node.js > 10.3
- AWS CLI
ハンズオンで利用するサービス紹介
今回のハンズオンで利用する主要なサービスの簡単な解説が行われます。 SNSとSQSについては、AWS CDKによる記載方法、デプロイ方法を学ぶ際にでてきますがハンズオンの目的とは異なるため割愛されているようです。
AWS CDKについて
AWS CDKの概要説明、およびCDKアプリケーションの構成に関する説明です。 App, Stack, Constructの概念はAWS CDKを利用する上で重要となるので頭に入れておきましょう。
環境構築
ここから実際に手を動かしながら学んでいきます。まずは、AWS CDKのインストールからです。
$ sudo npm install -g aws-cdk /usr/local/bin/cdk -> /usr/local/lib/node_modules/aws-cdk/bin/cdk + aws-cdk@1.62.0 added 216 packages from 187 contributors in 7.762s
AWS CDKがインストールできたらcdk-workshop
という空のディレクトリを作成しそこで初期コードを生成します。
$ cdk init app --language typescript Applying project template app for typescript # 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 Executing npm install... npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142 npm WARN deprecated request-promise-native@1.0.9: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 npm WARN deprecated har-validator@5.1.5: this library is no longer supported npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^2.1.2 (node_modules/jest-haste-map/node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) npm WARN cdk-workshop@0.1.0 No repository field. npm WARN cdk-workshop@0.1.0 No license field. ✅ All done!
これでAWS CDKに必要なファイルが配置され環境構築は完了になります。
SNS + SQS
必要となるConstructライブラリ(各サービスに対応したライブラリ)をインストールします。 (ハンズオン手順としてはでてきませんが、自動インストールされなかったため手動でインストールしました)
$ npm install @aws-cdk/aws-sns @aws-cdk/aws-sns @aws-cdk/aws-sns-subscriptions npm WARN cdk-workshop@0.1.0 No repository field. npm WARN cdk-workshop@0.1.0 No license field. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) + @aws-cdk/aws-sns@1.62.0 + @aws-cdk/aws-sns@1.62.0 + @aws-cdk/aws-sns-subscriptions@1.62.0 added 12 packages from 1 contributor, updated 1 package and audited 990 packages in 11.333s 24 packages are looking for funding run `npm fund` for details found 0 vulnerabilities
AWS CDKが生成したコードに、SNSとSQSの定義を追加します。
import * as sns from '@aws-cdk/aws-sns'; import * as subs from '@aws-cdk/aws-sns-subscriptions'; import * as sqs from '@aws-cdk/aws-sqs'; import * as cdk from '@aws-cdk/core'; export class CdkWorkshopStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); const queue = new sqs.Queue(this, 'CdkWorkshopQueue', { visibilityTimeout: cdk.Duration.seconds(300) }); const topic = new sns.Topic(this, 'CdkWorkshopTopic'); topic.addSubscription(new subs.SqsSubscription(queue)); } }
リソースの定義が記載できたので、デプロイの際にAWS CDKによって生成されるCloudFormationテンプレートを確認します。
$ cdk synth Resources: CdkWorkshopQueue50D9D426: Type: AWS::SQS::Queue Properties: VisibilityTimeout: 300 Metadata: aws:cdk:path: CdkWorkshopStack/CdkWorkshopQueue/Resource CdkWorkshopQueuePolicyAF2494A5: Type: AWS::SQS::QueuePolicy Properties: PolicyDocument: Statement: - Action: sqs:SendMessage Condition: ArnEquals: aws:SourceArn: Ref: CdkWorkshopTopicD368A42F Effect: Allow Principal: Service: sns.amazonaws.com Resource: Fn::GetAtt: - CdkWorkshopQueue50D9D426 - Arn Version: "2012-10-17" Queues: - Ref: CdkWorkshopQueue50D9D426 Metadata: aws:cdk:path: CdkWorkshopStack/CdkWorkshopQueue/Policy/Resource CdkWorkshopQueueCdkWorkshopStackCdkWorkshopTopicD7BE96438B5AD106: Type: AWS::SNS::Subscription Properties: Protocol: sqs TopicArn: Ref: CdkWorkshopTopicD368A42F Endpoint: Fn::GetAtt: - CdkWorkshopQueue50D9D426 - Arn Metadata: aws:cdk:path: CdkWorkshopStack/CdkWorkshopQueue/CdkWorkshopStackCdkWorkshopTopicD7BE9643/Resource CdkWorkshopTopicD368A42F: Type: AWS::SNS::Topic Metadata: aws:cdk:path: CdkWorkshopStack/CdkWorkshopTopic/Resource CDKMetadata: Type: AWS::CDK::Metadata Properties: Modules: aws-cdk=1.62.0,@aws-cdk/aws-cloudwatch=1.62.0,@aws-cdk/aws-iam=1.62.0,@aws-cdk/aws-kms=1.62.0,@aws-cdk/aws-sns=1.62.0,@aws-cdk/aws-sns-subscriptions=1.62.0,@aws-cdk/aws-sqs=1.62.0,@aws-cdk/cloud-assembly-schema=1.62.0,@aws-cdk/core=1.62.0,@aws-cdk/cx-api=1.62.0,@aws-cdk/region-info=1.62.0,jsii-runtime=node.js/v10.19.0 Condition: CDKMetadataAvailable 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デプロイ管理用の環境(S3バケット)を作成します。このコマンドは初回のみ実行する必要があります。
$ cdk bootstrap ⏳ Bootstrapping environment aws://10000000000/ap-northeast-1... CDKToolkit: creating CloudFormation changeset... [██████████████████████████████████████████████████████████] (2/2) ✅ Environment aws://10000000000/ap-northeast-1 bootstrapped.
デプロイを行います。
$ cdk deploy This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening). Please confirm you intend to make the following modifications: IAM Statement Changes ┌───┬─────────────────────────┬────────┬─────────────────┬───────────────────────────┬─────────────────────────────────────────────────────────┐ │ │ Resource │ Effect │ Action │ Principal │ Condition │ ├───┼─────────────────────────┼────────┼─────────────────┼───────────────────────────┼─────────────────────────────────────────────────────────┤ │ + │ ${CdkWorkshopQueue.Arn} │ Allow │ sqs:SendMessage │ Service:sns.amazonaws.com │ "ArnEquals": { │ │ │ │ │ │ │ "aws:SourceArn": "${CdkWorkshopTopic}" │ │ │ │ │ │ │ } │ └───┴─────────────────────────┴────────┴─────────────────┴───────────────────────────┴─────────────────────────────────────────────────────────┘ (NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) Do you wish to deploy these changes (y/n)? y CdkWorkshopStack: deploying... CdkWorkshopStack: creating CloudFormation changeset... [██████████████████████████████████████████████████████████] (6/6) ✅ CdkWorkshopStack Stack ARN: arn:aws:cloudformation:ap-northeast-1:1000000000:stack/CdkWorkshopStack/60ca4330-f656-11ea-ad13-0aa2cd508fc6
AWSコンソールから、CloudFormationのスタックを表示し各リソースが実際にデプロイされていることを確認しました。
AWS CDKのコードを変更してデプロイする方法について学べたので、SNSとSQSについてはコードから削除します。
import * as cdk from '@aws-cdk/core'; export class CdkWorkshopStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); } }
削除したもののdiffを確認してみましょう。
$ cdk diff Stack CdkWorkshopStack IAM Statement Changes ┌───┬────────────────────────────────────────┬────────┬─────────────────┬────────────────────────────────────────┬──────────────────────────────────────────┐ │ │ Resource │ Effect │ Action │ Principal │ Condition │ ├───┼────────────────────────────────────────┼────────┼─────────────────┼────────────────────────────────────────┼──────────────────────────────────────────┤ │ - │ ${CdkWorkshopQueue50D9D426.Arn} │ Allow │ sqs:SendMessage │ Service:sns.amazonaws.com │ "ArnEquals": { │ │ │ │ │ │ │ "aws:SourceArn": "${CdkWorkshopTopicD3 │ │ │ │ │ │ │ 68A42F}" │ │ │ │ │ │ │ } │ └───┴────────────────────────────────────────┴────────┴─────────────────┴────────────────────────────────────────┴──────────────────────────────────────────┘ (NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) Resources [-] AWS::SQS::Queue CdkWorkshopQueue50D9D426 destroy [-] AWS::SQS::QueuePolicy CdkWorkshopQueuePolicyAF2494A5 destroy [-] AWS::SNS::Subscription CdkWorkshopQueueCdkWorkshopStackCdkWorkshopTopicD7BE96438B5AD106 destroy [-] AWS::SNS::Topic CdkWorkshopTopicD368A42F destroy
先ほど追加されたリソース群が削除されることが確認できたので、デプロイして不要なリソースを削除します。
$ cdk deploy CdkWorkshopStack: deploying... CdkWorkshopStack: creating CloudFormation changeset... [██████████████████████████████████████████████████████████] (6/6) ✅ CdkWorkshopStack Stack ARN: arn:aws:cloudformation:ap-northeast-1:10000000000:stack/CdkWorkshopStack/60ca4330-f656-11ea-ad13-0aa2cd508fc6
Lambda
ハンズオンの本題であるLambdaの作成に入ります。 まずはConstructライブラリのインストールを行います。
$ npm install @aws-cdk/aws-lambda npm WARN cdk-workshop@0.1.0 No repository field. npm WARN cdk-workshop@0.1.0 No license field. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) + @aws-cdk/aws-lambda@1.62.0 updated 1 package and audited 991 packages in 7.85s 24 packages are looking for funding run `npm fund` for details found 0 vulnerabilities
次に、Lambdaのソースをlambdaというディレクトリを作成し新規作成します。
処理としては、API Gatewayから渡されるイベント情報からアクセスパスを返却する簡単なものとなっています。
exports.handler = async function (event) { console.log('request:', JSON.stringify(event, undefined, 2)); return { statusCode: 200, headers: { 'Content-Type': 'text/plain' }, body: `Hello, CDK! You've hit ${event.path}\n` }; };
Lambdaのソースが完成したので、AWS CDKの管理対象としてLambdaを定義します。
ポイントとしては、Assetの指定にディレクトリ名、handlerの指定にファイル名とexportしている関数名を結合したもの指定します。もし変更していた場合は間違えないようにしてください。
import * as cdk from '@aws-cdk/core'; import * as lambda from '@aws-cdk/aws-lambda'; export class CdkWorkshopStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); const hello = new lambda.Function(this, 'HelloHandler', { runtime: lambda.Runtime.NODEJS_10_X, code: lambda.Code.fromAsset('lambda'), handler: 'hello.handler' }) } }
LambdaのソースコードとAWS CDKの記載が完了したので、diffを確認します。
$ cdk diff Stack CdkWorkshopStack IAM Statement Changes ┌───┬─────────────────────────────────┬────────┬────────────────┬──────────────────────────────┬───────────┐ │ │ Resource │ Effect │ Action │ Principal │ Condition │ ├───┼─────────────────────────────────┼────────┼────────────────┼──────────────────────────────┼───────────┤ │ + │ ${HelloHandler/ServiceRole.Arn} │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws.com │ │ └───┴─────────────────────────────────┴────────┴────────────────┴──────────────────────────────┴───────────┘ IAM Policy Changes ┌───┬─────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐ │ │ Resource │ Managed Policy ARN │ ├───┼─────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ + │ ${HelloHandler/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │ └───┴─────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘ (NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) Parameters [+] Parameter AssetParameters/f0156e9e857a3c790844d347ec128e4d95577dd58e2a11f152756874830b47f8/S3Bucket AssetParametersf0156e9e857a3c790844d347ec128e4d95577dd58e2a11f152756874830b47f8S3Bucket0DFBA133: {"Type":"String","Description":"S3 bucket for asset \"f0156e9e857a3c790844d347ec128e4d95577dd58e2a11f152756874830b47f8\""} [+] Parameter AssetParameters/f0156e9e857a3c790844d347ec128e4d95577dd58e2a11f152756874830b47f8/S3VersionKey AssetParametersf0156e9e857a3c790844d347ec128e4d95577dd58e2a11f152756874830b47f8S3VersionKey2DB6E077: {"Type":"String","Description":"S3 key for asset version \"f0156e9e857a3c790844d347ec128e4d95577dd58e2a11f152756874830b47f8\""} [+] Parameter AssetParameters/f0156e9e857a3c790844d347ec128e4d95577dd58e2a11f152756874830b47f8/ArtifactHash AssetParametersf0156e9e857a3c790844d347ec128e4d95577dd58e2a11f152756874830b47f8ArtifactHash7BD937C8: {"Type":"String","Description":"Artifact hash for asset \"f0156e9e857a3c790844d347ec128e4d95577dd58e2a11f152756874830b47f8\""} Resources [+] AWS::IAM::Role HelloHandler/ServiceRole HelloHandlerServiceRole11EF7C63 [+] AWS::Lambda::Function HelloHandler HelloHandler2E4FBA4D
問題なさそうなので、デプロイを行います。
$ cdk deploy This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening). Please confirm you intend to make the following modifications: IAM Statement Changes ┌───┬─────────────────────────────────┬────────┬────────────────┬──────────────────────────────┬───────────┐ │ │ Resource │ Effect │ Action │ Principal │ Condition │ ├───┼─────────────────────────────────┼────────┼────────────────┼──────────────────────────────┼───────────┤ │ + │ ${HelloHandler/ServiceRole.Arn} │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws.com │ │ └───┴─────────────────────────────────┴────────┴────────────────┴──────────────────────────────┴───────────┘ IAM Policy Changes ┌───┬─────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐ │ │ Resource │ Managed Policy ARN │ ├───┼─────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ + │ ${HelloHandler/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │ └───┴─────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘ (NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) Do you wish to deploy these changes (y/n)? y CdkWorkshopStack: deploying... [0%] start: Publishing f0156e9e857a3c790844d347ec128e4d95577dd58e2a11f152756874830b47f8:current [100%] success: Published f0156e9e857a3c790844d347ec128e4d95577dd58e2a11f152756874830b47f8:current CdkWorkshopStack: creating CloudFormation changeset... [██████████████████████████████████████████████████████████] (4/4) ✅ CdkWorkshopStack Stack ARN: arn:aws:cloudformation:ap-northeast-1:10000000000:stack/CdkWorkshopStack/60ca4330-f656-11ea-ad13-0aa2cd508fc6
デプロイが行えたのでAWSコンソール上で動作確認を行います。
デプロイされたLambdaを確認します。
テスト用イベントとしてイベントテンプレートから、apigateway-aws-proxy
を選択しイベントを作成します。
実際にテストを実行して、先ほど作成したテストイベント内容である、/path/to/resouce
が返却されていることを確認します。
API Gateway + Lambda
Lambdaのデプロイ、動作確認が行えたのでAPI Gatewayを追加しAPI Gateway経由でLambdaが起動できるようにします。
まずは、Constructライブラリをインストールします。
$ npm install @aws-cdk/aws-apigateway npm WARN cdk-workshop@0.1.0 No repository field. npm WARN cdk-workshop@0.1.0 No license field. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) + @aws-cdk/aws-apigateway@1.62.0 added 4 packages from 1 contributor and audited 994 packages in 5.543s 24 packages are looking for funding run `npm fund` for details found 0 vulnerabilities
次にAWS CDKの管理対象としてAPI Gatewayを定義します。
API Gatewayのhandlerに直前で定義したLambda(hello)を渡しています。
import * as cdk from '@aws-cdk/core'; import * as lambda from '@aws-cdk/aws-lambda'; import * as apigw from '@aws-cdk/aws-apigateway'; export class CdkWorkshopStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); const hello = new lambda.Function(this, 'HelloHandler', { runtime: lambda.Runtime.NODEJS_10_X, code: lambda.Code.fromAsset('lambda'), handler: 'hello.handler' }) new apigw.LambdaRestApi(this, 'Endpoint', { handler: hello }); } }
AWS CDKの記載が完了したので、diffを確認します。
$ cdk diff Stack CdkWorkshopStack IAM Statement Changes ┌───┬──────────────────────────────────────┬────────┬───────────────────────┬──────────────────────────────────────┬────────────────────────────────────────┐ │ │ Resource │ Effect │ Action │ Principal │ Condition │ ├───┼──────────────────────────────────────┼────────┼───────────────────────┼──────────────────────────────────────┼────────────────────────────────────────┤ │ + │ ${Endpoint/CloudWatchRole.Arn} │ Allow │ sts:AssumeRole │ Service:apigateway.amazonaws.com │ │ ├───┼──────────────────────────────────────┼────────┼───────────────────────┼──────────────────────────────────────┼────────────────────────────────────────┤ │ + │ ${HelloHandler.Arn} │ Allow │ lambda:InvokeFunction │ Service:apigateway.amazonaws.com │ "ArnLike": { │ │ │ │ │ │ │ "AWS:SourceArn": "arn:${AWS::Partiti │ │ │ │ │ │ │ on}:execute-api:${AWS::Region}:${AWS:: │ │ │ │ │ │ │ AccountId}:${EndpointEEF1FD8F}/${Endpo │ │ │ │ │ │ │ int/DeploymentStage.prod}/*/*" │ │ │ │ │ │ │ } │ │ + │ ${HelloHandler.Arn} │ Allow │ lambda:InvokeFunction │ Service:apigateway.amazonaws.com │ "ArnLike": { │ │ │ │ │ │ │ "AWS:SourceArn": "arn:${AWS::Partiti │ │ │ │ │ │ │ on}:execute-api:${AWS::Region}:${AWS:: │ │ │ │ │ │ │ AccountId}:${EndpointEEF1FD8F}/test-in │ │ │ │ │ │ │ voke-stage/*/*" │ │ │ │ │ │ │ } │ │ + │ ${HelloHandler.Arn} │ Allow │ lambda:InvokeFunction │ Service:apigateway.amazonaws.com │ "ArnLike": { │ │ │ │ │ │ │ "AWS:SourceArn": "arn:${AWS::Partiti │ │ │ │ │ │ │ on}:execute-api:${AWS::Region}:${AWS:: │ │ │ │ │ │ │ AccountId}:${EndpointEEF1FD8F}/${Endpo │ │ │ │ │ │ │ int/DeploymentStage.prod}/*/" │ │ │ │ │ │ │ } │ │ + │ ${HelloHandler.Arn} │ Allow │ lambda:InvokeFunction │ Service:apigateway.amazonaws.com │ "ArnLike": { │ │ │ │ │ │ │ "AWS:SourceArn": "arn:${AWS::Partiti │ │ │ │ │ │ │ on}:execute-api:${AWS::Region}:${AWS:: │ │ │ │ │ │ │ AccountId}:${EndpointEEF1FD8F}/test-in │ │ │ │ │ │ │ voke-stage/*/" │ │ │ │ │ │ │ } │ └───┴──────────────────────────────────────┴────────┴───────────────────────┴──────────────────────────────────────┴────────────────────────────────────────┘ IAM Policy Changes ┌───┬────────────────────────────┬─────────────────────────────────────────────────────────────────────────────────────────┐ │ │ Resource │ Managed Policy ARN │ ├───┼────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤ │ + │ ${Endpoint/CloudWatchRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs │ └───┴────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────────────┘ (NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) Resources [+] AWS::ApiGateway::RestApi Endpoint EndpointEEF1FD8F [+] AWS::IAM::Role Endpoint/CloudWatchRole EndpointCloudWatchRoleC3C64E0F [+] AWS::ApiGateway::Account Endpoint/Account EndpointAccountB8304247 [+] AWS::ApiGateway::Deployment Endpoint/Deployment EndpointDeployment318525DA5f8cdfe532107839d82cbce31f859259 [+] AWS::ApiGateway::Stage Endpoint/DeploymentStage.prod EndpointDeploymentStageprodB78BEEA0 [+] AWS::ApiGateway::Resource Endpoint/Default/{proxy+} Endpointproxy39E2174E [+] AWS::Lambda::Permission Endpoint/Default/{proxy+}/ANY/ApiPermission.CdkWorkshopStackEndpoint018E8349.ANY..{proxy+} EndpointproxyANYApiPermissionCdkWorkshopStackEndpoint018E8349ANYproxy747DCA52 [+] AWS::Lambda::Permission Endpoint/Default/{proxy+}/ANY/ApiPermission.Test.CdkWorkshopStackEndpoint018E8349.ANY..{proxy+} EndpointproxyANYApiPermissionTestCdkWorkshopStackEndpoint018E8349ANYproxy41939001 [+] AWS::ApiGateway::Method Endpoint/Default/{proxy+}/ANY EndpointproxyANYC09721C5 [+] AWS::Lambda::Permission Endpoint/Default/ANY/ApiPermission.CdkWorkshopStackEndpoint018E8349.ANY.. EndpointANYApiPermissionCdkWorkshopStackEndpoint018E8349ANYE84BEB04 [+] AWS::Lambda::Permission Endpoint/Default/ANY/ApiPermission.Test.CdkWorkshopStackEndpoint018E8349.ANY.. EndpointANYApiPermissionTestCdkWorkshopStackEndpoint018E8349ANYB6CC1B64 [+] AWS::ApiGateway::Method Endpoint/Default/ANY EndpointANY485C938B Outputs [+] Output Endpoint/Endpoint Endpoint8024A810: {"Value":{"Fn::Join":["",["https://",{"Ref":"EndpointEEF1FD8F"},".execute-api.",{"Ref":"AWS::Region"},".",{"Ref":"AWS::URLSuffix"},"/",{"Ref":"EndpointDeploymentStageprodB78BEEA0"},"/"]]}}
問題なくAPI Gateway関連のリソースが追加されているため、デプロイします。
$ cdk deploy This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening). Please confirm you intend to make the following modifications: IAM Statement Changes ┌───┬──────────────────────────────────────┬────────┬───────────────────────┬──────────────────────────────────────┬────────────────────────────────────────┐ │ │ Resource │ Effect │ Action │ Principal │ Condition │ ├───┼──────────────────────────────────────┼────────┼───────────────────────┼──────────────────────────────────────┼────────────────────────────────────────┤ │ + │ ${Endpoint/CloudWatchRole.Arn} │ Allow │ sts:AssumeRole │ Service:apigateway.amazonaws.com │ │ ├───┼──────────────────────────────────────┼────────┼───────────────────────┼──────────────────────────────────────┼────────────────────────────────────────┤ │ + │ ${HelloHandler.Arn} │ Allow │ lambda:InvokeFunction │ Service:apigateway.amazonaws.com │ "ArnLike": { │ │ │ │ │ │ │ "AWS:SourceArn": "arn:${AWS::Partiti │ │ │ │ │ │ │ on}:execute-api:${AWS::Region}:${AWS:: │ │ │ │ │ │ │ AccountId}:${EndpointEEF1FD8F}/${Endpo │ │ │ │ │ │ │ int/DeploymentStage.prod}/*/*" │ │ │ │ │ │ │ } │ │ + │ ${HelloHandler.Arn} │ Allow │ lambda:InvokeFunction │ Service:apigateway.amazonaws.com │ "ArnLike": { │ │ │ │ │ │ │ "AWS:SourceArn": "arn:${AWS::Partiti │ │ │ │ │ │ │ on}:execute-api:${AWS::Region}:${AWS:: │ │ │ │ │ │ │ AccountId}:${EndpointEEF1FD8F}/test-in │ │ │ │ │ │ │ voke-stage/*/*" │ │ │ │ │ │ │ } │ │ + │ ${HelloHandler.Arn} │ Allow │ lambda:InvokeFunction │ Service:apigateway.amazonaws.com │ "ArnLike": { │ │ │ │ │ │ │ "AWS:SourceArn": "arn:${AWS::Partiti │ │ │ │ │ │ │ on}:execute-api:${AWS::Region}:${AWS:: │ │ │ │ │ │ │ AccountId}:${EndpointEEF1FD8F}/${Endpo │ │ │ │ │ │ │ int/DeploymentStage.prod}/*/" │ │ │ │ │ │ │ } │ │ + │ ${HelloHandler.Arn} │ Allow │ lambda:InvokeFunction │ Service:apigateway.amazonaws.com │ "ArnLike": { │ │ │ │ │ │ │ "AWS:SourceArn": "arn:${AWS::Partiti │ │ │ │ │ │ │ on}:execute-api:${AWS::Region}:${AWS:: │ │ │ │ │ │ │ AccountId}:${EndpointEEF1FD8F}/test-in │ │ │ │ │ │ │ voke-stage/*/" │ │ │ │ │ │ │ } │ └───┴──────────────────────────────────────┴────────┴───────────────────────┴──────────────────────────────────────┴────────────────────────────────────────┘ IAM Policy Changes ┌───┬────────────────────────────┬─────────────────────────────────────────────────────────────────────────────────────────┐ │ │ Resource │ Managed Policy ARN │ ├───┼────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤ │ + │ ${Endpoint/CloudWatchRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs │ └───┴────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────────────┘ (NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) Do you wish to deploy these changes (y/n)? y CdkWorkshopStack: deploying... [0%] start: Publishing f0156e9e857a3c790844d347ec128e4d95577dd58e2a11f152756874830b47f8:current [100%] success: Published f0156e9e857a3c790844d347ec128e4d95577dd58e2a11f152756874830b47f8:current CdkWorkshopStack: creating CloudFormation changeset... [██████████████████████████████████████████████████████████] (14/14) ✅ CdkWorkshopStack Outputs: CdkWorkshopStack.Endpoint8024A810 = https://w4z0werc3i.execute-api.ap-northeast-1.amazonaws.com/prod/ Stack ARN: arn:aws:cloudformation:ap-northeast-1:10000000000:stack/CdkWorkshopStack/60ca4330-f656-11ea-ad13-0aa2cd508fc6
コンソール出力の最後に、API Gatewayのエンドポイントが表示されているので動作確認を行います。
まずはcurlでアクセスします。
$ curl https://w4z0werc3i.execute-api.ap-northeast-1.amazonaws.com/prod/ Hello, CDK! You've hit /
次にブラウザでアクセスします。
ちゃんと動作していますね。
最後に、AWS CDKで作成したリソース群を削除します。
手順書には、もっと学びたい人のために追加の手順等が記載されているので学習を続ける方はリソースの削除をせずにハンズオンを進めてください。
$ cdk destroy Are you sure you want to delete: CdkWorkshopStack (y/n)? y CdkWorkshopStack: destroying... 3:52:32 PM | DELETE_IN_PROGRESS | AWS::IAM::Role | HelloHandler/ServiceRole ✅ CdkWorkshopStack: destroyed ************************************************** *** Newer version of CDK is available [1.63.0] *** *** Upgrade recommended *** **************************************************
まとめ
今回のハンズオンで、AWS CDKの下記3点について経験することができました。
- 環境構築
- リソースの定義方法(Lambda, API Gateway)
- デプロイやdiffの確認方法
最後に
今回初めてAWS CDKを利用してみました。CloudFormationテンプレートよりも抽象化されていることで記述量が減ること、型があるためIDEの支援を受けられることは大きな魅力に感じました!
以上なります。ハンズオンの動画や資料はとても丁寧でわかりやすいので、みなさんもぜひやってみてください。