AWS CDK を使用した Lambda 関数のデプロイ - AWS Lambda

AWS CDK を使用した Lambda 関数のデプロイ

AWS Cloud Development Kit (AWS CDK) は、選択したプログラミング言語を使用して、AWS クラウドインフラストラクチャの定義に使用できる、Infrastructure as Code (IaC) フレームワークです。独自のクラウドインフラストラクチャを定義するには、最初に、(CDK でサポートされている言語のいずれかで) 1 つ以上のスタックが含まれるアプリケーションを記述します。次に、それを AWS CloudFormation テンプレートに合成して、AWS アカウント にリソースをデプロイします。このトピックの手順に従って、Amazon API Gateway エンドポイントからイベントを返す Lambda 関数をデプロイします。

CDK に含まれる AWS 構成ライブラリは、AWS のサービス が提供するリソースのモデル化に使用できるモジュールを提供します。一般的なサービスでは、ライブラリが、スマートなデフォルトとベストプラクティスを持つ厳選された構成を提供します。aws_lambda モジュールを使用して、数行のコードで関数とサポートリソースを定義できます。

前提条件

このチュートリアルを開始する前に、次のコマンドを実行して AWS CDK をインストールします。

npm install -g aws-cdk

ステップ 1:AWS CDK プロジェクトを設定する

新しいAWS CDKアプリケーションのディレクトリを作成し、プロジェクトを初期化します。

JavaScript
mkdir hello-lambda cd hello-lambda cdk init --language javascript
TypeScript
mkdir hello-lambda cd hello-lambda cdk init --language typescript
Python
mkdir hello-lambda cd hello-lambda cdk init --language python

プロジェクトが開始されたら、プロジェクトの仮想環境をアクティブにし、AWS CDK のベースラインの依存関係をインストールします。

source .venv/bin/activate python -m pip install -r requirements.txt
Java
mkdir hello-lambda cd hello-lambda cdk init --language java

この Maven プロジェクトを Java 統合開発環境 (IDE) にインポートします。例えば Eclipse では、[ファイル][インポート][Maven][既存の Maven プロジェクト] を選択します。

C#
mkdir hello-lambda cd hello-lambda cdk init --language csharp
注記

AWS CDKアプリケーションテンプレートは、プロジェクトディレクトリの名前を使用し、ソースファイルとクラスの名前を生成します。この例では、ディレクトリ名は hello-lambda です。別のプロジェクトディレクトリ名を使用する場合、アプリケーションはこれらの指示と一致しません。

AWS CDK v2 は、aws-cdk-lib と呼ばれる単一パッケージですべての AWS のサービス の安定した構成を含んでいます。このパッケージは、プロジェクト開始時に依存関係としてインストールされます。特定のプログラミング言語で作業する場合、パッケージはプロジェクトを初めて構築するときにインストールされます。

ステップ 2: AWS CDK スタックを定義する

CDK スタックは、AWS リソースを定義する 1 つ以上のコンストラクトのコレクションです。各 CDK スタックは、CDK アプリ内の AWS CloudFormation スタックを表します。

CDK を定義するには、希望するプログラミング言語の手順に従います。このスタックでは、以下を定義します。

  • 関数の論理名: MyFunction

  • code プロパティで指定された関数コードの場所。詳細については、「AWS Cloud Development Kit (AWS CDK) API リファレンス」の「Handler code」を参照してください。

  • REST API の論理名: HelloApi

  • API Gateway エンドポイントの論理名: ApiGwEndpoint

このチュートリアルのすべての CDK スタックは、Lambda 関数に Node.js ランタイムを使用することに注意してください。CDK スタックと Lambda 関数に異なるプログラミング言語を使用して、各言語の長所を活用できます。例えば、CDK スタックに TypeScript を使用して、インフラストラクチャコードの静的型付けの利点を活用できます。Lambda 関数に JavaScript を使用すると、動的に型付けされた言語の柔軟性と迅速な開発を活用できます。

JavaScript

lib/hello-lambda-stack.js ファイルを開き、内容を次に置き換えます。

const { Stack } = require('aws-cdk-lib'); const lambda = require('aws-cdk-lib/aws-lambda'); const apigw = require('aws-cdk-lib/aws-apigateway'); class HelloLambdaStack extends Stack { /** * * @param {Construct} scope * @param {string} id * @param {StackProps=} props */ constructor(scope, id, props) { super(scope, id, props); const fn = new lambda.Function(this, 'MyFunction', { code: lambda.Code.asset('lib/lambda-handler'), runtime: lambda.Runtime.NODEJS_LATEST, handler: 'index.handler' }); const endpoint = new apigw.LambdaRestApi(this, 'MyEndpoint', { handler: fn, restApiName: "HelloApi" }); } } module.exports = { HelloLambdaStack }
TypeScript

lib/hello-lambda-stack.ts ファイルを開き、内容を次に置き換えます。

import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import * as apigw from "aws-cdk-lib/aws-apigateway"; import * as lambda from "aws-cdk-lib/aws-lambda"; import * as path from 'node:path'; export class HelloLambdaStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps){ super(scope, id, props) const fn = new lambda.Function(this, 'MyFunction', { runtime: lambda.Runtime.NODEJS_LATEST, handler: 'index.handler', code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), }); const endpoint = new apigw.LambdaRestApi(this, `ApiGwEndpoint`, { handler: fn, restApiName: `HelloApi`, }); } }
Python

/hello-lambda/hello_lambda/hello_lambda_stack.py ファイルを開き、内容を次に置き換えます。

