チュートリアル: 最初の AWS CDK アプリの作成 - AWS Cloud Development Kit (AWS CDK) v2

これは v2 AWS CDK デベロッパーガイドです。古い CDKv1 は 2022 年 6 月 1 日にメンテナンスを開始し、2023 年 6 月 1 日にサポートを終了しました。

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

チュートリアル: 最初の AWS CDK アプリの作成

AWS CDK コマンドラインインターフェイス (AWS CDK CLI) を使用して AWS Cloud Development Kit (AWS CDK) の使用を開始し、最初の CDK アプリの開発、AWS 環境のブートストラップ、AWS にアプリケーションのデプロイを行います。

前提条件

このチュートリアルを開始する前に、AWS CDK の開始方法 の設定のステップをすべて完了させてください。

このチュートリアルの内容

このチュートリアルでは、AWS CDK を使用して AWS に単純なアプリケーションを作成してデプロイします。アプリケーションは、呼び出されたときに Hello World! メッセージを返す AWS Lambda 関数で構成されます。関数は、Lambda 関数の専用 HTTP(S) エンドポイントとして機能する Lambda 関数 URL を介して呼び出されます。

このチュートリアルでは、次の手順を実行します。

  • プロジェクトの作成 – CDK CLI cdk init コマンドを使用して CDK プロジェクトを作成します。

  • AWS 環境の設定 – アプリケーションをデプロイする AWS 環境を設定します。

  • AWS 環境のブートストラップ — CDK CLI cdk bootstrap コマンドを使用して AWS 環境をブートストラップしてデプロイの準備をします。

  • アプリの開発 – AWS コンストラクトライブラリのコンストラクトを使用し、Lambda 関数および Lambda 関数 URL リソースを定義します。

  • アプリのデプロイの準備 – CDK CLI を使用し、アプリを構築して AWS CloudFormation テンプレートを合成します。

  • アプリをデプロイする – CDK CLI cdk deploy コマンドを使用し、アプリケーションをデプロイして AWS リソースをプロビジョニングします。

  • アプリケーションの操作 – デプロイされた Lambda 関数を呼び出してレスポンスを得て、AWS で操作します。

  • アプリの変更 – Lambda 関数を変更してデプロイし、変更を実装します。

  • アプリの削除 – CDK CLI cdk destroy コマンドを使用して作成したすべてのリソースを削除します。

ステップ 1: CDK プロジェクトの作成

このステップでは、新しい CKD プロジェクトを作成します。CDK プロジェクトは、独自のローカルモジュールの依存関係を持つ独自のディレクトリにある必要があります。

CDK プロジェクトを作成する方法
  1. 選択した開始ディレクトリで、hello-cdk という名前のディレクトリを作成して移動します。

    $ mkdir hello-cdk && cd hello-cdk
    重要

    こちらに示されているとおり、プロジェクトディレクトリに必ず hello-cdk という名前を付けてください。CDK CLI は、このディレクトリ名を使用して CDK コード内のものに名前を付けます。別のディレクトリ名を使用する場合、このチュートリアル中に問題が発生します。

  2. hello-cdk ディレクトリで、CDK CLI cdk init コマンドを使用して新しい CDK プロジェクトを初期化します。--language オプションを使用し、app テンプレートおよび任意のプログラミング言語を指定します。

    TypeScript
    $ cdk init app --language typescript
    JavaScript
    $ cdk init app --language javascript
    Python
    $ cdk init app --language python

    アプリを作成したら、以下の 2 つのコマンドも入力します。アプリの Python 仮想環境がアクティブ化され、AWS CDK コア依存関係がインストールされます。

    $ source .venv/bin/activate # On Windows, run `.\venv\Scripts\activate` instead $ python -m pip install -r requirements.txt
    Java
    $ cdk init app --language java

    IDE を使用している場合は、これでプロジェクトを開くかインポートできるようになります。例えば、Eclipse では [ファイル] > [インポート] > [Maven] > [既存の Maven プロジェクト] を選択します。プロジェクト設定が Java 8 (1.8) を使用するように設定されていることを確認してください。

    C#
    $ cdk init app --language csharp

    Visual Studio を使用している場合は、src ディレクトリでソリューションファイルを開きます。

    Go
    $ cdk init app --language go

    アプリを作成したら、以下のコマンドを入力して、アプリに必要な AWS コンストラクトライブラリモジュールをインストールします。

    $ go get

cdk init コマンドは hello-cdk ディレクトリ内にファイルおよびフォルダの構造を作成し、CDK アプリのソースコードを整理できるようにします。このファイルおよびフォルダの構造は、CDK プロジェクトと呼ばれます。少し時間をかけて CDK プロジェクトを確認してください。

Git がインストールされている場合、cdk init を使用して作成する各プロジェクトも Git リポジトリとして初期化されます。

