

這是 AWS CDK v2 開發人員指南。較舊的 CDK v1 已於 2022 年 6 月 1 日進入維護，並於 2023 年 6 月 1 日結束支援。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 設定和執行 CDK 堆疊合成
<a name="configure-synth"></a>

您必須先合成 AWS 雲端開發套件 (AWS CDK) 堆疊，才能部署該堆疊。*堆疊合成*是從 CDK 堆疊產生 AWS CloudFormation 範本和部署成品的程序。範本和成品稱為*雲端組件*。雲端組件是部署用來佈建資源的項目 AWS。如需部署如何運作的詳細資訊，請參閱 [AWS CDK 部署如何運作](deploy.md#deploy-how)。

## 合成和引導如何一起運作
<a name="configure-synth-bootstrap"></a>

若要讓您的 CDK 應用程式正確部署，合成期間產生的 CloudFormation 範本必須正確指定在引導期間建立的資源。因此，引導和合成必須互相補充，才能成功部署：
+ 引導是設定 AWS CDK 部署 AWS 環境的一次性程序。它會在您的環境中設定 CDK 用於部署的特定 AWS 資源。這些通常稱為*引導資源*。如需引導的指示，請參閱[引導您的環境以搭配 AWS CDK 使用](bootstrapping-env.md)。
+ 合成期間產生的 CloudFormation 範本包含要使用哪些引導資源的資訊。在合成期間，CDK CLI 不知道如何引導您的 AWS 環境。反之，CDK CLI 會根據您為每個 CDK 堆疊設定的合成器產生 CloudFormation 範本。若要讓部署成功，合成器必須產生 CloudFormation 範本，參考要使用的正確引導資源。

CDK 隨附預設合成器和引導組態，旨在共同運作。如果您自訂一個，則必須將相關的自訂套用至另一個。

## 如何設定 CDK 堆疊合成
<a name="bootstrapping-synthesizers"></a>

您可以使用[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html)執行個體的 `synthesizer` 屬性來設定 CDK 堆疊合成。此屬性指定 CDK 堆疊的合成方式。您提供實作 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.IStackSynthesizer.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.IStackSynthesizer.html)或 的 類別執行個體[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.IReusableStackSynthesizer.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.IReusableStackSynthesizer.html)。每次將資產新增至堆疊或合成堆疊時，都會叫用其方法。以下是在堆疊中使用此屬性的基本範例：

**Example**  

```
new MyStack(this, 'MyStack', {
  // stack properties
  synthesizer: new DefaultStackSynthesizer({
    // synthesizer properties
  }),
});
```

```
new MyStack(this, 'MyStack', {
  // stack properties
  synthesizer: new DefaultStackSynthesizer({
    // synthesizer properties
  }),
});
```

```
MyStack(self, "MyStack",
    # stack properties
    synthesizer=DefaultStackSynthesizer(
        # synthesizer properties
))
```

```
new MyStack(app, "MyStack", StackProps.builder()
  // stack properties
  .synthesizer(DefaultStackSynthesizer.Builder.create()
    // synthesizer properties
    .build())
  .build();
)
```

```
new MyStack(app, "MyStack", new StackProps
// stack properties
{
    Synthesizer = new DefaultStackSynthesizer(new DefaultStackSynthesizerProps
    {
        // synthesizer properties
    })
});
```

```
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 堆疊設定合成器：

**Example**  

```
import { App, Stack, DefaultStackSynthesizer } from 'aws-cdk-lib';

const app = new App({
  // Configure for all stacks in this app
  defaultStackSynthesizer: new DefaultStackSynthesizer({
    /* ... */
  }),
});
```

```
const { App, Stack, DefaultStackSynthesizer } = require('aws-cdk-lib');

const app = new App({
  // Configure for all stacks in this app
  defaultStackSynthesizer: new DefaultStackSynthesizer({
    /* ... */
  }),
});
```

```
from aws_cdk import App, Stack, DefaultStackSynthesizer

