AWS CDKでAPIGateway+Lambdaを作る


cdkの入門として、シンプルにAPIGateway+Lambdaを作っていく流れを書きます

はじめに

  • Ubuntu 18.04.4 LTS (WSL利用)
  • VSCode
  • aws-cdk 1.94.1
  • typescript

AWS CDKをインストール

$ npm install -g aws-cdk
$ cdk --version

AWS CDKのプロジェクト作成

# プロジェクトディレクトリを作成
$ mkdir cdk-api-lambda

# 移動
$ cd cdk-api-lambda/

# プロジェクト作成
$ cdk init app --language=typescript

パッケージインストール

$ npm install @aws-cdk/aws-lambda @aws-cdk/aws-apigateway

lambdaコードを格納するフォルダを作成

$ mkdir lib/lambda/

lambdaコードをアップロードするS3バケットを準備する

これを実施しないと This stack uses assets, so the toolkit stack must be deployed to the environment のエラーが発生することがあります

$ cdk bootstrap --profile xxx
 ⏳  Bootstrapping environment aws://XXXXXXXXXXX/ap-northeast-1...
CDKToolkit: creating CloudFormation changeset...
[██████████████████████████████████████████████████████████] (3/3)

 ✅  Environment aws://XXXXXXXXXXX/ap-northeast-1 bootstrapped.

Lambdaの実装コードを書く

echoという名前でパラメータで受けたメッセージを単純に返却する形で作ります

/lib/lambda/echo.ts
export const handler = async (event: any = {}): Promise<any> => {
  return { statusCode: 200, body: event.queryStringParameters.msg};
};

APIGatewayとLambdaを作るコードを作ります

CdkLambdaStackとCdkApiStackという2つのスタックに分けようと思いますのでファイルを分けます

# 初期に作成されたcdkapi-lambda-stack.tsを、lambdaのスタックにして
$ mv lib/cdkapi-lambda-stack.ts lib/cdk-lambda-stack.ts

# APIGatewayのスタックは新規に作ります
$ touch lib/cdk-api-stack.ts
/lib/cdk-lambda-stack.ts
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';

export class CdkLambdaStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const region = cdk.Stack.of(this).region;
    new lambda.Function(
      this,
      'echo',
      {
        code: lambda.Code.fromAsset('lib/lambda'),
        environment: {
          REGION: region,
          TZ: 'Asia/Tokyo',
        },
        functionName: 'echo',
        handler: 'echo.handler',
        runtime: lambda.Runtime.NODEJS_12_X,
        tracing: lambda.Tracing.ACTIVE,
        timeout: cdk.Duration.seconds(10),
      },
    );
  }
}
/lib/cdk-api-stack.ts
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as apigateway from '@aws-cdk/aws-apigateway';

export class CdkApiStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const accountId = cdk.Stack.of(this).account;
    const region = cdk.Stack.of(this).region;
    const echoFunction = lambda.Function.fromFunctionArn(
      this,
      'echo',
      `arn:aws:lambda:${region}:${accountId}:function:echo`,
    );

    const restApi = new apigateway.RestApi(this, 'RestApi', {
      restApiName: `echo-api`,
      deployOptions: {
        stageName: 'v1',
      },
    });

    const userResource = restApi.root.addResource('echo');
    userResource.addMethod(
      'GET',
      new apigateway.LambdaIntegration(echoFunction),
    );

    new lambda.CfnPermission(this, `${echoFunction}-Permission`, {
      principal: 'apigateway.amazonaws.com',
      action: 'lambda:InvokeFunction',
      functionName: echoFunction.functionName,
      sourceArn: restApi.arnForExecuteApi(
        'GET',
        '/echo',
        '*',
      ),
    });
  }
}

/bin/cdk-api-lambda.ts
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from '@aws-cdk/core';
import { CdkLambdaStack } from '../lib/cdk-lambda-stack';
import { CdkApiStack } from '../lib/cdk-api-stack';

const app = new cdk.App();
new CdkLambdaStack(app, 'CdkLambdaStack');
new CdkApiStack(app, 'CdkApiStack');

デプロイの確認

作成したコードをビルドチェック

$ npm run build

AWSにデプロイ

作成したコードをAWSにデプロイします

# $ cdk deploy --all --profile myself
$ cdk deploy CdkLambdaStack --profile myself
$ cdk deploy CdkApiStack --profile myself
CdkApiStack: deploying...
CdkApiStack: creating CloudFormation changeset...
[██████████████████████████████████████████████████████████] (10/10)

 ✅  CdkApiStack

Outputs:
CdkApiStack.RestApiEndpointXXXXXXX = https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxxx:stack/CdkApiStack/xxxxxxxxxxxxxxxxxxxxxxx

CloudFormationで確認

スタックが正常に完了しています

APIGatewayで確認

作成されています

APIを呼び出して確認

$ curl https://xxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/echo?msg=hoge
hoge

応答もOKです

AWSから削除

デプロイしたものを削除します

$ cdk destroy CdkApiStack --profile xxx
$ cdk destroy CdkLambdaStack --profile xxx
# $ cdk destroy --all --profile xxx