1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AWS CDK with TypeScrip API Gateway & Lambda (Part1)

Last updated at Posted at 2023-02-09

環境情報

  • 作業環境はAWS Cloud9を利用
  • cdk versionは2.63.2

作成イメージ

AWS CDKを利用してAmazon API Gateway経由でコールできるLambdaサービスのデモを作成していきたいと思います。作成するデモイメージは以下です。
hello-arch.drawio.png
では早速手を動かしていきましょう。

CDK新規プロジェクトの作成

今回の作業環境はAWS Cloud9を利用しています。タイトルにもある通り、今回はTypeScriptでプロジェクトを作成していきます。
まずは今回使用していくプロジェクト用のディレクトリを作成します。

mkdir cdk-workshop && cd cdk-workshop

TypeScriptのCDKプロジェクトを作成します。(ちょっと時間かかります)

cdk init sample-app --language typescript

こんな感じで、便利なcdkコマンドが表示されているかと思います。後にこれらを利用していきます。

## Useful commands

* `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

下図のようなプロジェクトディレクトリが作成されているかと思います。
スクリーンショット 2023-02-07 15.25.59.png
補足しておくと、

  • lib/cdk-workshop-stack.ts: CDKアプリケショーンのメインスタックを定義するファイルです。こちらのファイルをメインに編集していきます。
  • bin/cdk-workshop.ts: CDKアプリケーションのエントリーポイントになります。lib/cdk-workshop-stack.tsで定義されたスタックを読み込みます。
  • cdk.json: toolkitに対してアプリのrunの方法を定義しています。今回の場合はnpx ts-node bin/cdk-workshop.tsのように記述されています。

Lambda関数・API Gatewayの作成

不要コードのクリーンアップと初回のデプロイ

まずは不要である既存のコードをいくつかクリーンアップするところからです。
lib/cdk-workshop-stack.tsを開いて、以下の様にクリーンアップします。SQS QueueやSNS topicは今回のデモでは不要なためです。

lib/cdk-workshop-stack.ts
import * as cdk from 'aws-cdk-lib';

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

    // nothing here!
  }
}

中身は何もありませんが、CDKで記述した中身からAWS CloudFormationのテンプレートを作成していきます(synthesizeする)。CDKを利用した場合も、AWS環境へデプロイする際はCloudFormationテンプレートのカタチでデプロイする、ということです。

cdk synth

CloudFormationテンプレートがcheckoutフォルダに作成されました。

続いて、初回のデプロイ時のみbootstrap stackというスタックをインストールできます。こちらのスタックには、CDK Toolkitで利用されるリソース(例えばCloudFormationテンプレートを保持するS3バケットなど)が含まれています。以下のコマンドです。

cdk bootstrap

それではデプロイしていきます!

cdk deploy

デプロイ成功後のCloudFormationのコンソールを見ると、作成したスタックが存在しているのがわかりますね!(cdk synthで作成したテンプレートが適用されたという意味です。)
スクリーンショット 2023-02-07 16.09.02.png

Hello Lambda関数の作成

Lambda関数のコードを記述していきましょう。以下を実施していきます。

  1. lambdaディレクトリーをbinやlibディレクトリーと同じ階層に作成。
  2. .gitignoreファイルが存在している場合は、ファイル内に!lambda/*.jsを追記。
  3. lambda/hello.jsファイルを作成して、以下のコードを記述します。
lambda/hello.js
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関数をスタックに追加

先ほど作成したlambda関数をスタックに追加します。Lambdaスタックの追加にはLambda用のCDK Libraryも必要なのでimportします。

lib/cdk-workshop-stack.ts
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';

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

    // defines an AWS Lambda resource
    const hello = new lambda.Function(this, 'HelloHandler', {
      runtime: lambda.Runtime.NODEJS_16_X,
      code: lambda.Code.fromAsset('lambda'),
      handler: 'hello.handler'
    });
  }
}

上記コードについて少し補足すると、

  • NodeJS(version16)ランタイムを利用。
  • Lambda関数のhandlerはlambdaディレクトリから読むこまれるように記述。
  • handlerの名前も作成した関数内のhandlerと一致させている。
    のようにしています。

デプロイの前にコードの差分を見てみましょう。差分が確認できると思います。

cdk diff

デプロイ

デプロイします。

cdk deploy

deploy後にコンソールを見てみると、hello.jsのLambda関数ができていることと、S3バケット内にもassetフォルダが作成されていることが分かると思います。

テスト

作成されたLambda関数をテストしてみます。Lambdaのコンソールから"Amazon API Gateway AWS Proxy"テンプレートを使ったテストを作成して実行してみます。
スクリーンショット 2023-02-08 17.50.35.png
良い感じに返ってきました。
スクリーンショット 2023-02-08 17.52.56.png

API Gatewayの作成

次にAPI Gatewayを作成していきます。API Gatewayはインターネット上にパブリックエンドポイントを公開してくれるサービスで、API GatewayとLambdaを繋げることでブラウザなどからリクエストを受け取れるようになります。
以下のように記述します。

lib/cdk-workshop-stack.ts
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigw from 'aws-cdk-lib/aws-apigateway';

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

    // defines an AWS Lambda resource
    const hello = new lambda.Function(this, 'HelloHandler', {
      runtime: lambda.Runtime.NODEJS_16_X,
      code: lambda.Code.fromAsset('lambda'),
      handler: 'hello.handler'
    });
    
    // defines an API Gateway REST API resource backed by "hello" function.
    new apigw.LambdaRestApi(this, 'Endpoint', {
      handler: hello
    });
  }
}

スタックの差分を見てみましょう。

cdk diff

一気に沢山のリソースが作成されちるのがわかりますね。CDKの利便性を感じます。

Resources
[+] AWS::ApiGateway::RestApi Endpoint EndpointEEF1FD8F 
[+] 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 

デプロイします。

cdk deploy

Outputとして以下の様なURLエンドポイントが表示されると思います。

Outputs:
CdkWorkshopStack.Endpoint8024A810 = https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/

crulコマンドでこのエンドポイントを叩いてあげれば、Lambda関数からレスポンスが返ってくるのがわかりますね!ブラウザからも試してみてください。

$ curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/
Hello, CDK! You've hit /

まとめ

今回はCDKを用いて簡単なバックエンドアプリをAPI Gateway + Lambdaの構成で作成してみました。
コンソールでポチポチ構成する場合やCloudFormationを記述する場合と比べて、時間的にはかなり短縮して作成完了ができるような感覚ではなかったでしょうか。今後もCDKシリーズを公開していきたいと思います。

Part2として、Hello Lambdaにヒットした回数をカウントするHit Counter LambdaとDynamoDBをCDKで作成した内容をこちらに記載しています。

最後に、今回作成したアプリを削除したい場合は以下のコマンドで綺麗サッパリクリーンアップされます。

cdk destroy

参考サイト

以上。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?