CDK スタック合成を設定して実行する - AWS Cloud Development Kit (AWS CDK) v2

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

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

CDK スタック合成を設定して実行する

AWS Cloud Development Kit (AWS CDK) スタックをデプロイする前に、まずスタックを合成する必要があります。スタック合成は、CDKスタックから AWS CloudFormation テンプレートとデプロイアーティファクトを生成するプロセスです。テンプレートとアーティファクトは、クラウドアセンブリ と呼ばれます。クラウドアセンブリは、 でリソースをプロビジョニングするためにデプロイされます AWS。デプロイの仕組みの詳細については、「」を参照してくださいAWS CDK デプロイの仕組み

合成とブートストラップの連携方法

CDK アプリケーションを適切にデプロイするには、合成中に生成された CloudFormation テンプレートで、ブートストラップ中に作成されたリソースを正しく指定する必要があります。したがって、ブートストラップと合成は、デプロイを成功させるために相互に補完する必要があります。

  • ブートストラップは、 AWS CDK デプロイ用の AWS 環境を設定する 1 回限りのプロセスです。デプロイCDKに が使用する環境内の特定の AWS リソースを設定します。これらは一般的にブートストラップリソース と呼ばれます。ブートストラップの手順については、「」を参照してくださいで使用する環境をブートストラップする AWS CDK

  • CloudFormation 合成中に生成されるテンプレートには、使用するブートストラップリソースに関する情報が含まれます。合成中、 CDKCLI は、 AWS 環境がブートストラップされた方法を具体的には知りません。代わりに、 CDKCLI は、各CDKスタック用に設定したシンセサイザーに基づいて CloudFormation テンプレートを生成します。デプロイを成功させるには、シンセサイザーは使用する正しいブートストラップリソースを参照する CloudFormation テンプレートを作成する必要があります。

CDK には、連携するように設計されたデフォルトのシンセサイザーとブートストラップ設定が付属しています。1 つをカスタマイズする場合は、関連するカスタマイズをもう 1 つに適用する必要があります。

CDK スタック合成を設定する方法

CDK スタック合成は、Stackインスタンスの synthesizerプロパティを使用して設定します。このプロパティは、CDKスタックの合成方法を指定します。IStackSynthesizer または を実装するクラスのインスタンスを指定しますIReusableStackSynthesizer。そのメソッドは、アセットがスタックに追加されるたびに、またはスタックが合成されるたびに呼び出されます。スタック内でこのプロパティを使用する基本的な例を次に示します。