プロジェクトの初期化中、CDK CLI は 1 つの CDK スタックを含む CDK アプリを作成します。CDK アプリインスタンスは、App コンストラクトを使用して作成されます。次の内容は、CDK アプリケーションファイルのこのコードの一部です。

TypeScript

bin/hello-cdk.ts にあります

#!/usr/bin/env node import 'source-map-support/register'; import * as cdk from 'aws-cdk-lib'; import { HelloCdkStack } from '../lib/hello-cdk-stack'; const app = new cdk.App(); new HelloCdkStack(app, 'HelloCdkStack', { });
JavaScript

bin/hello-cdk.js にあります

#!/usr/bin/env node const cdk = require('aws-cdk-lib'); const { HelloCdkStack } = require('../lib/hello-cdk-stack'); const app = new cdk.App(); new HelloCdkStack(app, 'HelloCdkStack', { });
Python

app.py にあります

#!/usr/bin/env python3 import os import aws_cdk as cdk from hello_cdk.hello_cdk_stack import HelloCdkStack app = cdk.App() HelloCdkStack(app, "HelloCdkStack",) app.synth()
Java

src/main/java/.../HelloCdkApp.java にあります

package com.myorg; import software.amazon.awscdk.App; import software.amazon.awscdk.Environment; import software.amazon.awscdk.StackProps; import java.util.Arrays; public class HelloCdkApp { public static void main(final String[] args) { App app = new App(); new HelloCdkStack(app, "HelloCdkStack", StackProps.builder() .build()); app.synth(); } }
C#

src/HelloCdk/Program.cs にあります

using Amazon.CDK; using System; using System.Collections.Generic; using System.Linq; namespace HelloCdk { sealed class Program { public static void Main(string[] args) { var app = new App(); new HelloCdkStack(app, "HelloCdkStack", new StackProps {}); app.Synth(); } } }
Go

hello-cdk.go にあります

package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" ) // ... func main() { defer jsii.Close() app := awscdk.NewApp(nil) NewHelloCdkStack(app, "HelloCdkStack", &HelloCdkStackProps{ awscdk.StackProps{ Env: env(), }, }) app.Synth(nil) } // ...

CDK スタックは Stack コンストラクトを使用して作成されます。次の内容は、CDK スタックファイルのこのコードの一部です。

TypeScript

lib/hello-cdk-stack.ts にあります

import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; export class HelloCdkStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Define your constructs here } }
JavaScript

lib/hello-cdk-stack.js にあります