from aws_cdk import ( Stack, aws_apigateway as apigw, aws_lambda as _lambda ) from constructs import Construct class HelloLambdaStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) fn = _lambda.Function( self, "MyFunction", runtime=_lambda.Runtime.NODEJS_LATEST, handler="index.handler", code=_lambda.Code.from_asset("lib/lambda-handler") ) endpoint = apigw.LambdaRestApi( self, "ApiGwEndpoint", handler=fn, rest_api_name="HelloApi" )
Java

/hello-lambda/src/main/java/com/myorg/HelloLambdaStack.java ファイルを開き、内容を次に置き換えます。

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; import software.amazon.awscdk.services.apigateway.LambdaRestApi; import software.amazon.awscdk.services.lambda.Function; public class HelloLambdaStack extends Stack { public HelloLambdaStack(final Construct scope, final String id) { this(scope, id, null); } public HelloLambdaStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); Function hello = Function.Builder.create(this, "MyFunction") .runtime(software.amazon.awscdk.services.lambda.Runtime.NODEJS_LATEST) .code(software.amazon.awscdk.services.lambda.Code.fromAsset("lib/lambda-handler")) .handler("index.handler") .build(); LambdaRestApi api = LambdaRestApi.Builder.create(this, "ApiGwEndpoint") .restApiName("HelloApi") .handler(hello) .build(); } }
C#

src/HelloLambda/HelloLambdaStack.cs ファイルを開き、内容を次に置き換えます。

using Amazon.CDK; using Amazon.CDK.AWS.APIGateway; using Amazon.CDK.AWS.Lambda; using Constructs; namespace HelloLambda { public class HelloLambdaStack : Stack { internal HelloLambdaStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { var fn = new Function(this, "MyFunction", new FunctionProps { Runtime = Runtime.NODEJS_LATEST, Code = Code.FromAsset("lib/lambda-handler"), Handler = "index.handler" }); var api = new LambdaRestApi(this, "ApiGwEndpoint", new LambdaRestApiProps { Handler = fn }); } } }

ステップ 3: Lambda 関数コードを作成する

  1. プロジェクトのルート (hello-lambda) から、Lambda 関数コードの /lib/lambda-handler ディレクトリを作成します。このディレクトリは、AWS CDK スタックの code プロパティで指定されます。

  2. /lib/lambda-handler ディレクトリに index.js という名前の新しいファイルを作成します。ファイルに次のコードを貼り付けます。関数は API リクエストから特定のプロパティを抽出し、JSON レスポンスとして返します。

    exports.handler = async (event) => { // Extract specific properties from the event object const { resource, path, httpMethod, headers, queryStringParameters, body } = event; const response = { resource, path, httpMethod, headers, queryStringParameters, body, }; return { body: JSON.stringify(response, null, 2), statusCode: 200, }; };

ステップ 4: AWS CDK スタックをデプロイする

  1. プロジェクトのルートから、cdk synth コマンドを実行します。

    cdk synth

    このコマンドは、CDK スタックから AWS CloudFormation テンプレートを合成します。テンプレートは、次のような約 400 行の YAML ファイルです。

    注記

    次のエラーが発生した場合は、プロジェクトディレクトリのルートにいることを確認してください。

    --app is required either in command-line, in cdk.json or in ~/.cdk.json
    例 AWS CloudFormation テンプレート
    Resources: MyFunctionServiceRole3C357FF2: 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 Metadata: aws:cdk:path: HelloLambdaStack/MyFunction/ServiceRole/Resource MyFunction1BAA52E7: Type: AWS::Lambda::Function Properties: Code: S3Bucket: Fn::Sub: cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region} S3Key: ab1111111cd32708dc4b83e81a21c296d607ff2cdef00f1d7f48338782f92l3901.zip Handler: index.handler Role: Fn::GetAtt: - MyFunctionServiceRole3C357FF2 - Arn Runtime: nodejs20.x ...
  2. cdk デプロイコマンドを実行します。

    cdk deploy

    リソースが作成されるまで待ちます。最終出力には、API Gateway エンドポイントの URL が含まれます。例:

    Outputs: HelloLambdaStack.ApiGwEndpoint77F417B1 = https://abcd1234.execute-api.us-east-1.amazonaws.com/prod/

ステップ 5: 関数をテストする

Lambda 関数を呼び出すには、API Gateway エンドポイントをコピーしてウェブブラウザに貼り付けるか、curl コマンドを実行します。

curl -s https://abcd1234.execute-api.us-east-1.amazonaws.com/prod/

レスポンスは、元のイベントオブジェクトから選択されたプロパティの JSON 表現であり、API Gateway エンドポイントに対して行われたリクエストに関する情報が含まれています。例:

{ "resource": "/", "path": "/", "httpMethod": "GET", "headers": { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Accept-Encoding": "gzip, deflate, br, zstd", "Accept-Language": "en-US,en;q=0.9", "CloudFront-Forwarded-Proto": "https", "CloudFront-Is-Desktop-Viewer": "true", "CloudFront-Is-Mobile-Viewer": "false", "CloudFront-Is-SmartTV-Viewer": "false", "CloudFront-Is-Tablet-Viewer": "false", "CloudFront-Viewer-ASN": "16509", "CloudFront-Viewer-Country": "US", "Host": "abcd1234.execute-api.us-east-1.amazonaws.com", ...

ステップ 6: リソースをクリーンアップする

API Gateway エンドポイントはパブリックにアクセスできます。予期しない料金が発生しないようにするには、cdk destroy コマンドを実行して、スタックと関連するすべてのリソースを削除します。

cdk destroy

次のステップ

選択した言語で AWS CDK アプリケーションを記述する方法については、以下を参照してください。

TypeScript

TypeScript で AWS CDK を操作

JavaScript

JavaScript で AWS CDK を操作 

Python

Python で AWS CDK を捜査 

Java

Java で AWS CDK を操作

C#

C# で AWS CDK を操作

Go

Go での AWS CDK の操作