TypeScript
new MyStack(this, 'MyStack', { // stack properties synthesizer: new DefaultStackSynthesizer({ // synthesizer properties }), });
JavaScript
new MyStack(this, 'MyStack', { // stack properties synthesizer: new DefaultStackSynthesizer({ // synthesizer properties }), });
Python
MyStack(self, "MyStack", # stack properties synthesizer=DefaultStackSynthesizer( # synthesizer properties ))
Java

new MyStack(app, "MyStack", StackProps.builder() // stack properties .synthesizer(DefaultStackSynthesizer.Builder.create() // synthesizer properties .build()) .build();
C#
new MyStack(app, "MyStack", new StackProps // stack properties { Synthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps { // synthesizer properties }) });
Go
func main() { app := awscdk.NewApp(nil) NewMyStack(app, "MyStack", &MyStackProps{ StackProps: awscdk.StackProps{ Synthesizer: awscdk.NewDefaultStackSynthesizer(&awscdk.DefaultStackSynthesizerProps{ // synthesizer properties }), }, }) app.Synth(nil) }

App インスタンスの defaultStackSynthesizerプロパティを使用して、CDKアプリ内のすべてのCDKスタックにシンセサイザーを設定することもできます。

TypeScript

import { App, Stack, DefaultStackSynthesizer } from 'aws-cdk-lib'; const app = new App({ // Configure for all stacks in this app defaultStackSynthesizer: new DefaultStackSynthesizer({ /* ... */ }), });
JavaScript

const { App, Stack, DefaultStackSynthesizer } = require('aws-cdk-lib'); const app = new App({ // Configure for all stacks in this app defaultStackSynthesizer: new DefaultStackSynthesizer({ /* ... */ }), });
Python

from aws_cdk import App, Stack, DefaultStackSynthesizer app = App( default_stack_synthesizer=DefaultStackSynthesizer( # Configure for all stacks in this app # ... ) )
Java

import software.amazon.awscdk.App; import software.amazon.awscdk.Stack; import software.amazon.awscdk.DefaultStackSynthesizer; public class Main { public static void main(final String[] args) { App app = new App(AppProps.builder() // Configure for all stacks in this app .defaultStackSynthesizer(DefaultStackSynthesizer.Builder.create().build()) .build() ); } }
C#

using Amazon.CDK; using Amazon.CDK.Synthesizers; namespace MyNamespace { sealed class Program { public static void Main(string[] args) { var app = new App(new AppProps { // Configure for all stacks in this app DefaultStackSynthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps { // ... }) }); } } }
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(&awscdk.AppProps{ // Configure for all stacks in this app DefaultStackSynthesizer: awscdk.NewDefaultStackSynthesizer(&awscdk.DefaultStackSynthesizerProps{ // ... }), }) }

デフォルトでは、 は AWS CDK を使用しますDefaultStackSynthesizer。シンセサイザーを設定しない場合、このシンセサイザーが使用されます。

ブートストラップスタックやテンプレートに変更を加えるなど、ブートストラップを変更しない場合、スタック合成を変更する必要はありません。シンセサイザーを提供する必要すらありません。CDK は、デフォルトのDefaultStackSynthesizerクラスを使用して、ブートストラップCDKスタックと適切にやり取りするようにスタック合成を設定します。

CDK スタックを合成する方法

CDK スタックを合成するには、 AWS CDK コマンドラインインターフェイス (AWS CDK CLI) cdk synth コマンド。このコマンドで使用可能なオプションなど、このコマンドの詳細については、「」を参照してくださいcdk synthesize

CDK アプリケーションに 1 つのスタックが含まれている場合、またはすべてのスタックを合成する場合は、CDKスタック名を引数として指定する必要はありません。デフォルトでは、 CDKCLI はCDKスタックをテンプレートに AWS CloudFormation 合成します。各スタックのjsonフォーマットされたテンプレートが cdk.out ディレクトリに保存されます。アプリケーションに 1 yaml つのスタックが含まれている場合、フォーマットされたテンプレートが に出力されますstdout。以下に例を示します。

$ cdk synth Resources: CDKMetadata: Type: AWS::CDK::Metadata Properties: Analytics: v2:deflate64:H4sIAAAAAAAA/unique-identifier Metadata: aws:cdk:path: CdkAppStack/CDKMetadata/Default Condition: CDKMetadataAvailable ...

CDK アプリケーションに複数のスタックが含まれている場合は、スタックの論理 ID を指定して 1 つのスタックを合成できます。以下に例を示します。

$ cdk synth MyStackName

スタックを合成して を実行しない場合cdk deploy、 CDKCLI は、デプロイ前にスタックを自動的に合成します。

合成のデフォルトでの仕組み

AWS CloudFormation テンプレートIDsで生成された論理

CDK スタックを合成して CloudFormation テンプレートを生成すると、論理IDsは次のソースから生成され、次のようにフォーマットされます。<construct-path><construct-ID><unique-hash>:

  • コンストラクトパス – CDKアプリ内のコンストラクトへのパス全体。このパスは、常に Resourceまたは である L1 コンストラクトの ID とDefault、それが属する最上位スタックの ID を除外します。

  • コンストラクト ID – コンストラクトをインスタンス化するときに 2 番目の引数として指定する ID。

  • 一意のハッシュ – は、決定論的なハッシュアルゴリズムを使用して 8 文字の一意のハッシュ AWS CDK を生成します。この一意のハッシュは、テンプレート内の論理 ID 値が互いに一意であることを確認するのに役立ちます。このハッシュ生成の決定的な動作により、合成を実行するたびに、各コンストラクトに対して生成された論理 ID 値が同じままになります。ハッシュ値は、コンストラクトの ID やパスなどの特定のコンストラクト値を変更する場合にのみ変更されます。

論理的な最大長IDsは 255 文字です。したがって、 AWS CDK は、その制限内を維持するために必要に応じて、コンストラクトパスとコンストラクト ID を切り捨てます。

以下は、Amazon Simple Storage Service (Amazon S3) バケットを定義するコンストラクトの例です。ここでは、コンストラクトの ID myBucketとして を渡します。

TypeScript
import * as cdk from 'aws-cdk-lib'; import { Construct} from 'constructs'; import * as s3 from 'aws-cdk-lib/aws-s3'; export class MyCdkAppStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Define the S3 bucket new s3.Bucket(this, 'myBucket', { versioned: true, removalPolicy: cdk.RemovalPolicy.DESTROY, }); } }
JavaScript

const cdk = require('aws-cdk-lib'); const s3 = require('aws-cdk-lib/aws-s3'); class MyCdkAppStack extends cdk.Stack { constructor(scope, id, props) { super(scope, id, props); new s3.Bucket(this, 'myBucket', { versioned: true, removalPolicy: cdk.RemovalPolicy.DESTROY, }); } } module.exports = { MyCdkAppStack }
Python
import aws_cdk as cdk from constructs import Construct from aws_cdk import Stack from aws_cdk import aws_s3 as s3 class MyCdkAppStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) s3.Bucket(self, 'MyBucket', versioned=True, removal_policy=cdk.RemovalPolicy.DESTROY )
Java

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; import software.amazon.awscdk.services.s3.Bucket; import software.amazon.awscdk.services.s3.BucketProps; import software.amazon.awscdk.RemovalPolicy; public class MyCdkAppStack extends Stack { public MyCdkAppStack(final Construct scope, final String id) { this(scope, id, null); } public MyCdkAppStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); Bucket.Builder.create(this, "myBucket") .versioned(true) .removalPolicy(RemovalPolicy.DESTROY) .build(); } }
C#
using Amazon.CDK; using Constructs; using Amazon.CDK.AWS.S3; namespace MyCdkApp { public class MyCdkAppStack : Stack { public MyCdkAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { new Bucket(this, "myBucket", new BucketProps { Versioned = true, RemovalPolicy = RemovalPolicy.DESTROY }); } } }
Go
package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/aws-cdk-go/awscdk/v2/awss3" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" ) type MyCdkAppStackProps struct { awscdk.StackProps } func NewMyCdkAppStack(scope constructs.Construct, id string, props *MyCdkAppStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) awss3.NewBucket(stack, jsii.String("myBucket"), &awss3.BucketProps{ Versioned: jsii.Bool(true), RemovalPolicy: awscdk.RemovalPolicy_DESTROY, }) return stack } // ...

を実行するとcdk synth、 形式の論理 ID myBucketunique-hashが生成されます。生成された AWS CloudFormation テンプレートのこのリソースの例を次に示します。

Resources: myBucket5AF9C99B: Type: AWS::S3::Bucket Properties: VersioningConfiguration: Status: Enabled UpdateReplacePolicy: Delete DeletionPolicy: Delete Metadata: aws:cdk:path: S3BucketAppStack/myBucket/Resource

以下は、Amazon S3 バケットを定義する Barという名前のカスタムコンストラクトの例です。Bar コンストラクトには、パスFooにカスタムコンストラクトが含まれます。

TypeScript

import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import * as s3 from 'aws-cdk-lib/aws-s3'; // Define the Bar construct export class Bar extends Construct { constructor(scope: Construct, id: string) { super(scope, id); // Define an S3 bucket inside of Bar new s3.Bucket(this, 'Bucket', { versioned: true, removalPolicy: cdk.RemovalPolicy.DESTROY, } ); } } // Define the Foo construct export class Foo extends Construct { constructor(scope: Construct, id: string) { super(scope, id); // Create an instance of Bar inside Foo new Bar(this, 'Bar'); } } // Define the CDK stack export class MyCustomAppStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Instantiate Foo construct in the stack new Foo(this, 'Foo'); } }
JavaScript

const cdk = require('aws-cdk-lib'); const s3 = require('aws-cdk-lib/aws-s3'); const { Construct } = require('constructs'); // Define the Bar construct class Bar extends Construct { constructor(scope, id) { super(scope, id); // Define an S3 bucket inside of Bar new s3.Bucket(this, 'Bucket', { versioned: true, removalPolicy: cdk.RemovalPolicy.DESTROY, }); } } // Define the Foo construct class Foo extends Construct { constructor(scope, id) { super(scope, id); // Create an instance of Bar inside Foo new Bar(this, 'Bar'); } } // Define the CDK stack class MyCustomAppStack extends cdk.Stack { constructor(scope, id, props) { super(scope, id, props); // Instantiate Foo construct in the stack new Foo(this, 'Foo'); } } module.exports = { MyCustomAppStack }
Python

import aws_cdk as cdk from constructs import Construct from aws_cdk import ( Stack, aws_s3 as s3, RemovalPolicy, ) # Define the Bar construct class Bar(Construct): def __init__(self, scope: Construct, id: str) -> None: super().__init__(scope, id) # Define an S3 bucket inside of Bar s3.Bucket(self, 'Bucket', versioned=True, removal_policy=RemovalPolicy.DESTROY ) # Define the Foo construct class Foo(Construct): def __init__(self, scope: Construct, id: str) -> None: super().__init__(scope, id) # Create an instance of Bar inside Foo Bar(self, 'Bar') # Define the CDK stack class MyCustomAppStack(Stack): def __init__(self, scope: Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # Instantiate Foo construct in the stack Foo(self, 'Foo')
Java

Eclipse my-custom-app/src/main/java/com/myorg/Bar.java:

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.services.s3.Bucket; import software.amazon.awscdk.services.s3.BucketProps; import software.amazon.awscdk.RemovalPolicy; public class Bar extends Construct { public Bar(final Construct scope, final String id) { super(scope, id); // Define an S3 bucket inside Bar Bucket.Builder.create(this, "Bucket") .versioned(true) .removalPolicy(RemovalPolicy.DESTROY) .build(); } }

Eclipse my-custom-app/src/main/java/com/myorg/Foo.java:

package com.myorg; import software.constructs.Construct; public class Foo extends Construct { public Foo(final Construct scope, final String id) { super(scope, id); // Create an instance of Bar inside Foo new Bar(this, "Bar"); } }

Eclipse my-custom-app/src/main/java/com/myorg/MyCustomAppStack.java:

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; public class MyCustomAppStack extends Stack { public MyCustomAppStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); // Instantiate Foo construct in the stack new Foo(this, "Foo"); } // Overload constructor in case StackProps is not provided public MyCustomAppStack(final Construct scope, final String id) { this(scope, id, null); } }
C#
using Amazon.CDK; using Constructs; using Amazon.CDK.AWS.S3; namespace MyCustomApp { // Define the Bar construct public class Bar : Construct { public Bar(Construct scope, string id) : base(scope, id) { // Define an S3 bucket inside Bar new Bucket(this, "Bucket", new BucketProps { Versioned = true, RemovalPolicy = RemovalPolicy.DESTROY }); } } // Define the Foo construct public class Foo : Construct { public Foo(Construct scope, string id) : base(scope, id) { // Create an instance of Bar inside Foo new Bar(this, "Bar"); } } // Define the CDK Stack public class MyCustomAppStack : Stack { public MyCustomAppStack(Construct scope, string id, StackProps props = null) : base(scope, id, props) { // Instantiate Foo construct in the stack new Foo(this, "Foo"); } } }
Go

package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/aws-cdk-go/awscdk/v2/awss3" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" ) // Define the Bar construct type Bar struct { constructs.Construct } func NewBar(scope constructs.Construct, id string) constructs.Construct { bar := constructs.NewConstruct(scope, &id) // Define an S3 bucket inside Bar awss3.NewBucket(bar, jsii.String("Bucket"), &awss3.BucketProps{ Versioned: jsii.Bool(true), RemovalPolicy: awscdk.RemovalPolicy_DESTROY, }) return bar } // Define the Foo construct type Foo struct { constructs.Construct } func NewFoo(scope constructs.Construct, id string) constructs.Construct { foo := constructs.NewConstruct(scope, &id) // Create an instance of Bar inside Foo NewBar(foo, "Bar") return foo } // Define the CDK Stack type MyCustomAppStackProps struct { awscdk.StackProps } func NewMyCustomAppStack(scope constructs.Construct, id string, props *MyCustomAppStackProps) awscdk.Stack { stack := awscdk.NewStack(scope, &id, &props.StackProps) // Instantiate Foo construct in the stack NewFoo(stack, "Foo") return stack } // Define the CDK App func main() { app := awscdk.NewApp(nil) NewMyCustomAppStack(app, "MyCustomAppStack", &MyCustomAppStackProps{ StackProps: awscdk.StackProps{}, }) app.Synth(nil) }

を実行するとcdk synth、 形式の論理 ID FooBarBucketunique-hashが生成されます。生成された AWS CloudFormation テンプレートのこのリソースの例を次に示します。

Resources: FooBarBucketBA3ED1FA: Type: AWS::S3::Bucket Properties: VersioningConfiguration: Status: Enabled UpdateReplacePolicy: Delete DeletionPolicy: Delete # ...

CDK スタック合成をカスタマイズする

デフォルトのCDK合成動作がニーズに合わない場合は、CDK合成をカスタマイズできます。これを行うには、 を変更するDefaultStackSynthesizerか、他の使用可能な組み込みシンセサイザーを使用するか、独自のシンセサイザーを作成します。手順については、CDK スタック合成をカスタマイズする を参照してください。