app = App(
    default_stack_synthesizer=DefaultStackSynthesizer(
        # Configure for all stacks in this app
        # ...
    )
)
```

```
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()
        );
    }
}
```

```
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
                {
                    // ...
                })
            });
        }
    }
}
```

```
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](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.DefaultStackSynthesizer.html) `。如果您未設定合成器，則會使用此合成器。

如果您不修改引導，例如變更引導堆疊或範本，則不需要修改堆疊合成。您甚至不需要提供合成器。CDK 將使用預設`DefaultStackSynthesizer`類別來設定 CDK 堆疊合成，以正確與您的引導堆疊互動。

## 如何合成 CDK 堆疊
<a name="configure-synth-stack"></a>

若要合成 CDK 堆疊，請使用 AWS CDK 命令列界面 (AWS CDK CLI) `cdk synth`命令。如需此命令的詳細資訊，包括可搭配此命令使用的選項，請參閱 [cdk 合成](ref-cli-cmd-synth.md)。

如果您的 CDK 應用程式包含單一堆疊，或要合成所有堆疊，您不需要提供 CDK 堆疊名稱做為引數。根據預設，CDK CLI 會將您的 CDK 堆疊合成為 AWS CloudFormation 範本。每個堆疊的`json`格式化範本會儲存至 `cdk.out`目錄。如果您的應用程式包含單一堆疊，`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 來合成單一堆疊。以下是範例：

```
$ cdk synth MyStackName
```

如果您不合成堆疊並執行 `cdk deploy`，CDK CLI 會在部署之前自動合成您的堆疊。

## 預設合成的運作方式
<a name="how-synth-default"></a><a name="how-synth-default-logical-ids"></a>

 **在您的 AWS CloudFormation 範本中產生的邏輯 IDs **   
當您合成 CDK 堆疊以產生 CloudFormation 範本時，會從下列來源產生邏輯 IDs，格式為 `construct-pathconstruct-IDunique-hash`：  
+  **建構路徑** – CDK 應用程式中建構的整個路徑。此路徑會排除 L1 建構的 ID，一律為 `Resource`或 `Default`，以及其所屬頂層堆疊的 ID。
+  **建構 ID** – 您在執行個體化建構時作為第二個引數提供的 ID。
+  **唯一雜湊** – AWS CDK 使用確定性雜湊演算法產生 8 個字元的唯一雜湊。此唯一雜湊有助於確保範本中的邏輯 ID 值彼此是唯一的。此雜湊產生的決定性行為可確保每次執行合成時，每個建構產生的邏輯 ID 值都保持不變。只有在您修改特定建構值，例如建構的 ID 或其路徑時，雜湊值才會變更。

  邏輯 IDs的長度上限為 255 個字元。因此， AWS CDK 將截斷建構路徑，並在必要時建構 ID，以保持在該限制內。

  以下是定義 Amazon Simple Storage Service (Amazon S3) 儲存貯體的建構範例。在這裡，我們會傳遞 `myBucket`做為建構的 ID：  
**Example**  

------
#### [ 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`，`myBucketunique-hash`會產生格式為 的邏輯 ID。以下是 generated AWS CloudFormation 範本中此資源的範例：

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

  以下是名為 的自訂建構範例`Bar`，可定義 Amazon S3 儲存貯體。`Bar` 建構包含其路徑`Foo`中的自訂建構：  
**Example**  

------
#### [ 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 ]

  在 `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();
      }
  }
  ```

  在 `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");
      }
  }
  ```

  在 `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`，`FooBarBucketunique-hash`會產生格式為 的邏輯 ID。以下是 generated AWS CloudFormation 範本中此資源的範例：

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

## 自訂 CDK 堆疊合成
<a name="bootstrapping-custom-synth"></a>

如果預設 CDK 合成行為不符合您的需求，您可以自訂 CDK 合成。若要這樣做，您可以修改 `DefaultStackSynthesizer`、使用其他可用的內建合成器，或建立您自己的合成器。如需說明，請參閱[自訂 CDK 堆疊合成](customize-synth.md)。