const { Stack } = require('aws-cdk-lib'); class HelloCdkStack extends Stack { constructor(scope, id, props) { super(scope, id, props); // Define your constructs here } } module.exports = { HelloCdkStack }
Python

hello_cdk/hello_cdk_stack.py にあります

from aws_cdk import ( Stack, ) from constructs import Construct class HelloCdkStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # Define your constructs here
Java

src/main/java/.../HelloCdkStack.java にあります

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; public class HelloCdkStack extends Stack { public HelloCdkStack(final Construct scope, final String id) { this(scope, id, null); } public HelloCdkStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); // Define your constructs here } }
C#

src/HelloCdk/HelloCdkStack.cs にあります

using Amazon.CDK; using Constructs; namespace HelloCdk { public class HelloCdkStack : Stack { internal HelloCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { // Define your constructs here } } }
Go

hello-cdk.go にあります

package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" ) type HelloCdkStackProps struct { awscdk.StackProps } func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) return stack } // ...

ステップ 2: AWS 環境の設定

このステップでは、CDK スタックの AWS 環境を設定します。これにより、CDK スタックをデプロイする環境を指定します。

最初は、使用する AWS 環境を決定します。AWS 環境は AWS アカウント および AWS リージョン で構成されます。

AWS CLI を使用してセキュリティ認証情報をローカルマシンに設定するとき、AWS CLI を使用して特定のプロファイルの AWS 環境情報を取得できます。

AWS CLI を使用して AWS アカウント IDを取得する方法
  1. 次の AWS CLI コマンドを実行し、default プロファイルの AWS アカウント ID を取得します。

    $ aws sts get-caller-identity --query "Account" --output text
  2. 名前付きプロファイルを使用する場合、--profile オプションを使用してプロファイルの名前を指定します。

    $ aws sts get-caller-identity --profile your-profile-name --query "Account" --output text
AWS リージョン を取得するために AWS CLI の使用
  1. 次の AWS CLI コマンドを実行し、default プロファイル用に設定したリージョンを取得します。

    $ aws configure get region
  2. 名前付きプロファイルを使用する場合、--profile オプションを使用してプロファイルの名前を指定します。

    $ aws configure get region --profile your-profile-name

次に、アプリケーションファイルHelloCdkStack インスタンスを変更し、CDK スタックの AWS 環境を設定します。このチュートリアルでは、AWS 環境情報をハードコーディングします。これは本番環境に推奨されます。環境を設定するその他の方法の詳細については、「AWS CDK で使用する環境を設定する」を参照してください。

CDK スタックの環境を設定する方法
  • アプリケーションファイルで、Stack コンストラクトの env プロパティを使用して環境を設定します。以下に例を示します。

    TypeScript

    bin/hello-cdk.ts にあります

    #!/usr/bin/env node import 'source-map-support/register'; import * as cdk from 'aws-cdk-lib'; import { HelloCdkStack } from '../lib/hello-cdk-stack'; const app = new cdk.App(); new HelloCdkStack(app, 'HelloCdkStack', { env: { account: '123456789012', region: 'us-east-1' }, });
    JavaScript

    bin/hello-cdk.js にあります

    #!/usr/bin/env node const cdk = require('aws-cdk-lib'); const { HelloCdkStack } = require('../lib/hello-cdk-stack'); const app = new cdk.App(); new HelloCdkStack(app, 'HelloCdkStack', { env: { account: '123456789012', region: 'us-east-1' }, });
    Python

    app.py にあります

    #!/usr/bin/env python3 import os import aws_cdk as cdk from hello_cdk.hello_cdk_stack import HelloCdkStack app = cdk.App() HelloCdkStack(app, "HelloCdkStack", env=cdk.Environment(account='123456789012', region='us-east-1'), ) app.synth()
    Java

    src/main/java/.../HelloCdkApp.java にあります

    package com.myorg; import software.amazon.awscdk.App; import software.amazon.awscdk.Environment; import software.amazon.awscdk.StackProps; import java.util.Arrays; public class HelloCdkApp { public static void main(final String[] args) { App app = new App(); new HelloCdkStack(app, "HelloCdkStack", StackProps.builder() .env(Environment.builder() .account("123456789012") .region("us-east-1") .build()) .build()); app.synth(); } }
    C#

    src/HelloCdk/Program.cs にあります

    using Amazon.CDK; using System; using System.Collections.Generic; using System.Linq; namespace HelloCdk { sealed class Program { public static void Main(string[] args) { var app = new App(); new HelloCdkStack(app, "HelloCdkStack", new StackProps { Env = new Amazon.CDK.Environment { Account = "123456789012", Region = "us-east-1", } }); app.Synth(); } } }
    Go

    hello-cdk.go にあります

    package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" ) // ... func main() { defer jsii.Close() app := awscdk.NewApp(nil) NewHelloCdkStack(app, "HelloCdkStack", &HelloCdkStackProps{ awscdk.StackProps{ Env: env(), }, }) app.Synth(nil) } func env() *awscdk.Environment { return &awscdk.Environment{ Account: jsii.String("123456789012"), Region: jsii.String("us-east-1"), } }

ステップ 3: AWS 環境のブートストラップ

このステップでは、前のステップで設定した AWS 環境をブートストラップします。CDK デプロイのために環境が準備されます。

環境をブートストラップするには、CDK プロジェクトのルートから次の内容を実行します。

$ cdk bootstrap

CDK プロジェクトのルートからブートストラップすることにより、追加情報を提供する必要はありません。CDK CLI は、プロジェクトから環境情報を取得します。CDK プロジェクトの外部でブートストラップするとき、cdk bootstrap コマンドを使用して環境情報を提供する必要があります。詳細については、「で使用する環境をブートストラップする AWS CDK」を参照してください。

ステップ 4: CDK アプリの構築

ほとんどのプログラミング環境では、変更後にコードを構築またはコンパイルします。CDK CLIが自動的にこのステップを実行するため、AWS CDK では必要ありません。ただし、構文および型エラーをキャッチするときでも、手動で構築できます。以下に例を示します。

TypeScript
$ npm run build > hello-cdk@0.1.0 build > tsc
JavaScript

構築ステップは必要ありません。

Python

構築ステップは必要ありません。

Java
$ mvn compile -q

または、Eclipseで Control-B を押します (他の Java IDE は異なる場合があります)。

C#
$ dotnet build src

または、Visual Studio で F6 キーを押します。

Go
$ go build

ステップ 5: アプリの CDK スタックの一覧表示

この時点では、1 つの CDK スタックを含む CDK アプリが必要です。確認するには、CDK CLI cdk list コマンドを使用してスタックを表示します。出力には、HelloCdkStack という名前のスタックが 1 つ表示されます。

$ cdk list HelloCdkStack

この出力が表示されない場合、プロジェクトの正しい作業ディレクトリにいることを確認し、もう一度やり直してください。スタックが表示されない場合は、ステップ 1: CDK プロジェクトの作成 を繰り返してもう一度やり直してください。

ステップ 6: Lambda 関数の定義

このステップでは、AWS コンストラクトライブラリから aws_lambda モジュールをインポートし、Function L2 コンストラクトを使用します。

次のように、CDK スタックファイルを変更します。

TypeScript

lib/hello-cdk-stack.ts にあります

import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; // Import the Lambda module import * as lambda from 'aws-cdk-lib/aws-lambda'; export class HelloCdkStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Define the Lambda function resource const myFunction = new lambda.Function(this, "HelloWorldFunction", { runtime: lambda.Runtime.NODEJS_20_X, // Provide any supported Node.js runtime handler: "index.handler", code: lambda.Code.fromInline(` exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello World!'), }; }; `), }); } }
JavaScript

lib/hello-cdk-stack.js にあります

const { Stack } = require('aws-cdk-lib'); // Import the Lambda module const lambda = require('aws-cdk-lib/aws-lambda'); class HelloCdkStack extends Stack { constructor(scope, id, props) { super(scope, id, props); // Define the Lambda function resource const myFunction = new lambda.Function(this, "HelloWorldFunction", { runtime: lambda.Runtime.NODEJS_20_X, // Provide any supported Node.js runtime handler: "index.handler", code: lambda.Code.fromInline(` exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello World!'), }; }; `), }); } } module.exports = { HelloCdkStack }
Python

hello_cdk/hello_cdk_stack.py にあります

from aws_cdk import ( Stack, aws_lambda as _lambda, # Import the Lambda module ) from constructs import Construct class HelloCdkStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # Define the Lambda function resource my_function = _lambda.Function( self, "HelloWorldFunction", runtime = _lambda.Runtime.NODEJS_20_X, # Provide any supported Node.js runtime handler = "index.handler", code = _lambda.Code.from_inline( """ exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello World!'), }; }; """ ), )
Java

src/main/java/.../HelloCdkStack.java にあります

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; // Import Lambda function import software.amazon.awscdk.services.lambda.Code; import software.amazon.awscdk.services.lambda.Function; import software.amazon.awscdk.services.lambda.Runtime; public class HelloCdkStack extends Stack { public HelloCdkStack(final Construct scope, final String id) { this(scope, id, null); } public HelloCdkStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); // Define the Lambda function resource Function myFunction = Function.Builder.create(this, "HelloWorldFunction") .runtime(Runtime.NODEJS_20_X) // Provide any supported Node.js runtime .handler("index.handler") .code(Code.fromInline( "exports.handler = async function(event) {" + " return {" + " statusCode: 200," + " body: JSON.stringify('Hello World!')" + " };" + "};")) .build(); } }
C#

src/main/java/.../HelloCdkStack.java にあります

using Amazon.CDK; using Constructs; // Import the Lambda module using Amazon.CDK.AWS.Lambda; namespace HelloCdk { public class HelloCdkStack : Stack { internal HelloCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { // Define the Lambda function resource var myFunction = new Function(this, "HelloWorldFunction", new FunctionProps { Runtime = Runtime.NODEJS_20_X, // Provide any supported Node.js runtime Handler = "index.handler", Code = Code.FromInline(@" exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello World!'), }; }; "), }); } } }
Go

hello-cdk.go にあります

package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" // Import the Lambda module "github.com/aws/aws-cdk-go/awscdk/v2/awslambda" ) type HelloCdkStackProps struct { awscdk.StackProps } func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) // Define the Lambda function resource myFunction := awslambda.NewFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.FunctionProps{ Runtime: awslambda.Runtime_NODEJS_20_X(), // Provide any supported Node.js runtime Handler: jsii.String("index.handler"), Code: awslambda.Code_FromInline(jsii.String(` exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello World!'), }; }; `)), }) return stack } // ...

Function コンストラクトの詳細を見てみましょう。すべてのコンストラクトと同様に、Function クラスは 3 つのパラメータを使用します。

  • scopeStack インスタンスを Function コンストラクトの親として定義します。AWS リソースを定義するすべてのコンストラクトは、スタックの範囲内で作成されます。コンストラクト内でコンストラクトを定義し、階層 (ツリー) を作成できます。こちらとほとんどの場合、スコープは this (Python で self) です。

  • ID – AWS CDK アプリ内の Function のコンストラクト ID。この ID に加え、スタック内で関数の場所に基づくハッシュは、デプロイ中に関数を一意に識別します。アプリの コンストラクトを更新し、デプロイされたリソースを更新するために再デプロイするとき、AWS CDK はこの ID も参照します。こちらでは、コンストラクト ID は HelloWorldFunction です。関数には functionName プロパティで指定された名前を付けることもできます。これはコンストラクト ID とは異なります。

  • props – 関数のプロパティを定義する値のバンドル。こちらでは runtimehandlercode プロパティを定義します。

    Props は、AWS CDK でサポートされている言語で異なる方法で表されます。

    • TypeScript および JavaScript では、props は単一の引数であり、目的のプロパティを含むオブジェクトを渡します。

    • Python では、props はキーワード引数として渡されます。

    • Java では、ビルダーは props を渡すために提供されます。2 つあります。1 つは FunctionProps 用で、2 つ目は 1 つのステップでコンストラクトおよびその props オブジェクトを構築できるようにするため、Function 用にあります。このコードは後者を使用します。

    • C# では、オブジェクト初期化子を使用して FunctionProps オブジェクトをインスタンス化し、3 番目のパラメータとして渡します。

    コンストラクトの props がオプションの場合、props パラメータを完全に省略できます。

すべてのコンストラクトはこれらの 3 つの引数を取るため、新しい引数について知るときに方向性の意識を維持しやすくなります。さらに予想どおり、必要に応じて、あるいはデフォルトを変更する場合、任意のコンストラクトをサブクラス化して拡張できます。

ステップ 7: Lambda 関数 URL の定義

このステップでは、Function コンストラクトの addFunctionUrl ヘルパーメソッドを使用し、Lambda 関数 URL を定義します。デプロイ時にこの URL の値を出力するには、CfnOutput コンストラクトを使用して AWS CloudFormation 出力を作成します。

次の内容を CDK スタックファイルに追加します。

TypeScript

lib/hello-cdk-stack.ts にあります

// ... export class HelloCdkStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Define the Lambda function resource // ... // Define the Lambda function URL resource const myFunctionUrl = myFunction.addFunctionUrl({ authType: lambda.FunctionUrlAuthType.NONE, }); // Define a CloudFormation output for your URL new cdk.CfnOutput(this, "myFunctionUrlOutput", { value: myFunctionUrl.url, }) } }
JavaScript

lib/hello-cdk-stack.js にあります

const { Stack, CfnOutput } = require('aws-cdk-lib'); // Import CfnOutput class HelloCdkStack extends Stack { constructor(scope, id, props) { super(scope, id, props); // Define the Lambda function resource // ... // Define the Lambda function URL resource const myFunctionUrl = myFunction.addFunctionUrl({ authType: lambda.FunctionUrlAuthType.NONE, }); // Define a CloudFormation output for your URL new CfnOutput(this, "myFunctionUrlOutput", { value: myFunctionUrl.url, }) } } module.exports = { HelloCdkStack }
Python

hello_cdk/hello_cdk_stack.py にあります

from aws_cdk import ( # ... CfnOutput # Import CfnOutput ) from constructs import Construct class HelloCdkStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # Define the Lambda function resource # ... # Define the Lambda function URL resource my_function_url = my_function.add_function_url( auth_type = _lambda.FunctionUrlAuthType.NONE, ) # Define a CloudFormation output for your URL CfnOutput(self, "myFunctionUrlOutput", value=my_function_url.url)
Java

src/main/java/.../HelloCdkStack.java にあります

package com.myorg; // ... // Import Lambda function URL import software.amazon.awscdk.services.lambda.FunctionUrl; import software.amazon.awscdk.services.lambda.FunctionUrlAuthType; import software.amazon.awscdk.services.lambda.FunctionUrlOptions; // Import CfnOutput import software.amazon.awscdk.CfnOutput; public class HelloCdkStack extends Stack { public HelloCdkStack(final Construct scope, final String id) { this(scope, id, null); } public HelloCdkStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); // Define the Lambda function resource // ... // Define the Lambda function URL resource FunctionUrl myFunctionUrl = myFunction.addFunctionUrl(FunctionUrlOptions.builder() .authType(FunctionUrlAuthType.NONE) .build()); // Define a CloudFormation output for your URL CfnOutput.Builder.create(this, "myFunctionUrlOutput") .value(myFunctionUrl.getUrl()) .build(); } }
C#

src/main/java/.../HelloCdkStack.java にあります

// ... namespace HelloCdk { public class HelloCdkStack : Stack { internal HelloCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { // Define the Lambda function resource // ... // Define the Lambda function URL resource var myFunctionUrl = myFunction.AddFunctionUrl(new FunctionUrlOptions { AuthType = FunctionUrlAuthType.NONE }); // Define a CloudFormation output for your URL new CfnOutput(this, "myFunctionUrlOutput", new CfnOutputProps { Value = myFunctionUrl.Url }); } } }
Go

hello-cdk.go にあります

// ... func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) // Define the Lambda function resource // ... // Define the Lambda function URL resource myFunctionUrl := myFunction.AddFunctionUrl(&awslambda.FunctionUrlOptions{ AuthType: awslambda.FunctionUrlAuthType_NONE, }) // Define a CloudFormation output for your URL awscdk.NewCfnOutput(stack, jsii.String("myFunctionUrlOutput"), &awscdk.CfnOutputProps{ Value: myFunctionUrl.Url(), }) return stack } // ...
警告

このチュートリアルを簡単にするため、Lambda 関数 URL は認証なしで定義されます。デプロイすると、関数の呼び出しに使用できるパブリックアクセス可能なエンドポイントが作成されます。このチュートリアルを完了したら、ステップ 12: アプリケーションの削除 に従ってこれらのリソースを削除します。

ステップ 8: CloudFormation テンプレートの合成

このステップでは、CDK CLI cdk synth コマンドを使用して CloudFormation テンプレートを合成することにより、デプロイの準備をします。このコマンドは CDK コードの基本的な検証の実行、CDK アプリの実行、CDK スタックから CloudFormation テンプレートの生成をします。

アプリに複数のスタックが含まれている場合、合成するスタックを指定する必要があります。アプリに 1 つのスタックが含まれているため、CDK CLI は合成するスタックを自動的に検出します。

テンプレートを合成しない場合、デプロイ時にCDK CLI はこのステップを自動的に実行します。ただし、合成エラーを確認するには、各デプロイの前にこのステップを実行することをお勧めします。

テンプレートを合成する前に、オプションでアプリケーションを構築し、構文および入力エラーをキャッチできます。手順については、ステップ 4: CDK アプリの構築 を参照してください。

CloudFormation テンプレートを合成するには、プロジェクトのルートから次の内容を実行します。

$ cdk synth
注記

次のようなエラーが表示された場合、hello-cdk ディレクトリにいることを確認してもう一度やり直してください。

--app is required either in command-line, in cdk.json or in ~/.cdk.json

正常に処理された場合、CDK CLI は YAML にフォーマットされた CloudFormation テンプレートを stdout に出力し、JSON にフォーマットされたテンプレートをプロジェクトの cdk.out ディレクトリに保存します。

次の内容は、CloudFormation テンプレートの出力の例です。

Resources: HelloWorldFunctionServiceRoleunique-identifier: 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: HelloCdkStack/HelloWorldFunction/ServiceRole/Resource HelloWorldFunctionunique-identifier: Type: AWS::Lambda::Function Properties: Code: ZipFile: " \ exports.handler = async function(event) { \ return { \ statusCode: 200, \ body: JSON.stringify('Hello World!'), \ }; \ }; \ " Handler: index.handler Role: Fn::GetAtt: - HelloWorldFunctionServiceRoleunique-identifier - Arn Runtime: nodejs20.x DependsOn: - HelloWorldFunctionServiceRoleunique-identifier Metadata: aws:cdk:path: HelloCdkStack/HelloWorldFunction/Resource HelloWorldFunctionFunctionUrlunique-identifier: Type: AWS::Lambda::Url Properties: AuthType: NONE TargetFunctionArn: Fn::GetAtt: - HelloWorldFunctionunique-identifier - Arn Metadata: aws:cdk:path: HelloCdkStack/HelloWorldFunction/FunctionUrl/Resource HelloWorldFunctioninvokefunctionurlunique-identifier: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunctionUrl FunctionName: Fn::GetAtt: - HelloWorldFunctionunique-identifier - Arn FunctionUrlAuthType: NONE Principal: "*" Metadata: aws:cdk:path: HelloCdkStack/HelloWorldFunction/invoke-function-url CDKMetadata: Type: AWS::CDK::Metadata Properties: Analytics: v2:deflate64:unique-identifier Metadata: aws:cdk:path: HelloCdkStack/CDKMetadata/Default Condition: CDKMetadataAvailable Outputs: myFunctionUrlOutput: Value: Fn::GetAtt: - HelloWorldFunctionFunctionUrlunique-identifier - FunctionUrl Parameters: BootstrapVersion: Type: AWS::SSM::Parameter::Value<String> Default: /cdk-bootstrap/unique-identifier/version Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip] Rules: CheckBootstrapVersion: Assertions: - Assert: Fn::Not: - Fn::Contains: - - "1" - "2" - "3" - "4" - "5" - Ref: BootstrapVersion AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.
注記

生成されたすべてのテンプレートには、デフォルトで AWS::CDK::Metadata リソースが含まれています。AWS CDK チームはこのメタデータを使用して AWS CDK 使用状況を把握し、改善方法を探します。バージョンレポートをオプトアウトする方法などの詳細については、「バージョンのレポート」を参照してください。

1 つの L2 コンストラクトを定義することにより、AWS CDK は Lambda リソースを含む広範な CloudFormation テンプレートに加え、リソースがアプリケーション内で操作するために必要なアクセス許可およびグルーロジックも作成します。

ステップ 9: CDK スタックのデプロイ

このステップでは、CDK CLI cdk deploy コマンドを使用して CDK スタックをデプロイします。このコマンドは、生成された CloudFormation テンプレートを取得して AWS CloudFormation を通じてデプロイします。これにより、CloudFormation スタックの一部としてリソースがプロビジョニングされます。

プロジェクトのルートから次のコマンドを実行します。プロンプトが表示されたら変更を確認します。

$ cdk deploy ✨ Synthesis time: 2.69s HelloCdkStack: start: Building unique-identifier:current_account-current_region HelloCdkStack: success: Built unique-identifier:current_account-current_region HelloCdkStack: start: Publishing unique-identifier:current_account-current_region HelloCdkStack: success: Published unique-identifier:current_account-current_region 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 │ ├───┼───────────────────────────────────────┼────────┼──────────────────────────┼──────────────────────────────┼───────────┤ │ + │ ${HelloWorldFunction.Arn} │ Allow │ lambda:InvokeFunctionUrl │ * │ │ ├───┼───────────────────────────────────────┼────────┼──────────────────────────┼──────────────────────────────┼───────────┤ │ + │ ${HelloWorldFunction/ServiceRole.Arn} │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws.com │ │ └───┴───────────────────────────────────────┴────────┴──────────────────────────┴──────────────────────────────┴───────────┘ IAM Policy Changes ┌───┬───────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐ │ │ Resource │ Managed Policy ARN │ ├───┼───────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ + │ ${HelloWorldFunction/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

cdk synth と同様に、アプリには 1 つのスタックが含まれているため、AWS CDK スタックを指定する必要はありません。

デプロイ中、スタックがデプロイされると CDK CLI に進行状況情報が表示されます。完了したら、AWS CloudFormation コンソールに移動して HelloCdkStack スタックを確認できます。Lambda コンソールにアクセスして HelloWorldFunction リソースを確認することもできます。

デプロイが完了すると、CDK CLI はエンドポイント URL を出力します。次のステップ用にこの URL をコピーします。以下に例を示します。

... HelloCdkStack: deploying... [1/1] HelloCdkStack: creating CloudFormation changeset... ✅ HelloCdkStack ✨ Deployment time: 41.65s Outputs: HelloCdkStack.myFunctionUrlOutput = https://<api-id>.lambda-url.<Region>.on.aws/ Stack ARN: arn:aws:cloudformation:Region:account-id:stack/HelloCdkStack/unique-identifier ✨ Total time: 44.34s

ステップ 10: AWS でアプリケーションの操作

このステップでは、関数 URL を使用して Lambda 関数を呼び出すことにより、AWS でアプリケーションを操作します。URL にアクセスすると、Lambda 関数は Hello World! メッセージを返します。

関数を呼び出すには、ブラウザまたはコマンドラインから関数 URL にアクセスします。以下に例を示します。

$ curl https://<api-id>.lambda-url.<Region>.on.aws/ "Hello World!"%

ステップ 11: アプリケーションの変更

このステップでは、呼び出し時に Lambda 関数が返すメッセージを変更します。CDK CLI cdk diff コマンドを使用して差分を実行し、変更をプレビューしたら、デプロイしてアプリケーションを更新します。次に、AWS でアプリケーションを操作し、新しいメッセージを確認します。

CDK スタックファイルの myFunction インスタンスを次のように変更します。

TypeScript

lib/hello-cdk-stack.ts にあります

// ... export class HelloCdkStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Modify the Lambda function resource const myFunction = new lambda.Function(this, "HelloWorldFunction", { runtime: lambda.Runtime.NODEJS_20_X, // Provide any supported Node.js runtime handler: "index.handler", code: lambda.Code.fromInline(` exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello CDK!'), }; }; `), }); // ...
JavaScript

lib/hello-cdk-stack.js にあります

// ... class HelloCdkStack extends Stack { constructor(scope, id, props) { super(scope, id, props); // Modify the Lambda function resource const myFunction = new lambda.Function(this, "HelloWorldFunction", { runtime: lambda.Runtime.NODEJS_20_X, // Provide any supported Node.js runtime handler: "index.handler", code: lambda.Code.fromInline(` exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello CDK!'), }; }; `), }); // ... } } module.exports = { HelloCdkStack }
Python

hello_cdk/hello_cdk_stack.py にあります

# ... class HelloCdkStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # Modify the Lambda function resource my_function = _lambda.Function( self, "HelloWorldFunction", runtime = _lambda.Runtime.NODEJS_20_X, # Provide any supported Node.js runtime handler = "index.handler", code = _lambda.Code.from_inline( """ exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello CDK!'), }; }; """ ), ) # ...
Java

src/main/java/.../HelloCdkStack.java にあります

// ... public class HelloCdkStack extends Stack { public HelloCdkStack(final Construct scope, final String id) { this(scope, id, null); } public HelloCdkStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); // Modify the Lambda function resource Function myFunction = Function.Builder.create(this, "HelloWorldFunction") .runtime(Runtime.NODEJS_20_X) // Provide any supported Node.js runtime .handler("index.handler") .code(Code.fromInline( "exports.handler = async function(event) {" + " return {" + " statusCode: 200," + " body: JSON.stringify('Hello CDK!')" + " };" + "};")) .build(); // ... } }
C#

// ... namespace HelloCdk { public class HelloCdkStack : Stack { internal HelloCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { // Modify the Lambda function resource var myFunction = new Function(this, "HelloWorldFunction", new FunctionProps { Runtime = Runtime.NODEJS_20_X, // Provide any supported Node.js runtime Handler = "index.handler", Code = Code.FromInline(@" exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello CDK!'), }; }; "), }); // ... } } }
Go

// ... type HelloCdkStackProps struct { awscdk.StackProps } func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) // Modify the Lambda function resource myFunction := awslambda.NewFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.FunctionProps{ Runtime: awslambda.Runtime_NODEJS_20_X(), // Provide any supported Node.js runtime Handler: jsii.String("index.handler"), Code: awslambda.Code_FromInline(jsii.String(` exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello CDK!'), }; }; `)), }) // ...

現在、コードの変更はデプロイされた Lambda リソースに直接更新が行われていません。コードは、リソースの目的の状態を定義します。デプロイされたリソースを変更するには、CDK CLI を使用して目的の状態を新しい AWS CloudFormation テンプレートに合成します。次に、新しい CloudFormation テンプレートを変更セットとしてデプロイします。変更セットは、新しい目的の状態に達するために必要な変更のみを行います。

変更をプレビューするには、cdk diff コマンドを実行します。以下に例を示します。

$ cdk diff Stack HelloCdkStack Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff) Resources [~] AWS::Lambda::Function HelloWorldFunction HelloWorldFunctionunique-identifier └─ [~] Code └─ [~] .ZipFile: ├─ [-] exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello World!'), }; }; └─ [+] exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello CDK!'), }; }; ✨ Number of stacks with differences: 1

この差分を作成するには、CDK は AWS アカウント アカウントに対して HelloCdkStack スタックの最新 AWS CloudFormation テンプレートを CLI クエリします。次に、最新のテンプレートとアプリから合成したばかりのテンプレートを比較します。

変更を実装するには、cdk deploy コマンドを実行します。以下に例を示します。

$ cdk deploy ✨ Synthesis time: 2.12s HelloCdkStack: start: Building unique-identifier:current_account-current_region HelloCdkStack: success: Built unique-identifier:current_account-current_region HelloCdkStack: start: Publishing unique-identifier:current_account-current_region HelloCdkStack: success: Published unique-identifier:current_account-current_region HelloCdkStack: deploying... [1/1] HelloCdkStack: creating CloudFormation changeset... ✅ HelloCdkStack ✨ Deployment time: 26.96s Outputs: HelloCdkStack.myFunctionUrlOutput = https://unique-identifier.lambda-url.<Region>.on.aws/ Stack ARN: arn:aws:cloudformation:Region:account-id:stack/HelloCdkStack/unique-identifier ✨ Total time: 29.07s

アプリケーションを操作するには、ステップ 10: AWS でアプリケーションの操作 を繰り返します。以下に例を示します。

$ curl https://<api-id>.lambda-url.<Region>.on.aws/ "Hello CDK!"%

ステップ 12: アプリケーションの削除

このステップでは、CDK CLI cdk destroy コマンドを使用してアプリケーションを削除します。このコマンドは、作成したリソースを含む CDK スタックに関連付けられた CloudFormation スタックを削除します。

アプリケーションを削除するには、cdk destroy コマンドを実行してアプリケーションを削除する要求を確認します。以下に例を示します。

$ cdk destroy Are you sure you want to delete: HelloCdkStack (y/n)? y HelloCdkStack: destroying... [1/1] ✅ HelloCdkStack: destroyed

次のステップ

お疲れ様でした。このチュートリアルを完了し、AWS CDK を使用して AWS クラウド のリソースの作成、変更、削除を正常に実行できました。これで AWS CDK の使用を開始する準備が整いました。

任意のプログラミング言語で AWS CDK の使用の詳細については、「AWS CDK ライブラリの使用」を参照してください。

その他のリソースについては、次の内容を参照してください。

  • CDK ワークショップを試し、より複雑なプロジェクトに関連する詳細なチュートリアルを体験できます。

  • APIリファレンス」を参照し、お気に入りのAWSサービスで利用できる CDK コンストラクトを確認できます。

  • Construct Hub にアクセスし、AWS およびその他のユーザーが作成したコンストラクトを確認できます。

  • AWS CDK を使用するを確認してください。

AWS CDK はオープンソースプロジェクトです。貢献するには、「AWS Cloud Development Kit (AWS CDK) への貢献」を参照してください。