

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

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

# AWS CDK の主要な概念を学ぶ
<a name="core-concepts"></a>

 AWS Cloud Development Kit (AWS CDK) の主な概念について説明します。

## AWS CDK と IaC
<a name="concepts-iac"></a>

 AWS CDK は、コードを使用して AWS インフラストラクチャを管理するために使用できるオープンソースフレームワークです。このアプローチは、*Infrastructure as Code (IaC)* と呼ばれます。インフラストラクチャをコードとして管理およびプロビジョニングすることで、開発者がコードを処理するのと同じ方法でインフラストラクチャを処理します。これにより、バージョン管理やスケーラビリティなど、多くの利点が得られます。IaC の詳細については、[「Infrastructure as Code とは」](https://aws.amazon.com/what-is/iac/)を参照してください。

## AWS CDK と AWS CloudFormation
<a name="concepts-cfn"></a>

 AWS CDK は AWS CloudFormation と緊密に統合されています。 AWS CloudFormation は、インフラストラクチャの管理とプロビジョニングに使用できるフルマネージドサービスです AWS。 AWS CloudFormation では、 テンプレートでインフラストラクチャを定義し、 AWS CloudFormation にデプロイします。その後、 AWS CloudFormation サービスは、テンプレートで定義された設定に従ってインフラストラクチャをプロビジョニングします。

 AWS CloudFormation テンプレートは*宣言型*です。つまり、インフラストラクチャの望ましい状態または結果を宣言します。JSON または YAML を使用して、*リソース*と*プロパティ*を定義して AWS インフラストラクチャを AWS 宣言します。リソースは の多くのサービスを表 AWS し、プロパティはそれらのサービスの必要な設定を表します。テンプレートを AWS CloudFormation にデプロイすると、リソースとその設定済みプロパティがテンプレートの説明に従ってプロビジョニングされます。

 AWS CDK を使用すると、汎用プログラミング言語を使用してインフラストラクチャを*厳密に*管理できます。目的の状態を宣言的に定義する代わりに、目的の状態に達するために必要なロジックまたはシーケンスを定義できます。たとえば、`if` ステートメントまたは条件ループを使用して、インフラストラクチャの希望する終了状態に到達する方法を決定できます。

 AWS CDK で作成されたインフラストラクチャは、最終的に変換されるか、 AWS CloudFormation テンプレートに*合成*され、 AWS CloudFormation サービスを使用してデプロイされます。したがって、 AWS CDK はインフラストラクチャの作成に異なるアプローチを提供しますが、 AWS リソース設定の広範なサポートや堅牢なデプロイプロセスなど、 AWS CloudFormation の利点を引き続き享受できます。

 AWS CloudFormation の詳細については、[AWS CloudFormation とは」を参照してください。](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html) * AWS CloudFormation ユーザーガイド*」の「」を参照してください。

## AWS CDK と抽象化
<a name="concepts-abstractions"></a>

 AWS CloudFormation では、リソースの設定方法の詳細をすべて定義する必要があります。これにより、インフラストラクチャを完全に制御できます。ただし、そのためには、リソース設定の詳細と、アクセス許可やイベント駆動型のインタラクションなどのリソース間の関係を含む堅牢なテンプレートを学習、理解、作成する必要があります。

 AWS CDK を使用すると、リソース設定を同じように制御できます。ただし、 AWS CDK は強力な抽象化も提供するため、インフラストラクチャ開発プロセスを高速化して簡素化できます。たとえば、 AWS CDK には、適切なデフォルト設定を提供するコンストラクトと、定型コードを生成するヘルパーメソッドが含まれています。 AWS CDK には、インフラストラクチャ管理アクションを実行する AWS CDK コマンドラインインターフェイス (AWS CDK CLI) などのツールも用意されています。

## コア AWS CDK の概念の詳細
<a name="concepts-learn"></a><a name="concepts-learn-interact"></a>

 ** AWS CDK の操作**   
 AWS CDK で を使用する場合、主に AWS コンストラクトライブラリと AWS CDK CLI を操作します。<a name="concepts-learn-develop"></a>

 ** AWS CDK を使用した開発**   
 AWS CDK は、[サポートされている任意のプログラミング言語で](languages.md)記述できます。まず、[アセット](assets.md)を含むフォルダとファイルの構造を含む [CDK プロジェクト](projects.md)から始めます。プロジェクト内で、[CDK アプリケーション](apps.md)を作成します。アプリケーション内では[スタック](stacks.md)を定義します。これは CloudFormation スタックを直接表すものです。スタック内では、 [コンストラクト](constructs.md)を使用して AWS リソースとプロパティを定義します。<a name="concepts-learn-deploy"></a>

 ** AWS CDK を使用したデプロイ**   
CDK アプリケーションを AWS [環境](environments.md)にデプロイします。デプロイする前に、環境を準備するための[ブートストラップ](bootstrapping.md)を 1 回だけ実行する必要があります。<a name="concepts-learn-more"></a>

 **詳細はこちら**   
 AWS CDK の主要概念の詳細については、このセクションのトピックを参照してください。

# AWS CDK のサポートされているプログラミング言語
<a name="languages"></a>

AWS Cloud Development Kit (AWS CDK) には、次の汎用プログラミング言語に対するファーストクラスサポートがあります。
+ TypeScript
+ JavaScript
+ Python (パイソン)
+ Java
+ C\$1
+  Go 

その他の JVM や .NET CLR 言語も理論上使用できますが、現時点では公式なサポートを提供していません。

AWS CDK は TypeScript という 1 つの言語で開発されています。他の言語をサポートするため、AWS CDK は [JSII](https://github.com/aws/jsii) と呼ばれるツールを活用して言語バインディングを生成します。

AWS CDK を使用した開発ができるだけ自然で直感的にするため、各言語の通常の規則を提供することに取り組んでいます。例えば、任意の言語の標準リポジトリを使用して AWS コンストラクトライブラリモジュールを配布し、ユーザーは言語の標準パッケージマネージャーを使用してインストールします。メソッドおよびプロパティも、言語の推奨命名パターンを使用して名前が付けられます。

次の内容は、いくつかのコード例です。

**Example**  

```
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', {
  bucketName: 'amzn-s3-demo-bucket',
  versioned: true,
  websiteRedirect: {hostName: 'aws.amazon.com'}});
```

```
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', {
  bucketName: 'amzn-s3-demo-bucket',
  versioned: true,
  websiteRedirect: {hostName: 'aws.amazon.com'}});
```

```
bucket = s3.Bucket("amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket", versioned=True,
            website_redirect=s3.RedirectTarget(host_name="aws.amazon.com"))
```

```
Bucket bucket = Bucket.Builder.create(self, "amzn-s3-demo-bucket")
                      .bucketName("amzn-s3-demo-bucket")
                      .versioned(true)
                      .websiteRedirect(new RedirectTarget.Builder()
                          .hostName("aws.amazon.com").build())
                      .build();
```

```
var bucket = new Bucket(this, "amzn-s3-demo-bucket", new BucketProps {
                      BucketName = "amzn-s3-demo-bucket",
                      Versioned  = true,
                      WebsiteRedirect = new RedirectTarget {
                              HostName = "aws.amazon.com"
                      }});
```

```
bucket := awss3.NewBucket(scope, jsii.String("amzn-s3-demo-bucket"), &awss3.BucketProps {
	BucketName: jsii.String("amzn-s3-demo-bucket"),
	Versioned: jsii.Bool(true),
	WebsiteRedirect: &awss3.RedirectTarget {
		HostName: jsii.String("aws.amazon.com"),
	},
})
```

**注記**  
これらのコードスニペットは、あくまでも説明用に使用されています。不完全なため、そのままでは実行されません。

AWS コンストラクトライブラリは、NPM、PyPi、Maven、NuGet などの各言語の標準パッケージ管理ツールを使用して配布されます。各言語の「[AWS CDK API リファレンス](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html)」のバージョンも提供します。

このガイドでは、AWS CDK を任意の言語で使用できるように、サポートされている言語に関する次のトピックについて説明します。
+  [TypeScript で AWS CDK を使用する](work-with-cdk-typescript.md) 
+  [JavaScript で AWS CDK を使用する](work-with-cdk-javascript.md) 
+  [Python で AWS CDK を使用する](work-with-cdk-python.md) 
+  [Java で AWS CDK を使用する](work-with-cdk-java.md) 
+  [C\$1 で AWS CDK を操作](work-with-cdk-csharp.md) 
+  [Go で AWS CDK を操作](work-with-cdk-go.md) 

TypeScript は AWS CDK でサポートされている最初の言語であり、AWS CDK のコード例の多くは TypeScript で記述されています。このガイドには、サポートされている他の言語で TypeScript AWS CDK コードを使用するため、適応させる方法に特化したトピックが含まれています。詳細については、「[TypeScript の AWS CDK を他の言語と比較](work-with.md#work-with-cdk-compare)」を参照してください。

# AWS CDK ライブラリ
<a name="libraries"></a>

AWS Cloud Development Kit (AWS CDK) で使用するコアライブラリについて説明します。

## AWS CDK ライブラリ
<a name="libraries-cdk"></a>

AWS CDK ライブラリは `aws-cdk-lib` とも呼ばれ、AWS CDK を使用してアプリケーションを開発するために使用するメインライブラリです。AWS によって開発および維持されています。このライブラリには、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html) や [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) などのベースクラスが含まれています。コンストラクトを通じてインフラストラクチャを定義するために使用するライブラリも含まれています。

## AWS コンストラクトライブラリ
<a name="libraries-construct"></a>

AWS コンストラクトライブラリは AWS CDK ライブラリの一部です。AWS によって開発および維持されている[コンストラクト](constructs.md)のコレクションが含まれています。AWS のサービスごとにさまざまなモジュールに整理されています。各モジュールには、AWS リソースおよびプロパティの定義に使用できるコンストラクトが含まれています。

## コンストラクトライブラリ
<a name="libraries-constructs"></a>

コンストラクトライブラリは一般的に `constructs` と呼ばれ、クラウドインフラストラクチャコンポーネントを定義して作成するためのライブラリです。コンストラクトの構築ブロックを表すコア [https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html) クラスが含まれます。このクラスは、AWS コンストラクトライブラリからすべてのコンストラクトの基本ベースクラスです。コンストラクトライブラリは、*CDK for Terraform* や *CDK for Kubernetes* など、他のコンストラクトベースのツールで使用される別の汎用ライブラリです。

## AWS CDK API リファレンス
<a name="libraries-reference"></a>

「[AWS CDK API リファレンス](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html)」には、AWS コンストラクトライブラリおよびコンストラクトライブラリなど、AWS CDK ライブラリの公式リファレンスドキュメントが含まれています。API リファレンスのバージョンは、サポートされている各プログラミング言語に提供されます。
+ AWS CDK ライブラリ (`aws-cdk-lib`) のドキュメントについては、「[aws-cdk-lib モジュール](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib-readme.html)」を参照してください。
+ AWS コンストラクトライブラリのコンストラクトのドキュメントは、AWS のサービスによって `aws-cdk-lib.<service>` の形式で整理されています。例えば、Amazon Simple Storage Service (Amazon S3) のコンストラクトドキュメントは、「[aws-cdk-lib.aws\$1s3 モジュール](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3-readme.html)」にあります。
+ コンストラクトライブラリ (コンストラクト) のドキュメントについては、「[コンストラクトモジュール](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs-readme.html)」を参照してください。

### AWS CDK API リファレンスに貢献
<a name="libraries-reference-contribute"></a>

AWS CDK はオープンソースであり、ぜひご貢献をお待ちしています。コミュニティの貢献は良い影響をもたらして AWS CDK を改善します。特に AWS CDK API リファレンスのドキュメントに貢献するための手順については、「*aws-cdk GitHub リポジトリ*」の「[ドキュメント](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md#documentation)」を参照してください。

## 詳細
<a name="libraries-learn"></a>

インポートおよび CDK ライブラリを使用する手順については、「[CDK ライブラリを使用する](work-with.md)」を参照してください。

# AWS CDK プロジェクト
<a name="projects"></a>

AWS Cloud Development Kit (AWS CDK) プロジェクトは、CDK コードを含むファイルおよびフォルダを表します。内容はプログラミング言語によって異なります。

AWS CDK プロジェクトは手動で作成するか、AWS CDK コマンドラインインターフェイス (AWS CDK CLI) `cdk init` コマンドを使用して作成することができます。このトピックでは、AWS CDK CLI によって作成されたファイルおよびフォルダのプロジェクト構造および命名規則について説明します。ニーズに合わせて CDK プロジェクトをカスタマイズおよび整理できます。

**注記**  
AWS CDK CLI によって作成されたプロジェクト構造は、時間の経過とともにバージョンによって異なる場合があります。

## ユニバーサルファイルとフォルダ
<a name="projects-universal"></a><a name="projects-universal-git"></a>

 `.git`   
`git` がインストールされている場合、AWS CDK CLI はプロジェクトの Git リポジトリを自動的に初期化します。`.git` ディレクトリには、リポジトリに関する情報が含まれています。<a name="projects-universal-gitignore"></a>

 `.gitignore`   
無視するファイルおよびフォルダを指定するため、Git によって使用されるテキストファイル。<a name="projects-universal-readme"></a>

 `README.md`   
AWS CDK プロジェクトを管理するため、基本的なガイダンスおよび重要な情報を提供するテキストファイル。必要に応じてこのファイルを変更し、CDK プロジェクトに関する重要な情報を文書化します。<a name="projects-universal-cdk"></a>

 `cdk.json`   
AWS CDK の設定ファイル。このファイルは、アプリの実行方法に関する AWS CDK CLI への指示を提供します。

## 言語固有のファイルとフォルダ
<a name="projects-specific"></a>

次のファイルおよびフォルダは、サポートされているプログラミング言語ごとに一意です。

**Example**  
次の内容は、`cdk init --language typescript` コマンドを使用して `my-cdk-ts-project` ディレクトリで作成されたプロジェクトの例です。  

```
my-cdk-ts-project
├── .git
├── .gitignore
├── .npmignore
├── README.md
├── bin
│   └── my-cdk-ts-project.ts
├── cdk.json
├── jest.config.js
├── lib
│   └── my-cdk-ts-project-stack.ts
├── node_modules
├── package-lock.json
├── package.json
├── test
│   └── my-cdk-ts-project.test.ts
└── tsconfig.json
```  
 `.npmignore`   
パッケージを `npm` レジストリに発行するときに無視するファイルおよびフォルダを指定するファイル。このファイルは `.gitignore` に似ていますが、`npm` パッケージに特化しています。  
 `bin/my-cdk-ts-project.ts`   
*アプリケーションファイル*は CDK アプリを定義します。CDK プロジェクトには、1 つ以上のアプリケーションファイルを含めることができます。アプリケーションファイルは `bin` フォルダに保存されます。  
次の内容は、CDK アプリを定義する基本的なアプリケーションファイルの例です。  

```
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { MyCdkTsProjectStack } from '../lib/my-cdk-ts-project-stack';

const app = new cdk.App();
new MyCdkTsProjectStack(app, 'MyCdkTsProjectStack');
```  
 `jest.config.js`   
Jest の設定ファイル。*Jest* は、一般的な JavaScript テストフレームワークです。  
 `lib/my-cdk-ts-project-stack.ts`   
*スタックファイル*は CDK スタックを定義します。スタック内では、コンストラクトを使用して AWS リソースおよびプロパティを定義します。  
次の内容は、CDK スタックを定義する基本的なスタックファイルの例です。  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

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

  // code that defines your resources and properties go here
 }
}
```  
 `node_modules`   
プロジェクトの依存関係を含む Node.js プロジェクト内の共通フォルダ。  
 `package-lock.json`   
`package.json` ファイルと連携して依存関係のバージョンを管理するメタデータファイル。  
 `package.json`   
Node.js プロジェクトで一般的に使用されるメタデータファイル。このファイルには、プロジェクト名、スクリプト定義、依存関係、その他のインポートプロジェクトレベルの情報など、CDK プロジェクトに関する情報が含まれています。  
 `test/my-cdk-ts-project.test.ts`   
CDK プロジェクトのテストを整理するため、テストフォルダが作成されます。サンプルテストファイルも作成されます。  
テストを実行する前に TypeScript にテストを記述し、Jest を使用して TypeScript コードをコンパイルできます。  
 `tsconfig.json`   
コンパイラオプションおよびプロジェクト設定を指定する TypeScript プロジェクトで使用される設定ファイル。
次の内容は、`cdk init --language javascript` コマンドを使用して `my-cdk-js-project` ディレクトリで作成されたプロジェクトの例です。  

```
my-cdk-js-project
├── .git
├── .gitignore
├── .npmignore
├── README.md
├── bin
│   └── my-cdk-js-project.js
├── cdk.json
├── jest.config.js
├── lib
│   └── my-cdk-js-project-stack.js
├── node_modules
├── package-lock.json
├── package.json
└── test
    └── my-cdk-js-project.test.js
```  
 `.npmignore`   
パッケージを `npm` レジストリに発行するときに無視するファイルおよびフォルダを指定するファイル。このファイルは `.gitignore` に似ていますが、`npm` パッケージに特化しています。  
 `bin/my-cdk-js-project.js`   
*アプリケーションファイル*は CDK アプリを定義します。CDK プロジェクトには、1 つ以上のアプリケーションファイルを含めることができます。アプリケーションファイルは `bin` フォルダに保存されます。  
次の内容は、CDK アプリを定義する基本的なアプリケーションファイルの例です。  

```
#!/usr/bin/env node

const cdk = require('aws-cdk-lib');
const { MyCdkJsProjectStack } = require('../lib/my-cdk-js-project-stack');

const app = new cdk.App();
new MyCdkJsProjectStack(app, 'MyCdkJsProjectStack');
```  
 `jest.config.js`   
Jest の設定ファイル。*Jest* は、一般的な JavaScript テストフレームワークです。  
 `lib/my-cdk-js-project-stack.js`   
*スタックファイル*は CDK スタックを定義します。スタック内では、コンストラクトを使用して AWS リソースおよびプロパティを定義します。  
次の内容は、CDK スタックを定義する基本的なスタックファイルの例です。  

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

class MyCdkJsProjectStack extends Stack {
 constructor(scope, id, props) {
  super(scope, id, props);

  // code that defines your resources and properties go here
 }
}

module.exports = { MyCdkJsProjectStack }
```  
 `node_modules`   
プロジェクトの依存関係を含む Node.js プロジェクト内の共通フォルダ。  
 `package-lock.json`   
`package.json` ファイルと連携して依存関係のバージョンを管理するメタデータファイル。  
 `package.json`   
Node.js プロジェクトで一般的に使用されるメタデータファイル。このファイルには、プロジェクト名、スクリプト定義、依存関係、その他のインポートプロジェクトレベルの情報など、CDK プロジェクトに関する情報が含まれています。  
 `test/my-cdk-js-project.test.js`   
CDK プロジェクトのテストを整理するため、テストフォルダが作成されます。サンプルテストファイルも作成されます。  
テストを実行する前に JavaScript にテストを記述し、Jest を使用して JavaScript コードをコンパイルできます。
次の内容は、`cdk init --language python` コマンドを使用して `my-cdk-py-project` ディレクトリで作成されたプロジェクトの例です。  

```
my-cdk-py-project
├── .git
├── .gitignore
├── .venv
├── README.md
├── app.py
├── cdk.json
├── my_cdk_py_project
│   ├── __init__.py
│   └── my_cdk_py_project_stack.py
├── requirements-dev.txt
├── requirements.txt
├── source.bat
└── tests
    ├── __init__.py
    └── unit
```  
 `.venv`   
CDK CLI は、プロジェクトの仮想環境を自動的に作成します。`.venv` ディレクトリはこの仮想環境を参照します。  
 `app.py`   
*アプリケーションファイル*は CDK アプリを定義します。CDK プロジェクトには、1 つ以上のアプリケーションファイルを含めることができます。  
次の内容は、CDK アプリを定義する基本的なアプリケーションファイルの例です。  

```
#!/usr/bin/env python3
import os

import aws_cdk as cdk

from my_cdk_py_project.my_cdk_py_project_stack import MyCdkPyProjectStack

app = cdk.App()
MyCdkPyProjectStack(app, "MyCdkPyProjectStack")

app.synth()
```  
 `my_cdk_py_project`   
スタックファイルが含まれまる*スタックファイル*。CDK CLI はこちらで次のものを作成します。  
+ \$1\$1init\$1\$1.py – 空の Python パッケージ定義ファイル。
+  `my_cdk_py_project` – CDK スタックを定義するファイル。次に、コンストラクトを使用してスタック内の AWS リソースおよびプロパティを定義します。
次の内容はスタックファイルの例です。  

```
from aws_cdk import Stack

from constructs import Construct

class MyCdkPyProjectStack(Stack):
 def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
  super().__init__(scope, construct_id, **kwargs)

  # code that defines your resources and properties go here
```  
 `requirements-dev.txt`   
`requirements.txt` に似ていますが、本番ではなくて開発目的専用に依存関係を管理するために使用されます。  
 `requirements.txt`   
プロジェクトの依存関係を指定および管理するため、Python プロジェクトで使用される一般的なファイル。  
 `source.bat`   
Python 仮想環境のセットアップに使用される Windows のバッチファイル。  
 `tests`   
CDK プロジェクト用のテストを含むディレクトリ。  
次の内容はユニットテストの例です。  

```
import aws_cdk as core
import aws_cdk.assertions as assertions

from my_cdk_py_project.my_cdk_py_project_stack import MyCdkPyProjectStack

def test_sqs_queue_created():
 app = core.App()
 stack = MyCdkPyProjectStack(app, "my-cdk-py-project")
 template = assertions.Template.from_stack(stack)

 template.has_resource_properties("AWS::SQS::Queue", {
  "VisibilityTimeout": 300
 })
```
次の内容は、`cdk init --language java` コマンドを使用して `my-cdk-java-project` ディレクトリで作成されたプロジェクトの例です。  

```
my-cdk-java-project
├── .git
├── .gitignore
├── README.md
├── cdk.json
├── pom.xml
└── src
    ├── main
    └── test
```  
 `pom.xml`   
CDK プロジェクトに関する設定情報とメタデータを含むファイル。このファイルは Maven の一部です。  
 `src/main`   
*アプリケーション*および*スタック*ファイルを含むディレクトリ。  
次の内容は、アプリケーションファイルの例です。  

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.StackProps;

import java.util.Arrays;

public class MyCdkJavaProjectApp {
 public static void main(final String[] args) {
  App app = new App();

  new MyCdkJavaProjectStack(app, "MyCdkJavaProjectStack", StackProps.builder()
   .build());

  app.synth();
 }
}
```
次の内容は、スタックファイルの例です。  

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;

public class MyCdkJavaProjectStack extends Stack {
 public MyCdkJavaProjectStack(final Construct scope, final String id) {
  this(scope, id, null);
 }

 public MyCdkJavaProjectStack(final Construct scope, final String id, final StackProps props) {
  super(scope, id, props);

  // code that defines your resources and properties go here
 }
}
```  
 `src/test`   
テストファイルを含むディレクトリ。以下に例を示します。  

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.assertions.Template;
import java.io.IOException;

import java.util.HashMap;

import org.junit.jupiter.api.Test;

public class MyCdkJavaProjectTest {

 @Test
 public void testStack() throws IOException {
  App app = new App();
  MyCdkJavaProjectStack stack = new MyCdkJavaProjectStack(app, "test");

  Template template = Template.fromStack(stack);

  template.hasResourceProperties("AWS::SQS::Queue", new HashMap<String, Number>() {{
   put("VisibilityTimeout", 300);
  }});
 }
}
```
次の内容は、`cdk init --language csharp` コマンドを使用して `my-cdk-csharp-project` ディレクトリで作成されたプロジェクトの例です。  

```
my-cdk-csharp-project
├── .git
├── .gitignore
├── README.md
├── cdk.json
└── src
    ├── MyCdkCsharpProject
    └── MyCdkCsharpProject.sln
```  
 `src/MyCdkCsharpProject`   
*アプリケーション*および*スタック*ファイルを含むディレクトリ。  
次の内容は、アプリケーションファイルの例です。  

```
using Amazon.CDK;
using System;
using System.Collections.Generic;
using System.Linq;

namespace MyCdkCsharpProject
{
 sealed class Program
 {
  public static void Main(string[] args)
  {
   var app = new App();
   new MyCdkCsharpProjectStack(app, "MyCdkCsharpProjectStack", new StackProps{});
   app.Synth();
  }
 }
}
```
次の内容は、スタックファイルの例です。  

```
using Amazon.CDK;
using Constructs;

namespace MyCdkCsharpProject
{
 public class MyCdkCsharpProjectStack : Stack
 {
  internal MyCdkCsharpProjectStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
  {
   // code that defines your resources and properties go here
  }
 }
}
```
このディレクトリには、次のものも含まれています。  
  
+  `GlobalSuppressions.cs` – プロジェクト全体で特定のコンパイラ警告やエラーを抑制するために使用されるファイル。
+  `.csproj` – プロジェクト設定、依存関係、ビルド設定の定義に使用される XML ベースのファイル。---  
 `src/MyCdkCsharpProject.sln`   
 関連プロジェクトの整理および管理に使用される Microsoft Visual Studio Solution File。
次の内容は、`cdk init --language go` コマンドを使用して `my-cdk-go-project` ディレクトリで作成されたプロジェクトの例です。  

```
my-cdk-go-project
├── .git
├── .gitignore
├── README.md
├── cdk.json
├── go.mod
├── my-cdk-go-project.go
└── my-cdk-go-project_test.go
```  
 `go.mod`   
モジュール情報を含めて、Go プロジェクトの依存関係およびバージョニングを管理するために使用されるファイル。  
 `my-cdk-go-project.go`   
CDK アプリケーションおよびスタックを定義するファイル。  
以下に例を示します。  

```
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 MyCdkGoProjectStackProps struct {
 awscdk.StackProps
}

func NewMyCdkGoProjectStack(scope constructs.Construct, id string, props *MyCdkGoProjectStackProps) awscdk.Stack {
 var sprops awscdk.StackProps
 if props != nil {
  sprops = props.StackProps
 }
 stack := awscdk.NewStack(scope, &id, &sprops)
 // The code that defines your resources and properties go here

  return stack
}

func main() {
 defer jsii.Close()
 app := awscdk.NewApp(nil)
 NewMyCdkGoProjectStack(app, "MyCdkGoProjectStack", &MyCdkGoProjectStackProps{
  awscdk.StackProps{
   Env: env(),
  },
 })
 app.Synth(nil)
}

func env() *awscdk.Environment {

 return nil
}
```  
 `my-cdk-go-project_test.go`   
サンプルテストを定義するファイル。  
以下に例を示します。  

```
package main

import (
 "testing"

 "github.com/aws/aws-cdk-go/awscdk/v2"
 "github.com/aws/aws-cdk-go/awscdk/v2/assertions"
 "github.com/aws/jsii-runtime-go"
)

func TestMyCdkGoProjectStack(t *testing.T) {

 // GIVEN
 app := awscdk.NewApp(nil)

 // WHEN
 stack := NewMyCdkGoProjectStack(app, "MyStack", nil)

 // THEN
 template := assertions.Template_FromStack(stack, nil)
 template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{
  "VisibilityTimeout": 300,
 })
}
```

# AWS CDK アプリ
<a name="apps"></a>

AWS Cloud Development Kit (AWS CDK) アプリケーションまたは *app* は、1 つ以上の CDK [スタック](stacks.md)のコレクションです。スタックは、AWS リソースとプロパティを定義する、1 つ以上の[コンストラクト](constructs.md)のコレクションです。したがって、スタックとコンストラクトの集合全体を指して CDK アプリケーションと呼びます。

## CDK アプリの作成方法
<a name="apps-define"></a>

[プロジェクト](projects.md)のアプリケーションファイルでアプリケーションインスタンスを定義して、アプリケーションを作成します。これを行うには、AWS コンストラクトライブラリから [App](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html) コンストラクトをインポートして使用します。`App` コンストラクトには初期化引数は必要ありません。ルートとして使用できる唯一のコンストラクトです。

AWS コンストラクトライブラリの ` [App](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html) ` および ` [Stack](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html) ` クラスは、一意のコンストラクトです。他のコンストラクトと比較すると、それらは AWS リソースを独自に設定することはありません。代わりに、他のコンストラクトにコンテキストを提供するために使用されます。AWS リソースを表すすべてのコンストラクトは、直接または間接的に、`Stack` コンストラクトのスコープ内で定義する必要があります。`Stack` コンストラクトは、`App` コンストラクトのスコープ内で定義されます。

その後、アプリケーションが合成されてスタックの AWS CloudFormation テンプレートが作成されます。以下に例を示します。

**Example**  

```
const app = new App();
new MyFirstStack(app, 'hello-cdk');
app.synth();
```

```
const app = new App();
new MyFirstStack(app, 'hello-cdk');
app.synth();
```

```
app = App()
MyFirstStack(app, "hello-cdk")
app.synth()
```

```
App app = new App();
new MyFirstStack(app, "hello-cdk");
app.synth();
```

```
var app = new App();
new MyFirstStack(app, "hello-cdk");
app.Synth();
```

```
app := awscdk.NewApp(nil)

MyFirstStack(app, "MyFirstStack", &MyFirstStackProps{
  awscdk.StackProps{
    Env: env(),
  },
})

app.Synth(nil)
```

1 つのアプリケーション内のスタックは、互いのリソースとプロパティを簡単に参照できます。AWS CDK はスタック間の依存関係を推測し、正しい順序でデプロイできるようにします。1 つの `cdk deploy` コマンドで、アプリケーション内にスタックの一部またはすべてをデプロイできます。

## コンストラクトツリー
<a name="apps-tree"></a>

コンストラクトは、`App` クラスをルートとして、すべてのコンストラクトに渡される `scope` 引数を使用して、他のコンストラクトの内部で定義されます。このようにして、AWS CDK アプリは*コンストラクトツリー*と呼ばれるコンストラクトの階層を定義します。

このツリーのルートは、`App` クラスのインスタンスであるアプリです。アプリ内では、1 つ以上のスタックをインスタンス化します。スタック内では、コンストラクトをインスタンス化します。これにより、それ自体がリソースやその他のコンストラクトをインスタンス化できます。

コンストラクトは*常に*別のコンストラクトのスコープ内で明示的に定義され、コンストラクト間の関係が作成されます。ほとんどの場合、スコープとして `this` (Python では `self`) を渡す必要があります。これは、新しいコンストラクトが現在のコンストラクトの子であることを示します。想定されるパターンは、[https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html) からコンストラクトを派生させ、そのコンストラクタ内で使用するコンストラクトをインスタンス化することです。

スコープを明示的に渡すと、各コンストラクトはツリーに自身を追加できるようになります。この動作は[`Construct` 基底クラス](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html)内に完全に含まれています。これは AWS CDK がサポートするすべての言語で同じように動作し、追加のカスタマイズは必要ありません。

**重要**  
技術的には、コンストラクトをインスタンス化する場合、`this` 以外のスコープを渡すことができます。ツリー内の任意の場所、または同じアプリ内の別のスタックにコンストラクトを追加できます。たとえば、引数として渡されるスコープにコンストラクトを追加するミックスインスタイルの関数を記述できます。ここでの実際的な難点は、コンストラクトに選択した ID が他のユーザーのスコープ内で一意であることを簡単に確認できないことです。また、このプラクティスにより、コードの理解、維持、再利用の難しさが増してしまいます。したがって、コンストラクトツリーの一般的な構造を使用することをお勧めします。

AWS CDK は、ツリーのルートから各子コンストラクトへのパス内のすべてのコンストラクトの ID を使用して、AWS CloudFormation に必要な一意の ID を生成します。このアプローチは、コンストラクト ID は、ネイティブ AWS CloudFormation のようにスタック全体ではなく、スコープ内でのみ一意であればいいことを意味します。ただし、コンストラクトを別のスコープに移動すると、生成されたスタック固有の ID が変更され、AWS CloudFormation はそれを同じリソースとは見なさなくなります。

コンストラクトツリーは、AWS CDK コードで定義したコンストラクトとは別物です。ただしそれは、ツリー内のそのコンストラクトを表すノードへの参照である、任意のコンストラクトの `node` 属性からアクセスできます。各ノードは [https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Node.html](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Node.html) インスタンスであり、その属性はツリーのルートとノードの親スコープと子へのアクセスを提供します。

1.  `node.children` – コンストラクトの直接の子。

1.  `node.id` – スコープ内のコンストラクトの識別子。

1.  `node.path` – すべての親の ID を含む、コンストラクトの完全なパス。

1.  `node.root` – コンストラクトツリー (アプリケーション) のルート。

1.  `node.scope` – コンストラクトのスコープ (親)、またはノードがルートの場合は未定義。

1.  `node.scopes` – ルートまでのコンストラクトのすべての親。

1.  `node.uniqueId` – ツリー内のこのコンストラクトの一意の英数字識別子 (デフォルトでは、`node.path` および ハッシュから生成されます)。

コンストラクトツリーは、コンストラクトが最終 AWS CloudFormation テンプレートのリソースに合成される暗黙的な順序を定義します。あるリソースを別のリソースの前に作成する必要がある場合、AWS CloudFormation または AWS コンストラクトライブラリは通常、その依存関係を推測します。その後、リソースが正しい順序で作成されていることを確認します。

`node.addDependency()` を使用して、2 つのノード間に明示的な依存関係を追加することもできます。詳細については、「*AWS CDK API リファレンス*」の「[依存関係](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib-readme.html#dependencies)」を参照してください。

AWS CDK は、コンストラクトツリー内のすべてのノードを訪問し、それぞれに対して操作を実行する簡単な方法を提供します。詳細については、の「[アスペクトと AWS CDK](aspects.md)」を参照してください。

# AWS CDK スタックの概要
<a name="stacks"></a>

 AWS CDK スタックは、デプロイの最小単位です。CDK コンストラクトを使用して定義する AWS リソースのコレクションを表します。CDK アプリケーションをデプロイすると、CDK スタック内のリソースは AWS CloudFormation スタックとして一緒にデプロイされます。 AWS CloudFormation スタックの詳細については、「CloudFormation ユーザーガイド」の[AWS CloudFormationスタックを使用した単一ユニットとしての AWS リソースの管理](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacks.html)」を参照してください。 * AWS CloudFormation *

スタックを定義するには、[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) コンストラクトを拡張または継承します。以下の例は、*スタックファイル*と呼ばれる別のファイルで CDK スタックを定義するための一般的なパターンです。ここでは、`Stack` クラスを拡張または継承し、`id`、`scope`、`props`を受け入れるコンストラクターを定義します。次に、受け取った `scope`、`id`、`props` を引数とする `super` で、基底となる `Stack` クラスのコンストラクターを呼び出します。

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

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

    // Define your constructs here

  }
}
```

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

class MyCdkStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define your constructs here

  }
}

module.exports = { MyCdkStack }
```

```
from aws_cdk import (
  Stack,
)
from constructs import Construct

class MyCdkStack(Stack):

  def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
    super().__init__(scope, construct_id, **kwargs)

    # Define your constructs here
```

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;

public class MyCdkStack extends Stack {
  public MyCdkStack(final Construct scope, final String id) {
    this(scope, id, null);
  }

  public MyCdkStack(final Construct scope, final String id, final StackProps props) {
    super(scope, id, props);

    // Define your constructs here
  }
}
```

```
using Amazon.CDK;
using Constructs;

namespace MyCdk
{
  public class MyCdkStack : Stack
  {
    internal MyCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
    {
      // Define your constructs here
    }
  }
}
```

```
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 CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// The code that defines your stack goes here

	return stack
}

func main() {
	defer jsii.Close()

	app := awscdk.NewApp(nil)

	NewCdkDemoAppStack(app, "CdkDemoAppStack", &CdkDemoAppStackProps{
		awscdk.StackProps{
			Env: env(),
		},
	})

	app.Synth(nil)
}

//...
```

前の例では、スタックのみを定義しています。スタックを作成するには、CDK アプリのコンテキスト内でインスタンス化する必要があります。一般的なパターンは、CDK アプリケーションを定義し、*アプリケーションファイル*と呼ばれる別のファイルでスタックを初期化することです。

以下は、`MyCdkStack` という名前の CDK スタックを作成する例です。ここでは、CDK アプリケーションが作成され、アプリケーションのコンテキストで `MyCdkStack` がインスタンス化されます。

**Example**  

```
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { MyCdkStack } from '../lib/my-cdk-stack';

const app = new cdk.App();
new MyCdkStack(app, 'MyCdkStack', {
});
```

```
#!/usr/bin/env node

const cdk = require('aws-cdk-lib');
const { MyCdkStack } = require('../lib/my-cdk-stack');

const app = new cdk.App();
new MyCdkStack(app, 'MyCdkStack', {
});
```
`app.py` にあります  

```
#!/usr/bin/env python3
import os

import aws_cdk as cdk

from my_cdk.my_cdk_stack import MyCdkStack


app = cdk.App()
MyCdkStack(app, "MyCdkStack",)

app.synth()
```

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.StackProps;

import java.util.Arrays;

public class MyCdkApp {
  public static void main(final String[] args) {
    App app = new App();

    new MyCdkStack(app, "MyCdkStack", StackProps.builder()
      .build());

    app.synth();
  }
}
```

```
using Amazon.CDK;
using System;
using System.Collections.Generic;
using System.Linq;

namespace MyCdk
{
  sealed class Program
  {
    public static void Main(string[] args)
    {
      var app = new App();
      new MyCdkStack(app, "MyCdkStack", new StackProps
      {});
      app.Synth();
    }
  }
}
```

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

  NewMyCdkStack(app, "MyCdkStack", &MyCdkStackProps{
    awscdk.StackProps{
      Env: env(),
    },
  })

  app.Synth(nil)
}

// ...
```

以下の例では、2 つのスタックを含む CDK アプリケーションを作成します。

**Example**  

```
const app = new App();

new MyFirstStack(app, 'stack1');
new MySecondStack(app, 'stack2');

app.synth();
```

```
const app = new App();

new MyFirstStack(app, 'stack1');
new MySecondStack(app, 'stack2');

app.synth();
```

```
app = App()

MyFirstStack(app, 'stack1')
MySecondStack(app, 'stack2')

app.synth()
```

```
App app = new App();

new MyFirstStack(app, "stack1");
new MySecondStack(app, "stack2");

app.synth();
```

```
var app = new App();

new MyFirstStack(app, "stack1");
new MySecondStack(app, "stack2");

app.Synth();
```

```
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 MyFirstStackProps struct {
	awscdk.StackProps
}

func NewMyFirstStack(scope constructs.Construct, id string, props *MyFirstStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	myFirstStack := awscdk.NewStack(scope, &id, &sprops)

	// The code that defines your stack goes here

	return myFirstStack
}

type MySecondStackProps struct {
	awscdk.StackProps
}

func NewMySecondStack(scope constructs.Construct, id string, props *MySecondStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	mySecondStack := awscdk.NewStack(scope, &id, &sprops)

	// The code that defines your stack goes here

	return mySecondStack
}

func main() {
	defer jsii.Close()

	app := awscdk.NewApp(nil)

	NewMyFirstStack(app, "MyFirstStack", &MyFirstStackProps{
		awscdk.StackProps{
			Env: env(),
		},
	})

	NewMySecondStack(app, "MySecondStack", &MySecondStackProps{
		awscdk.StackProps{
			Env: env(),
		},
	})

	app.Synth(nil)
}

// ...
```

## スタック API について
<a name="stack-api"></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) オブジェクトには、以下のような豊富な API が用意されています。
+  `Stack.of(construct)` – コンストラクトが定義されている**スタック**を返す静的メソッド。これは、再利用可能なコンストラクト内からスタックを操作する必要がある場合に役立ちます。スタックがスコープ内で見つからない場合、呼び出しは失敗します。
+  `stack.stackName` (Python: `stack_name`) — スタックの物理名を返します。前述のように、すべての AWS CDK スタックには、 AWS CDK が合成中に解決できる物理名があります。
+  `stack.region` および `stack.account` - このスタックがデプロイされる AWS リージョンとアカウントをそれぞれ返します。これらのプロパティは、以下のいずれかの値を返します。
  + スタックが定義されたときに明示的に指定されたアカウントまたはリージョン
  + アカウントとリージョンの AWS CloudFormation 擬似パラメータに解決され、このスタックが環境に依存しないことを示す文字列エンコードされたトークン

    スタックの環境の決定方法については、[AWS 「CDK の環境](environments.md)」を参照してください。
+  `stack.addDependency(stack)` (Python: `stack.add_dependency(stack)`) – 2 つのスタック間の依存関係の順序を明示的に定義するために使用できます。この順序は、複数のスタックを一度にデプロイするときに `cdk deploy` コマンドによって考慮されます。
+  `stack.tags` – スタックレベルのタグを追加または削除するために使用できる [TagManager](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.TagManager.html) を返します。このタグマネージャーは、スタック内のすべてのリソースにタグを付け、 AWS CloudFormation を通じてスタックが作成されるとスタック自体にタグを付けます。
+  `stack.partition`、 `stack.urlSuffix` (Python: `url_suffix`)`stack.stackId`、 (Python: `stack_id`)、および `stack.notificationArn` (Python: `notification_arn`) – などのそれぞれの AWS CloudFormation 擬似パラメータに解決されるトークンを返します`{ "Ref": "AWS::Partition" }`。これらのトークンは、 AWS CDK フレームワークがクロススタック参照を識別できるように、特定のスタックオブジェクトに関連付けられます。
+  `stack.availabilityZones` (Python: `availability_zones`) – このスタックがデプロイされている環境で使用可能なアベイラビリティーゾーンのセットを返します。環境に依存しないスタックの場合、これは常に 2 つのアベイラビリティーゾーンを持つ配列を返します。環境固有のスタックの場合、 AWS CDK は環境をクエリし、指定したリージョンで使用できるアベイラビリティーゾーンの正確なセットを返します。
+  `stack.parseArn(arn)` および `stack.formatArn(comps)` (Python: `parse_arn`、`format_arn`) — Amazon リソースネーム (ARN) の操作に使用できます。
+  `stack.toJsonString(obj)` (Python: `to_json_string`) – 任意のオブジェクトを、 AWS CloudFormation テンプレートに埋め込むことができる JSON 文字列としてフォーマットするために使用できます。オブジェクトにはトークン、属性、参照を含めることができ、これらはデプロイ中にのみ解決されます。
+  `stack.templateOptions` (Python: `template_options`) – を使用して、スタックの変換、説明、メタデータなどの AWS CloudFormation テンプレートオプションを指定します。

## スタックの操作
<a name="stacks-work"></a>

スタックは、 AWS CloudFormation スタックとして[環境に](environments.md) AWS デプロイされます。環境は、特定の AWS アカウントと AWS リージョンを対象としています。

複数のスタックを持つアプリケーションの `cdk synth` コマンドを実行すると、クラウドアセンブリにはスタックインスタンスごとに個別のテンプレートが含まれます。2 つのスタックが同じクラスのインスタンスであっても、 AWS CDK は 2 つの個別のテンプレートとして出力します。

`cdk synth` コマンドでスタック名を指定することで、各テンプレートを合成できます。以下の例は、`stack1` のテンプレートを合成します。

```
$ cdk synth <stack1>
```

このアプローチは、 AWS CloudFormation テンプレートが通常どのように使用されるかとは概念的に異なり、テンプレートを複数回デプロイして [AWS CloudFormation パラメータ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html)を使用してパラメータ化できます。 AWS CloudFormation パラメータは AWS CDK で定義できますが、 AWS CloudFormation パラメータはデプロイ中にのみ解決されるため、一般的に推奨されません。これは、コード内ではパラメータの値を判断できないことを意味します。

例えば、パラメータ値に基づいてアプリにリソースを条件付きで含めるには、[AWS CloudFormation 条件](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html)を設定し、そのリソースにタグを付ける必要があります。 AWS CDK は、合成時に具体的なテンプレートが解決されるアプローチを取ります。したがって、`if` ステートメントを使用して値をチェックし、リソースを定義するか、何らかの動作を適用するかを決定できます。

**注記**  
 AWS CDK は、合成時に可能な限り多くの解像度を提供し、プログラミング言語のイディオマティックで自然な使用を可能にします。

他のコンストラクトと同様に、スタックはまとめてグループに構成できます。以下のコードは、コントロールプレーン、データプレーン、モニタリングスタックの 3 つのスタックで構成されるサービスの例を示しています。サービスコンストラクトは 2 回定義されます。ベータ環境用に 1 回、本番環境用に 1 回です。

**Example**  

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

interface EnvProps {
  prod: boolean;
}

// imagine these stacks declare a bunch of related resources
class ControlPlane extends Stack {}
class DataPlane extends Stack {}
class Monitoring extends Stack {}

class MyService extends Construct {

  constructor(scope: Construct, id: string, props?: EnvProps) {

    super(scope, id);

    // we might use the prod argument to change how the service is configured
    new ControlPlane(this, "cp");
    new DataPlane(this, "data");
    new Monitoring(this, "mon");  }
}

const app = new App();
new MyService(app, "beta");
new MyService(app, "prod", { prod: true });

app.synth();
```

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

// imagine these stacks declare a bunch of related resources
class ControlPlane extends Stack {}
class DataPlane extends Stack {}
class Monitoring extends Stack {}

class MyService extends Construct {

  constructor(scope, id, props) {

    super(scope, id);

    // we might use the prod argument to change how the service is configured
    new ControlPlane(this, "cp");
    new DataPlane(this, "data");
    new Monitoring(this, "mon");
  }
}

const app = new App();
new MyService(app, "beta");
new MyService(app, "prod", { prod: true });

app.synth();
```

```
from aws_cdk import App, Stack
from constructs import Construct

# imagine these stacks declare a bunch of related resources
class ControlPlane(Stack): pass
class DataPlane(Stack): pass
class Monitoring(Stack): pass

class MyService(Construct):

  def __init__(self, scope: Construct, id: str, *, prod=False):

    super().__init__(scope, id)

    # we might use the prod argument to change how the service is configured
    ControlPlane(self, "cp")
    DataPlane(self, "data")
    Monitoring(self, "mon")

app = App();
MyService(app, "beta")
MyService(app, "prod", prod=True)

app.synth()
```

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Stack;
import software.constructs.Construct;

public class MyApp {

    // imagine these stacks declare a bunch of related resources
    static class ControlPlane extends Stack {
        ControlPlane(Construct scope, String id) {
            super(scope, id);
        }
    }

    static class DataPlane extends Stack {
        DataPlane(Construct scope, String id) {
            super(scope, id);
        }
    }

    static class Monitoring extends Stack {
        Monitoring(Construct scope, String id) {
            super(scope, id);
        }
    }

    static class MyService extends Construct {
        MyService(Construct scope, String id) {
            this(scope, id, false);
        }

        MyService(Construct scope, String id, boolean prod) {
            super(scope, id);

            // we might use the prod argument to change how the service is configured
            new ControlPlane(this, "cp");
            new DataPlane(this, "data");
            new Monitoring(this, "mon");
        }
    }

    public static void main(final String argv[]) {
        App app = new App();

        new MyService(app, "beta");
        new MyService(app, "prod", true);

        app.synth();
    }
}
```

```
using Amazon.CDK;
using Constructs;

// imagine these stacks declare a bunch of related resources
public class ControlPlane : Stack {
    public ControlPlane(Construct scope, string id=null) : base(scope, id) { }
}

public class DataPlane : Stack {
    public DataPlane(Construct scope, string id=null) : base(scope, id) { }
}

public class Monitoring : Stack
{
    public Monitoring(Construct scope, string id=null) : base(scope, id) { }
}

public class MyService : Construct
{
    public MyService(Construct scope, string id, Boolean prod=false) : base(scope, id)
    {
        // we might use the prod argument to change how the service is configured
        new ControlPlane(this, "cp");
        new DataPlane(this, "data");
        new Monitoring(this, "mon");
    }
}

class Program
{
    static void Main(string[] args)
    {

        var app = new App();
        new MyService(app, "beta");
        new MyService(app, "prod", prod: true);
        app.Synth();
    }
}
```

```
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 ControlPlaneStackProps struct {
	awscdk.StackProps
}

func NewControlPlaneStack(scope constructs.Construct, id string, props *ControlPlaneStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	ControlPlaneStack := awscdk.NewStack(scope, jsii.String(id), &sprops)

	// The code that defines your stack goes here

	return ControlPlaneStack
}

type DataPlaneStackProps struct {
	awscdk.StackProps
}

func NewDataPlaneStack(scope constructs.Construct, id string, props *DataPlaneStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	DataPlaneStack := awscdk.NewStack(scope, jsii.String(id), &sprops)

	// The code that defines your stack goes here

	return DataPlaneStack
}

type MonitoringStackProps struct {
	awscdk.StackProps
}

func NewMonitoringStack(scope constructs.Construct, id string, props *MonitoringStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	MonitoringStack := awscdk.NewStack(scope, jsii.String(id), &sprops)

	// The code that defines your stack goes here

	return MonitoringStack
}

type MyServiceStackProps struct {
	awscdk.StackProps
	Prod bool
}

func NewMyServiceStack(scope constructs.Construct, id string, props *MyServiceStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	MyServiceStack := awscdk.NewStack(scope, jsii.String(id), &sprops)

	NewControlPlaneStack(MyServiceStack, "cp", &ControlPlaneStackProps{
		StackProps: sprops,
	})
	NewDataPlaneStack(MyServiceStack, "data", &DataPlaneStackProps{
		StackProps: sprops,
	})
	NewMonitoringStack(MyServiceStack, "mon", &MonitoringStackProps{
		StackProps: sprops,
	})

	return MyServiceStack
}

func main() {
	defer jsii.Close()

	app := awscdk.NewApp(nil)

	betaProps := MyServiceStackProps{
		StackProps: awscdk.StackProps{
			Env: env(),
		},
		Prod: false,
	}

	NewMyServiceStack(app, "beta", &betaProps)

	prodProps := MyServiceStackProps{
		StackProps: awscdk.StackProps{
			Env: env(),
		},
		Prod: true,
	}

	NewMyServiceStack(app, "prod", &prodProps)

	app.Synth(nil)
}

// ...
```
この AWS CDK アプリは最終的に 6 つのスタックで構成され、環境ごとに 3 つになります。  

```
$ cdk ls

betacpDA8372D3
betadataE23DB2BA
betamon632BD457
prodcp187264CE
proddataF7378CE5
prodmon631A1083
```

 AWS CloudFormation スタックの物理名は、ツリー内のスタックのコンストラクトパスに基づいて AWS CDK によって自動的に決定されます。デフォルトでは、スタックの名前は `Stack` オブジェクトのコンストラクト ID から取得されます。ただし、以下のように `stackName` prop (Python では `stack_name`) を使用して、明示的な名前を指定できます。

**Example**  

```
new MyStack(this, 'not:a:stack:name', { stackName: 'this-is-stack-name' });
```

```
new MyStack(this, 'not:a:stack:name', { stackName: 'this-is-stack-name' });
```

```
MyStack(self, "not:a:stack:name", stack_name="this-is-stack-name")
```

```
new MyStack(this, "not:a:stack:name", StackProps.builder()
    .StackName("this-is-stack-name").build());
```

```
new MyStack(this, "not:a:stack:name", new StackProps
{
    StackName = "this-is-stack-name"
});
```

### ネストされたスタックの操作
<a name="stack-nesting"></a>

*ネストされたスタック*は、親スタックと呼ばれる別のスタック内に作成する CDK スタックです。ネストされたスタックは、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.NestedStack.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.NestedStack.html) コンストラクトを使用して作成します。

ネストされたスタックを使用すると、複数のスタックにまたがってリソースを整理できます。ネストされたスタックは、スタックの AWS CloudFormation 500 リソース制限を回避する方法も提供します。ネストされたスタックは、それを含むスタック内の 1 つのリソースとしてカウントされます。そしてそれには、さらにネストされたスタックを含め、最大 500 個のリソースを含めることができます。

ネストされたスタックのスコープは、`Stack` または `NestedStack` コンストラクトである必要があります。ネストされたスタックは、親スタック内で字句的に宣言される必要はありません。ネストされたスタックをインスタンス化するときには、親スタックを最初のパラメータ (`scope`) として渡すだけで済みます。この制限とは別に、ネストされたスタック内のコンストラクトの定義は、通常のスタックとまったく同じように機能します。

合成時に、ネストされたスタックは独自の AWS CloudFormation テンプレートに合成され、デプロイ時に AWS CDK ステージングバケットにアップロードされます。ネストされたスタックは親スタックにバインドされ、独立したデプロイアーティファクトとしては扱われません。これらは `cdk list` で一覧表示されず、`cdk deploy` でデプロイすることもできません。

親スタックとネストされたスタック間のリファレンスは、[クロススタックリファレンス](resources.md#resource-stack)と同様に、生成された AWS CloudFormation テンプレートのスタックパラメータと出力に自動的に変換されます。

**警告**  
セキュリティ体制の変更は、ネストされたスタックのデプロイ前には表示されません。この情報は、最上位スタックにのみ表示されます。

# AWS CDK ステージの概要
<a name="stages"></a>

AWS Cloud Development Kit (AWS CDK) *ステージ*は、まとめてデプロイするように設定された 1 つ以上の CDK スタックのグループを表します。ステージを使用し、開発、テスト、本番稼働などの複数の環境にスタックの同じグループをデプロイします。

CDK ステージを設定するには、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stage.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stage.html) コンストラクトをインポートして使用します。

次の内容は、`MyAppStage` という名前の CDK ステージを定義する基本的な例です。`AppStack` および `DatabaseStack` という名前の 2 つの CDK スタックをステージに追加します。この例では、`AppStack` にはアプリケーションリソースが含まれており、`DatabaseStack` にはデータベースリソースが含まれています。次に、開発環境および本番環境用として `MyAppStage` の 2 つのインスタンスを作成します。

**Example**  
Eclipse `cdk-demo-app/lib/app-stack.ts`:  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

// Define the app stack
export class AppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    // The code that defines your application goes here
  }
}
```
Eclipse `cdk-demo-app/lib/database-stack.ts`:  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

// Define the database stack
export class DatabaseStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    // The code that defines your database goes here
  }
}
```
Eclipse `cdk-demo-app/lib/my-stage.ts`:  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Stage } from 'aws-cdk-lib';
import { AppStack } from './app-stack';
import { DatabaseStack } from './database-stack';

// Define the stage
export class MyAppStage extends Stage {
  constructor(scope: Construct, id: string, props?: cdk.StageProps) {
    super(scope, id, props);

    // Add both stacks to the stage
    new AppStack(this, 'AppStack');
    new DatabaseStack(this, 'DatabaseStack');
  }
}
```
Eclipse `cdk-demo-app/bin/cdk-demo-app.ts`:  

```
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { MyAppStage } from '../lib/my-stage';

// Create a CDK app
const app = new cdk.App();

// Create the development stage
new MyAppStage(app, 'Dev', {
  env: {
    account: '123456789012',
    region: 'us-east-1'
  }
});

// Create the production stage
new MyAppStage(app, 'Prod', {
  env: {
    account: '098765432109',
    region: 'us-east-1'
  }
});
```
Eclipse `cdk-demo-app/lib/app-stack.js`:  

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

class AppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // The code that defines your application goes here
  }
}

module.exports = { AppStack }
```
Eclipse `cdk-demo-app/lib/database-stack.js`:  

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

class DatabaseStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // The code that defines your database goes here
  }
}

module.exports = { DatabaseStack }
```
Eclipse `cdk-demo-app/lib/my-stage.js`:  

```
const { Stage } = require('aws-cdk-lib');
const { AppStack } = require('./app-stack');
const { DatabaseStack } = require('./database-stack');

// Define the stage
class MyAppStage extends Stage {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Add both stacks to the stage
    new AppStack(this, 'AppStack');
    new DatabaseStack(this, 'DatabaseStack');
  }
}

module.exports = { MyAppStage };
```
Eclipse `cdk-demo-app/bin/cdk-demo-app.js`:  

```
#!/usr/bin/env node

const cdk = require('aws-cdk-lib');
const { MyAppStage } = require('../lib/my-stage');

// Create the CDK app
const app = new cdk.App();

// Create the development stage
new MyAppStage(app, 'Dev', {
  env: {
    account: '123456789012',
    region: 'us-east-1',
  },
});

// Create the production stage
new MyAppStage(app, 'Prod', {
  env: {
    account: '098765432109',
    region: 'us-east-1',
  },
});
```
Eclipse `cdk-demo-app/cdk_demo_app/app_stack.py`:  

```
from aws_cdk import Stack
from constructs import Construct

# Define the app stack
class AppStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # The code that defines your application goes here
```
Eclipse `cdk-demo-app/cdk_demo_app/database_stack.py`:  

```
from aws_cdk import Stack
from constructs import Construct

# Define the database stack
class DatabaseStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # The code that defines your database goes here
```
Eclipse `cdk-demo-app/cdk_demo_app/my_stage.py`:  

```
from aws_cdk import Stage
from constructs import Construct
from .app_stack import AppStack
from .database_stack import DatabaseStack

# Define the stage
class MyAppStage(Stage):
    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # Add both stacks to the stage
        AppStack(self, "AppStack")
        DatabaseStack(self, "DatabaseStack")
```
Eclipse `cdk-demo-app/app.py`:  

```
#!/usr/bin/env python3
import os

import aws_cdk as cdk

from cdk_demo_app.my_stage import MyAppStage

#  Create a CDK app
app = cdk.App()

# Create the development stage
MyAppStage(app, 'Dev',
           env=cdk.Environment(account='123456789012', region='us-east-1'),
           )

# Create the production stage
MyAppStage(app, 'Prod',
           env=cdk.Environment(account='098765432109', region='us-east-1'),
           )

app.synth()
```
Eclipse `cdk-demo-app/src/main/java/com/myorg/AppStack.java`:  

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;

public class AppStack extends Stack {
    public AppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public AppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // The code that defines your application goes here
    }
}
```
Eclipse `cdk-demo-app/src/main/java/com/myorg/DatabaseStack.java`:  

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;

public class DatabaseStack extends Stack {
    public DatabaseStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public DatabaseStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // The code that defines your database goes here
    }
}
```
Eclipse `cdk-demo-app/src/main/java/com/myorg/MyAppStage.java`:  

```
package com.myorg;

import software.amazon.awscdk.Stage;
import software.amazon.awscdk.StageProps;
import software.constructs.Construct;

// Define the stage
public class MyAppStage extends Stage {
    public MyAppStage(final Construct scope, final String id, final software.amazon.awscdk.Environment env) {
        super(scope, id, StageProps.builder().env(env).build());

        // Add both stacks to the stage
        new AppStack(this, "AppStack");
        new DatabaseStack(this, "DatabaseStack");
    }
}
```
Eclipse `cdk-demo-app/src/main/java/com/myorg/CdkDemoAppApp.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 CdkDemoAppApp {
    public static void main(final String[] args) {

        // Create a CDK app
        App app = new App();

        // Create the development stage
        new MyAppStage(app, "Dev", Environment.builder()
                .account("123456789012")
                .region("us-east-1")
                .build());

        // Create the production stage
        new MyAppStage(app, "Prod", Environment.builder()
        .account("098765432109")
        .region("us-east-1")
        .build());

        app.synth();
    }
}
```
Eclipse `cdk-demo-app/src/CdkDemoApp/AppStack.cs`:  

```
using Amazon.CDK;
using Constructs;

namespace CdkDemoApp
{
    public class AppStack : Stack
    {
        internal AppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // The code that defines your application goes here
        }
    }
}
```
Eclipse `cdk-demo-app/src/CdkDemoApp/DatabaseStack.cs`:  

```
using Amazon.CDK;
using Constructs;

namespace CdkDemoApp
{
    public class DatabaseStack : Stack
    {
        internal DatabaseStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // The code that defines your database goes here
        }
    }
}
```
Eclipse `cdk-demo-app/src/CdkDemoApp/MyAppStage.cs`:  

```
using Amazon.CDK;
using Constructs;

namespace CdkDemoApp
{
    // Define the stage
    public class MyAppStage : Stage
    {
        internal MyAppStage(Construct scope, string id, Environment env) : base(scope, id, new StageProps { Env = env })
        {
            // Add both stacks to the stage
            new AppStack(this, "AppStack");
            new DatabaseStack(this, "DatabaseStack");
        }
    }
}
```
Eclipse `cdk-demo-app/src/CdkDemoApp/program.cs`:  

```
using Amazon.CDK;
using System;
using System.Collections.Generic;
using System.Linq;

namespace CdkDemoApp
{
    sealed class Program
    {
        public static void Main(string[] args)
        {
            // Create a CDK app
            var app = new App();

            // Create the development stage
            new MyAppStage(app, "Dev", new Amazon.CDK.Environment
            {
                Account = "123456789012",
                Region = "us-east-1"
            });

            // Create the production stage
            new MyAppStage(app, "Prod", new Amazon.CDK.Environment
            {
                Account = "098765432109",
                Region = "us-east-1"
            });

            app.Synth();
        }
    }
}
```
Eclipse `cdk-demo-app/cdk-demo-app.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"
)

// Define the app stack
type AppStackProps struct {
	awscdk.StackProps
}

func NewAppStack(scope constructs.Construct, id string, props *AppStackProps) awscdk.Stack {
	stack := awscdk.NewStack(scope, &id, &props.StackProps)

	// The code that defines your application goes here

	return stack
}

// Define the database stack
type DatabaseStackProps struct {
	awscdk.StackProps
}

func NewDatabaseStack(scope constructs.Construct, id string, props *DatabaseStackProps) awscdk.Stack {
	stack := awscdk.NewStack(scope, &id, &props.StackProps)

	// The code that defines your database goes here

	return stack
}

// Define the stage
type MyAppStageProps struct {
	awscdk.StageProps
}

func NewMyAppStage(scope constructs.Construct, id string, props *MyAppStageProps) awscdk.Stage {
	stage := awscdk.NewStage(scope, &id, &props.StageProps)

	// Add both stacks to the stage
	NewAppStack(stage, "AppStack", &AppStackProps{
		StackProps: awscdk.StackProps{
			Env: props.Env,
		},
	})

	NewDatabaseStack(stage, "DatabaseStack", &DatabaseStackProps{
		StackProps: awscdk.StackProps{
			Env: props.Env,
		},
	})

	return stage
}

func main() {
	defer jsii.Close()

	// Create a CDK app
	app := awscdk.NewApp(nil)

	// Create the development stage
	NewMyAppStage(app, "Dev", &MyAppStageProps{
		StageProps: awscdk.StageProps{
			Env: &awscdk.Environment{
				Account: jsii.String("123456789012"),
				Region:  jsii.String("us-east-1"),
			},
		},
	})

	// Create the production stage
	NewMyAppStage(app, "Prod", &MyAppStageProps{
		StageProps: awscdk.StageProps{
			Env: &awscdk.Environment{
				Account: jsii.String("098765432109"),
				Region:  jsii.String("us-east-1"),
			},
		},
	})

	app.Synth(nil)
}

func env() *awscdk.Environment {
	return nil
}
```

`cdk synth` を実行するとき、`cdk.out` に 2 つのクラウドアセンブリが作成されます。これら 2 つのクラウドアセンブリには、各ステージの合成された AWS CloudFormation テンプレートおよびアセットが含まれています。次の内容は、プロジェクトディレクトリのスニペットです。

**Example**  

```
cdk-demo-app
├── bin
│   └── cdk-demo-app.ts
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
└── lib
    ├── app-stack.ts
    ├── database-stack.ts
    └── my-stage.ts
```

```
cdk-demo-app
├── bin
│   └── cdk-demo-app.js
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
└── lib
    ├── app-stack.js
    ├── database-stack.js
    └── my-stage.js
```

```
cdk-demo-app
├── app.py
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── cdk.out
│   ├── manifest.json
│   └── tree.json
└── cdk_demo_app
    ├── __init__.py
    ├── app_stack.py
    ├── database_stack.py
    └── my_stage.py
```

```
cdk-demo-app
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── cdk.out
│   ├── manifest.json
│   └── tree.json
└── src
    └── main
        └── java
            └── com
                └── myorg
                    ├── AppStack.java
                    ├── CdkDemoAppApp.java
                    ├── DatabaseStack.java
                    └── MyAppStage.java
```

```
cdk-demo-app
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── cdk.out
│   ├── manifest.json
│   └── tree.json
└── src
    └── CdkDemoApp
        ├── AppStack.cs
        ├── DatabaseStack.cs
        ├── MyAppStage.cs
        └── Program.cs
```

```
cdk-demo-app
├── cdk-demo-app.go
└── cdk.out
    ├── assembly-Dev
    │   ├── DevAppStack<unique-hash>.assets.json
    │   ├── DevAppStack<unique-hash>.template.json
    │   ├── DevDatabaseStack<unique-hash>.assets.json
    │   ├── DevDatabaseStack<unique-hash>.template.json
    │   ├── cdk.out
    │   └── manifest.json
    ├── assembly-Prod
    │   ├── ProdAppStack<unique-hash>.assets.json
    │   ├── ProdAppStack<unique-hash>.template.json
    │   ├── ProdDatabaseStack<unique-hash>.assets.json
    │   ├── ProdDatabaseStack<unique-hash>.template.json
    │   ├── cdk.out
    │   └── manifest.json
    ├── cdk.out
    ├── manifest.json
    └── tree.json
```
`cdk list` でスタックを一覧表示するとき、合計 4 つのスタックが表示されます。  

```
$ cdk list
Dev/AppStack (Dev-AppStack)
Dev/DatabaseStack (Dev-DatabaseStack)
Prod/AppStack (Prod-AppStack)
Prod/DatabaseStack (Prod-DatabaseStack)
```
特定のステージをデプロイするには、`cdk deploy` を実行してデプロイするスタックを指定します。次の内容は、`/*` ワイルドカードを使用して両方のスタックを `Dev` ステージにデプロイする例です。  

```
$ cdk deploy <"Dev/*">

✨  Synthesis time: 3.18s

Dev/AppStack (Dev-AppStack)
Dev/AppStack (Dev-AppStack): deploying... [1/2]

 ✅  Dev/AppStack (Dev-AppStack)

✨  Deployment time: 1.11s

Stack ARN:
...

✨  Total time: 4.29s

Dev/DatabaseStack (Dev-DatabaseStack)
Dev/DatabaseStack (Dev-DatabaseStack): deploying... [2/2]

 ✅  Dev/DatabaseStack (Dev-DatabaseStack)

✨  Deployment time: 1.09s

Stack ARN:
...

✨  Total time: 4.27s
```

# AWS CDK コンストラクト
<a name="constructs"></a>

コンストラクトは、 AWS Cloud Development Kit (AWS CDK) アプリケーションの基本的な構成要素です。コンストラクトは、1 つ以上の AWS CloudFormation リソースとその設定を表すアプリケーション内のコンポーネントです。コンストラクトをインポートして設定することで、アプリケーションを 1 つずつ構築していきます。

## コンストラクトをインポートして使用する
<a name="constructs-import"></a>

コンストラクトは、[AWS コンストラクトライブラリ](libraries.md#libraries-construct) から CDK アプリケーションにインポートするクラスです。また、独自のコンストラクトを作成および配布することや、サードパーティーの開発者によって作成されたコンストラクトを使用することもできます。

コンストラクトは、コンストラクトプログラミングモデル (CPM) の一部です。CDK for Terraform (CDKtf)、CDK for Kubernetes (CDK8s)、Projen など、他のツールでも使用できます。

多数のサードパーティーも AWS CDK と互換性のあるコンストラクトを公開しています。 AWS CDK [コンストラクトパートナーエコシステムについては、Construct Hub](https://constructs.dev/search?q=&cdk=aws-cdk&cdkver=2&offset=0) を参照してください。

## コンストラクトレベル
<a name="constructs-lib-levels"></a>

コンストラクトライブラリからの AWS コンストラクトは、3 つのレベルに分類されます。各レベルは、抽象化のレベルが段階的に上がっていきます。抽象化が高いほど、設定が容易になり、必要な専門知識も少なくなります。抽象化が低いほど、より高度なカスタマイズが可能になりますが、より多くの専門知識が必要になります。<a name="constructs-lib-levels-one"></a>

 **レベル 1 (L1) コンストラクト**   
L1 コンストラクトは、*CFN リソース* とも呼ばれ、最下位のコンストラクトであり、抽象化は行いません。各 L1 コンストラクトは、単一の AWS CloudFormation リソースに直接マッピングされます。L1 コンストラクトでは、特定の AWS CloudFormation リソースを表すコンストラクトをインポートします。次に、コンストラクトインスタンス内でリソースのプロパティを定義します。  
L1 コンストラクトは、 AWS CloudFormation に精通しており、 AWS リソースプロパティの定義を完全に制御する必要がある場合に最適です。  
コンストラクトライブラリでは、L1 AWS コンストラクトの名前は で始まり`Cfn`、その後にそれが表す AWS CloudFormation リソースの識別子が続きます。たとえば、 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.CfnBucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.CfnBucket.html)コンストラクトは [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html) AWS CloudFormation リソースを表す L1 コンストラクトです。  
L1 コンストラクトは、[AWS CloudFormation リソース仕様](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html)から生成されます。リソースが AWS CloudFormation に存在する場合、L1 コンストラクトとして AWS CDK で使用できます。新しいリソースまたはプロパティが AWS コンストラクトライブラリで使用可能になるまでに最大 1 週間かかる場合があります。詳細については、* AWS 「 CloudFormation ユーザーガイド*」の[AWS 「リソースタイプとプロパティタイプのリファレンス](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html)」を参照してください。<a name="constructs-lib-levels-two"></a>

 **レベル 2 (L2) コンストラクト**   
*キュレーションされた*コンストラクトとも呼ばれる L2 コンストラクトは、CDK チームによって慎重に開発され、通常は最も広く使用されているコンストラクトタイプです。L2 コンストラクトは、L1 コンストラクトと同様に single AWS CloudFormation リソースに直接マッピングされます。L1 コンストラクトと比較して、L2 コンストラクトは直感的なインテントベースの API を通してより高度な抽象化を提供します。L2 コンストラクトには、適切なデフォルトプロパティ設定、ベストプラクティスのセキュリティポリシー、および多くのボイラープレートコードやグルーロジックを生成する機能が含まれています。  
L2 コンストラクトは、ほとんどのリソースにヘルパーメソッドも提供します。これにより、プロパティ、アクセス許可、リソース間のイベントベースのインタラクションなどをより簡単かつ迅速に定義できます。これらの機能の多くは、[Mixins](mixins.md) と呼ばれる独立した構成要素としても利用でき、 `.with()`メソッドを使用して L1 コンストラクトと L2 コンストラクトの両方に適用できます。  
[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html) クラスは、Amazon Simple Storage Service (Amazon S3) バケットリソースの L2 コンストラクトの一例です。  
 AWS コンストラクトライブラリには、安定して本番環境で使用できるように指定された L2 コンストラクトが含まれています。開発中の L2 コンストラクトは実験的なものとして指定され、別個のモジュールとして提供されます。<a name="constructs-lib-levels-three"></a>

 **レベル 3 (L3) コンストラクト**   
L3 コンストラクトは、*パターン*とも呼ばれ、最も高度な最高レベルです。各 L3 コンストラクトには、アプリケーション内の特定のタスクまたはサービスを達成するために連携するように設定された、複数リソースの集合を含めることができます。L3 コンストラクトは、アプリケーションの特定のユースケースの AWS アーキテクチャ全体を作成するために使用されます。  
完全なシステム設計、または大規模なシステムの主要部分を提供するために、L3 コンストラクトは、独自の考えに基づくデフォルトのプロパティ設定を提供します。これらは、問題を解決し、解決策を提供するための特定のアプローチを軸に構築されています。L3 コンストラクトを使用すると、入力とコードの量を最小限に抑えながら、複数のリソースをすばやく作成して設定できます。  
[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs_patterns.ApplicationLoadBalancedFargateService.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs_patterns.ApplicationLoadBalancedFargateService.html) クラスは、Amazon Elastic Container Service (Amazon ECS) クラスターで実行され、アプリケーションロードバランサーにフロントされる AWS Fargate サービスを表す L3 コンストラクトの例です。  
L2 コンストラクトと同様に、本番環境で使用できる L3 AWS コンストラクトは コンストラクトライブラリに含まれています。開発中のものは、別個のモジュールで提供されます。

## コンストラクトの定義
<a name="constructs-define"></a>

### コンポジション
<a name="constructs-composition"></a>

 *コンポジション*は、コンストラクトを通して高レベルの抽象化を定義するための重要なパターンです。高レベルのコンストラクトは、任意の数の低レベルのコンストラクトから構成できます。ボトムアップの観点からは、 コンストラクトを使用して、デプロイする個々の AWS リソースを整理します。必要な階層数で、目的に応じて便利な抽象化を使用します。

コンポジションを使用することで、再利用可能なコンポーネントを定義し、他のコードと同様に共有することができます。たとえば、チームはバックアップ、グローバルレプリケーション、自動スケーリング、モニタリングなど、Amazon DynamoDB テーブルに対する会社のベストプラクティスを実装するコンストラクトを定義できます。チームは、コンストラクトを内部的に他のチームと共有することも、公開することもできます。

チームは、他のライブラリパッケージと同様にコンストラクトを使用できます。ライブラリが更新されると、開発者は他のコードライブラリと同様に、新しいバージョンの改善やバグ修正にアクセスできるようになります。

### 初期化
<a name="constructs-init"></a>

コンストラクトは、[https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html) 基底クラスを拡張したクラスとして実装されます。コンストラクトの定義は、クラスのインスタンス化によって行います。すべてのコンストラクトは、初期化時に以下の 3 つのパラメータを取ります。
+  **scope** – コンストラクトの親または所有者。これはスタックでも別のコンストラクトでもかまいません。スコープは、[コンストラクトツリー](apps.md#apps-tree)内のコンストラクトの場所を決定します。通常は、現在のオブジェクトを表す `this` (Python では `self`) をスコープとして渡すべきです。
+  **id** — スコープ内で一意でなければならない[識別子](identifiers.md)です。識別子は、 コンストラクト内で定義されているすべての名前空間として機能します。これは、[リソース名](resources.md#resources-physical-names)や AWS CloudFormation 論理 IDs などの一意の識別子を生成するために使用されます。

  識別子が一意である必要があるのはスコープ内のみです。これにより、含まれる可能性のあるコンストラクトと識別子を気にせずにコンストラクトをインスタンス化して再利用でき、コンストラクトを組み合わせてより高いレベルの抽象化を作成できるようになります。さらに、スコープを使用すると、コンストラクトのグループを一度に参照できます。例としては、[タグ付け](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tag.html)や、コンストラクトのデプロイ先の指定などが挙げられます。
+  **props** – 言語に応じて、コンストラクトの初期設定を定義するプロパティまたはキーワード引数のセット。高レベルのコンストラクトであるほど多くのデフォルト値が提供され、すべての prop 要素がオプションである場合は、props パラメータを完全に省略することができます。

### 設定
<a name="constructs-config"></a>

ほとんどのコンストラクトは、3 番目の引数 (Python ではキーワード引数) として `props` を受け入れます。これは、コンストラクトの設定を定義する名前と値のコレクションです。次の例では、 AWS Key Management Service (AWS KMS) 暗号化と静的ウェブサイトホスティングが有効になっているバケットを定義します。暗号化キーの明示的な指定はされていないため、`Bucket` コンストラクトは新しい `kms.Key` を定義してバケットに関連付けます。

**Example**  

```
new s3.Bucket(this, 'MyEncryptedBucket', {
  encryption: s3.BucketEncryption.KMS,
  websiteIndexDocument: 'index.html'
});
```

```
new s3.Bucket(this, 'MyEncryptedBucket', {
  encryption: s3.BucketEncryption.KMS,
  websiteIndexDocument: 'index.html'
});
```

```
s3.Bucket(self, "MyEncryptedBucket", encryption=s3.BucketEncryption.KMS,
    website_index_document="index.html")
```

```
Bucket.Builder.create(this, "MyEncryptedBucket")
        .encryption(BucketEncryption.KMS_MANAGED)
        .websiteIndexDocument("index.html").build();
```

```
new Bucket(this, "MyEncryptedBucket", new BucketProps
{
    Encryption = BucketEncryption.KMS_MANAGED,
    WebsiteIndexDocument = "index.html"
});
```

```
	awss3.NewBucket(stack, jsii.String("MyEncryptedBucket"), &awss3.BucketProps{
		Encryption: awss3.BucketEncryption_KMS,
		WebsiteIndexDocument: jsii.String("index.html"),
	})
```

### コンストラクトの操作
<a name="constructs-interact"></a>

コンストラクトは、基底クラスである [Construct](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html) クラスを拡張したクラスです。コンストラクトをインスタンス化すると、コンストラクトオブジェクトは一連のメソッドとプロパティを公開します。これにより、コンストラクトを操作し、システムの他の部分への参照として渡すことができます。

 AWS CDK フレームワークでは、コンストラクトの APIsに制限はありません。作成者は必要な API を定義できます。ただし、 などの AWS コンストラクトライブラリに含まれているコンストラクト AWS は`s3.Bucket`、ガイドラインと一般的なパターンに従います。これにより、すべての AWS リソースで一貫したエクスペリエンスが提供されます。

ほとんどの AWS コンストラクトには、そのコンストラクトに対する AWS Identity and Access Management (IAM) アクセス許可をプリンシパルに付与するために使用できる一連の[付与](permissions.md#permissions-grants)メソッドがあります。以下の例では、IAM グループ `data-science` に対し、Amazon S3 バケット `raw-data` から読み取りを行うためのアクセス許可を付与します。

**Example**  

```
const rawData = new s3.Bucket(this, 'raw-data');
const dataScience = new iam.Group(this, 'data-science');
rawData.grants.read(dataScience);
```

```
const rawData = new s3.Bucket(this, 'raw-data');
const dataScience = new iam.Group(this, 'data-science');
rawData.grants.read(dataScience);
```

```
raw_data = s3.Bucket(self, 'raw-data')
data_science = iam.Group(self, 'data-science')
raw_data.grants.read(data_science)
```

```
Bucket rawData = new Bucket(this, "raw-data");
Group dataScience = new Group(this, "data-science");
rawData.getGrants().read(dataScience);
```

```
var rawData = new Bucket(this, "raw-data");
var dataScience = new Group(this, "data-science");
rawData.Grants.Read(dataScience);
```

```
	rawData := awss3.NewBucket(stack, jsii.String("raw-data"), nil)
	dataScience := awsiam.NewGroup(stack, jsii.String("data-science"), nil)
	rawData.Grants().Read(dataScience, nil)
```

もう 1 つの一般的なパターンは、 AWS コンストラクトが他の場所で提供されたデータからリソースの属性の 1 つを設定することです。属性には、Amazon リソースネーム (ARN)、名前、または URL などが含まれます。

次のコードは、 AWS Lambda 関数を定義し、環境変数のキューの URL を介して Amazon Simple Queue Service (Amazon SQS) キューに関連付けます。

**Example**  

```
const jobsQueue = new sqs.Queue(this, 'jobs');
const createJobLambda = new lambda.Function(this, 'create-job', {
  runtime: lambda.Runtime.NODEJS_18_X,
  handler: 'index.handler',
  code: lambda.Code.fromAsset('./create-job-lambda-code'),
  environment: {
    QUEUE_URL: jobsQueue.queueUrl
  }
});
```

```
const jobsQueue = new sqs.Queue(this, 'jobs');
const createJobLambda = new lambda.Function(this, 'create-job', {
  runtime: lambda.Runtime.NODEJS_18_X,
  handler: 'index.handler',
  code: lambda.Code.fromAsset('./create-job-lambda-code'),
  environment: {
    QUEUE_URL: jobsQueue.queueUrl
  }
});
```

```
jobs_queue = sqs.Queue(self, "jobs")
create_job_lambda = lambda_.Function(self, "create-job",
    runtime=lambda_.Runtime.NODEJS_18_X,
    handler="index.handler",
    code=lambda_.Code.from_asset("./create-job-lambda-code"),
    environment=dict(
        QUEUE_URL=jobs_queue.queue_url
    )
)
```

```
final Queue jobsQueue = new Queue(this, "jobs");
Function createJobLambda = Function.Builder.create(this, "create-job")
                .handler("index.handler")
                .code(Code.fromAsset("./create-job-lambda-code"))
                .environment(java.util.Map.of(   // Map.of is Java 9 or later
                    "QUEUE_URL", jobsQueue.getQueueUrl()))
                .build();
```

```
var jobsQueue = new Queue(this, "jobs");
var createJobLambda = new Function(this, "create-job", new FunctionProps
{
    Runtime = Runtime.NODEJS_18_X,
    Handler = "index.handler",
    Code = Code.FromAsset(@".\create-job-lambda-code"),
    Environment = new Dictionary<string, string>
    {
        ["QUEUE_URL"] = jobsQueue.QueueUrl
    }
});
```

```
	createJobLambda := awslambda.NewFunction(stack, jsii.String("create-job"), &awslambda.FunctionProps{
		Runtime: awslambda.Runtime_NODEJS_18_X(),
		Handler: jsii.String("index.handler"),
		Code:    awslambda.Code_FromAsset(jsii.String(".\\create-job-lambda-code"), nil),
		Environment: &map[string]*string{
			"QUEUE_URL": jsii.String(*jobsQueue.QueueUrl()),
		},
	})
```

コンストラクトライブラリの最も一般的な API AWS パターンについては、[「リソース」と AWS 「CDK](resources.md)」を参照してください。

### Mixins で機能を追加する
<a name="constructs-mixins"></a>

ミキサーは、 `.with()`メソッドを使用して任意のコンストラクトに適用できる構成可能な機能です。Mixins を使用すると、別のコンストラクトを使用したり、低レベルコードを記述したりすることなく、L1 および L2 コンストラクトに機能を追加できます。

例えば、L1 `CfnBucket`か L2 かにかかわらず、Amazon S3 バケットでバージョニングを有効にしてパブリックアクセスをブロックできます`Bucket`。

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

// Apply mixins to an L1 construct
new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());

// Apply mixins to an L2 construct
new s3.Bucket(this, 'MyL2Bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY })
  .with(new s3.mixins.BucketAutoDeleteObjects());
```

```
const cdk = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

// Apply mixins to an L1 construct
new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());

// Apply mixins to an L2 construct
new s3.Bucket(this, 'MyL2Bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY })
  .with(new s3.mixins.BucketAutoDeleteObjects());
```

```
import aws_cdk as cdk
import aws_cdk.aws_s3 as s3

# Apply mixins to an L1 construct
s3.CfnBucket(self, "MyBucket") \
    .with_(s3.mixins.BucketVersioning()) \
    .with_(s3.mixins.BucketBlockPublicAccess())

# Apply mixins to an L2 construct
s3.Bucket(self, "MyL2Bucket", removal_policy=cdk.RemovalPolicy.DESTROY) \
    .with_(s3.mixins.BucketAutoDeleteObjects())
```

```
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.s3.*;

// Apply mixins to an L1 construct
CfnBucket bucket = new CfnBucket(this, "MyBucket");
bucket.with(new BucketVersioning());
bucket.with(new BucketBlockPublicAccess());

// Apply mixins to an L2 construct
Bucket l2Bucket = Bucket.Builder.create(this, "MyL2Bucket")
        .removalPolicy(RemovalPolicy.DESTROY)
        .build();
l2Bucket.with(new BucketAutoDeleteObjects());
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

// Apply mixins to an L1 construct
var bucket = new CfnBucket(this, "MyBucket");
bucket.With(new BucketVersioning());
bucket.With(new BucketBlockPublicAccess());

// Apply mixins to an L2 construct
var l2Bucket = new Bucket(this, "MyL2Bucket", new BucketProps
{
    RemovalPolicy = RemovalPolicy.DESTROY
});
l2Bucket.With(new BucketAutoDeleteObjects());
```

```
bucket := awss3.NewCfnBucket(stack, jsii.String("MyBucket"), nil)
bucket.With(awss3.NewBucketVersioning())
bucket.With(awss3.NewBucketBlockPublicAccess())

l2Bucket := awss3.NewBucket(stack, jsii.String("MyL2Bucket"), &awss3.BucketProps{
    RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
})
l2Bucket.With(awss3.NewBucketAutoDeleteObjects())
```

ミキサーは、各サービスモジュール`mixins`の名前空間 ( など`s3.mixins`) から使用できます。各ミックスインは特定のリソースタイプをターゲットとし、そのリソースにちなんで命名されます。ミックスインを L2 コンストラクトに適用すると、そのミックスは基盤となる L1 リソースに自動的に適用されます。

Mixins の詳細については、[「Mixins](mixins.md)」を参照してください。

### アプリケーションとスタックのコンストラクト
<a name="constructs-apps-stacks"></a>

 AWS コンストラクトライブラリの [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html)および [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) クラスは一意のコンストラクトです。他のコンストラクトと比較して、リソース AWS は独自に設定されません。代わりに、他のコンストラクトにコンテキストを提供するために使用されます。 AWS リソースを表すすべてのコンストラクトは、`Stack`コンストラクトの範囲内で直接または間接的に定義する必要があります。 `Stack`コンストラクトは、`App`コンストラクトの範囲内で定義されます。

CDK アプリの詳細については、「[AWS CDK アプリ](apps.md)」を参照してください。CDK スタックの詳細については、[AWS 「CDK スタックの概要](stacks.md)」を参照してください。

以下の例では、単一のスタックを持つアプリケーションを定義します。スタック内では、L2 コンストラクトを使用して Amazon S3 バケットリソースを設定します。

**Example**  

```
import { App, Stack, StackProps } from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

class HelloCdkStack extends Stack {
  constructor(scope: App, id: string, props?: StackProps) {
    super(scope, id, props);

    new s3.Bucket(this, 'MyFirstBucket', {
      versioned: true
    });
  }
}

const app = new App();
new HelloCdkStack(app, "HelloCdkStack");
```

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

class HelloCdkStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    new s3.Bucket(this, 'MyFirstBucket', {
      versioned: true
    });
  }
}

const app = new App();
new HelloCdkStack(app, "HelloCdkStack");
```

```
from aws_cdk import App, Stack
import aws_cdk.aws_s3 as s3
from constructs import Construct

class HelloCdkStack(Stack):

    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        s3.Bucket(self, "MyFirstBucket", versioned=True)

app = App()
HelloCdkStack(app, "HelloCdkStack")
```
`HelloCdkStack.java` ファイルで定義されるスタック:  

```
import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.s3.*;

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);

        Bucket.Builder.create(this, "MyFirstBucket")
            .versioned(true).build();
    }
}
```
`HelloCdkApp.java` ファイルで定義されるアプリケーション:  

```
import software.amazon.awscdk.App;
import software.amazon.awscdk.StackProps;

public class HelloCdkApp {
    public static void main(final String[] args) {
        App app = new App();

        new HelloCdkStack(app, "HelloCdkStack", StackProps.builder()
                .build());

        app.synth();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

namespace HelloCdkApp
{
    internal static class Program
    {
        public static void Main(string[] args)
        {
            var app = new App();
            new HelloCdkStack(app, "HelloCdkStack");
            app.Synth();
        }
    }

    public class HelloCdkStack : Stack
    {
        public HelloCdkStack(Construct scope, string id, IStackProps props=null) : base(scope, id, props)
        {
            new Bucket(this, "MyFirstBucket", new BucketProps { Versioned = true });
        }
    }
}
```

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

	awss3.NewBucket(stack, jsii.String("MyFirstBucket"), &awss3.BucketProps{
		Versioned: jsii.Bool(true),
	})

	return stack
}
```

## コンストラクトの使用
<a name="constructs-work"></a>

### L1 コンストラクトの使用
<a name="constructs-l1-using"></a>

L1 コンストラクトは、個々の AWS CloudFormation リソースに直接マッピングされます。設定に必要なリソースは自分で用意しなければなりません。

この例では、L1 `CfnBucket` コンストラクトを使用して `bucket` オブジェクトを作成します。

**Example**  

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket"
});
```

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket"
});
```

```
bucket = s3.CfnBucket(self, "amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket")
```

```
CfnBucket bucket = new CfnBucket.Builder().bucketName("amzn-s3-demo-bucket").build();
```

```
var bucket = new CfnBucket(this, "amzn-s3-demo-bucket", new CfnBucketProps
{
    BucketName= "amzn-s3-demo-bucket"
});
```

```
	awss3.NewCfnBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.CfnBucketProps{
		BucketName: jsii.String("amzn-s3-demo-bucket"),
	})
```

単純なブール語、文字列、数値、コンテナではないコンストラクトのプロパティは、サポートされている言語ごとに異なる方法で処理されます。

**Example**  

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket",
  corsConfiguration: {
    corsRules: [{
          allowedOrigins: ["*"],
          allowedMethods: ["GET"]
    }]
  }
});
```

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket",
  corsConfiguration: {
    corsRules: [{
          allowedOrigins: ["*"],
          allowedMethods: ["GET"]
    }]
  }
});
```
Python では、これらのプロパティは L1 コンストラクトの内部クラスとして定義された型として表現されます。たとえば、`CfnBucket` のオプションプロパティ `cors_configuration` には、`CfnBucket.CorsConfigurationProperty` 型のラッパーが必要です。ここでは、`CfnBucket` インスタンスで `cors_configuration` を定義しています。  

```
bucket = CfnBucket(self, "amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket",
    cors_configuration=CfnBucket.CorsConfigurationProperty(
        cors_rules=[CfnBucket.CorsRuleProperty(
            allowed_origins=["*"],
            allowed_methods=["GET"]
        )]
    )
)
```
Java では、これらのプロパティは L1 コンストラクトの内部クラスとして定義された型として表現されます。たとえば、`CfnBucket` のオプションプロパティ `corsConfiguration` には、`CfnBucket.CorsConfigurationProperty` 型のラッパーが必要です。ここでは、`CfnBucket` インスタンスで `corsConfiguration` を定義しています。  

```
CfnBucket bucket = CfnBucket.Builder.create(this, "amzn-s3-demo-bucket")
                        .bucketName("amzn-s3-demo-bucket")
                        .corsConfiguration(new CfnBucket.CorsConfigurationProperty.Builder()
                            .corsRules(Arrays.asList(new CfnBucket.CorsRuleProperty.Builder()
                                .allowedOrigins(Arrays.asList("*"))
                                .allowedMethods(Arrays.asList("GET"))
                                .build()))
                            .build())
                        .build();
```
C\$1 では、これらのプロパティは L1 コンストラクトの内部クラスとして定義された型として表現されます。たとえば、`CfnBucket` のオプションプロパティ `CorsConfiguration` には、`CfnBucket.CorsConfigurationProperty` 型のラッパーが必要です。ここでは、`CfnBucket` インスタンスで `CorsConfiguration` を定義しています。  

```
var bucket = new CfnBucket(this, "amzn-s3-demo-bucket", new CfnBucketProps
{
    BucketName = "amzn-s3-demo-bucket",
    CorsConfiguration = new CfnBucket.CorsConfigurationProperty
    {
        CorsRules = new object[] {
            new CfnBucket.CorsRuleProperty
            {
                AllowedOrigins = new string[] { "*" },
                AllowedMethods = new string[] { "GET" },
            }
        }
    }
});
```
Go では、これらの型は L1 コンストラクトの名前、アンダースコア、プロパティ名を使用して命名されます。たとえば、`CfnBucket` のオプションプロパティ `CorsConfiguration` には、`CfnBucket_CorsConfigurationProperty` 型のラッパーが必要です。ここでは、`CfnBucket` インスタンスで `CorsConfiguration` を定義しています。  

```
	awss3.NewCfnBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.CfnBucketProps{
		BucketName: jsii.String("amzn-s3-demo-bucket"),
		CorsConfiguration: &awss3.CfnBucket_CorsConfigurationProperty{
			CorsRules: []awss3.CorsRule{
				awss3.CorsRule{
					AllowedOrigins: jsii.Strings("*"),
					AllowedMethods: &[]awss3.HttpMethods{"GET"},
				},
			},
		},
	})
```

**重要**  
L1 コンストラクトで L2 プロパティタイプを使用することはできません。その逆も同様です。L1 コンストラクトを使用する場合は、使用している L1 コンストラクトに定義されているタイプを必ず使用してください。他の L1 コンストラクトの型を使用しないでください (名前が同じものもありますが、同じ型ではありません)。  
言語固有の API リファレンスの中には、現在 L1 プロパティタイプへのパスにエラーがあるか、これらのクラスがまったく記載されていないものがあります。これは近いうちに修正したいと考えています。それまでの間、このような型は常に、それらが使用される L1 コンストラクトの内部クラスであることに注意してください。

#### 他のコンストラクトからのリソースの参照
<a name="constructs-resource-references"></a>

他の AWS リソースを参照するコンストラクトプロパティを設定する場合、2 つの同等のオプションがあります。
+  **文字列参照**: ARNs、名前、その他のリソース識別子などの明示的な文字列値を渡す
+  **オブジェクト参照**: コンストラクトオブジェクトを直接渡します。これにより、プロパティが期待する識別子タイプを決定する必要がなくなります。CDK がそれを処理します。

##### 文字列参照の使用
<a name="_using_string_references"></a>

ARNs、その他のリソース識別子などの明示的な文字列値を渡すことができます。このアプローチはすべてのプロパティで機能し、複雑なオブジェクト内のネストされたプロパティに必要です。

次の例では、L2 コンストラクト () を使用して定義されたロールを持つ L1 コンストラクト () を使用して Lambda 関数を作成します`Role`。`CfnFunction` L2 ロールの ARN は `role`プロパティに渡されます。

**Example**  

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    ),
  ],
});

const myFunction = new lambda.CfnFunction(this, 'HelloWorldFunction', {
  runtime: 'nodejs24.x',
  role: role.roleArn, // Pass the ARN string explicitly
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});
```

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    )
  ]
});

const myFunction = new lambda.CfnFunction(this, "HelloWorldFunction", {
  runtime: 'nodejs24.x',
  role: role.roleArn, // Pass the ARN string explicitly
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});
```

```
role = iam.Role(self, "MyRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
    managed_policies=[
        iam.ManagedPolicy.from_aws_managed_policy_name(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ]
)

my_function = _lambda.CfnFunction(self, "HelloWorldFunction",
    runtime="nodejs24.x",
    role=role.role_arn,  # Pass the ARN string explicitly
    handler="index.handler",
    code=_lambda.CfnFunction.CodeProperty(
        zip_file=
        """
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        """
    )
)
```

```
Role role = Role.Builder.create(this, "MyRole")
    .assumedBy(new ServicePrincipal("lambda.amazonaws.com"))
    .managedPolicies(Arrays.asList(
        ManagedPolicy.fromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ))
    .build();

CfnFunction myFunction = CfnFunction.Builder.create(this, "HelloWorldFunction")
    .runtime("nodejs24.x")
    .role(role.getRoleArn())  // Pass the ARN string explicitly
    .handler("index.handler")
    .code(CfnFunction.CodeProperty.builder()
        .zipFile(
            "exports.handler = async function(event) {" +
            "  return {" +
            "    statusCode: 200," +
            "    body: JSON.stringify('Hello World!')," +
            "  };" +
            "};")
        .build())
    .build();
```

```
var role = new Role(this, "MyRole", new RoleProps
{
    AssumedBy = new ServicePrincipal("lambda.amazonaws.com"),
    ManagedPolicies = new[]
    {
        ManagedPolicy.FromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    }
});

var myFunction = new CfnFunction(this, "HelloWorldFunction", new CfnFunctionProps
{
    Runtime = "nodejs24.x",
    Role = role.RoleArn,  // Pass the ARN string explicitly
    Handler = "index.handler",
    Code = new CfnFunction.CodeProperty
    {
        ZipFile = @"
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        "
    }
});
```

```
role := awsiam.NewRole(stack, jsii.String("MyRole"), &awsiam.RoleProps{
	AssumedBy: awsiam.NewServicePrincipal(jsii.String("lambda.amazonaws.com"), nil),
	ManagedPolicies: &[]awsiam.IManagedPolicy{
		awsiam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("service-role/AWSLambdaBasicExecutionRole")),
	},
})

myFunction := awslambda.NewCfnFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.CfnFunctionProps{
	Runtime: jsii.String("nodejs24.x"),
	Role:    role.RoleArn(), // Pass the ARN string explicitly
	Handler: jsii.String("index.handler"),
	Code: &awslambda.CfnFunction_CodeProperty{
		ZipFile: jsii.String(`
		exports.handler = async function(event) {
		  return {
		    statusCode: 200,
		    body: JSON.stringify('Hello World!'),
		  };
		};
		`),
	},
})
```

##### オブジェクトリファレンスの使用
<a name="_using_object_references"></a>

選択したプロパティでは、コンストラクトオブジェクトを手動で抽出する代わりに、コンストラクトオブジェクトを直接渡すことができます。オブジェクト参照のサポートはプロパティによって異なり、新しいプロパティが追加されると時間の経過とともに拡張される可能性があります。

コンストラクトの でオブジェクト参照を渡すと`props`、CDK はそれを適切な文字列値 (ARN、名前、その他の識別子など) に解決します。後でコンストラクトインスタンスの対応するプロパティにアクセスすると、元のオブジェクトリファレンスではなく、この解決された文字列値が表示されます。

オブジェクト参照は、コンストラクトの最上位プロパティでのみ機能します。複雑なオブジェクト内にネストされたプロパティには、明示的な文字列値が必要です。

次の例は、同じ Lambda 関数を示していますが、ロールの ARN 文字列の代わりにロールオブジェクトを使用します。

**Example**  

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    ),
  ],
});

const myFunction = new lambda.CfnFunction(this, 'HelloWorldFunction', {
  runtime: 'nodejs24.x',
  role: role, // CDK resolves to role ARN automatically
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});

// After creation, myFunction.role contains the resolved ARN string
```

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    )
  ]
});

const myFunction = new lambda.CfnFunction(this, "HelloWorldFunction", {
  runtime: 'nodejs24.x',
  role: role, // CDK resolves to role ARN automatically
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});

// After creation, myFunction.role contains the resolved ARN string
```

```
role = iam.Role(self, "MyRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
    managed_policies=[
        iam.ManagedPolicy.from_aws_managed_policy_name(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ]
)

my_function = _lambda.CfnFunction(self, "HelloWorldFunction",
    runtime="nodejs24.x",
    role=role,  # CDK resolves to role ARN automatically
    handler="index.handler",
    code=_lambda.CfnFunction.CodeProperty(
        zip_file=
        """
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        """
    )
)

# After creation, my_function.role contains the resolved ARN string
```

```
Role role = Role.Builder.create(this, "MyRole")
    .assumedBy(new ServicePrincipal("lambda.amazonaws.com"))
    .managedPolicies(Arrays.asList(
        ManagedPolicy.fromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ))
    .build();

CfnFunction myFunction = CfnFunction.Builder.create(this, "HelloWorldFunction")
    .runtime("nodejs24.x")
    .role(role)  // CDK resolves to role ARN automatically
    .handler("index.handler")
    .code(CfnFunction.CodeProperty.builder()
        .zipFile(
            "exports.handler = async function(event) {" +
            "  return {" +
            "    statusCode: 200," +
            "    body: JSON.stringify('Hello World!')," +
            "  };" +
            "};")
        .build())
    .build();

// After creation, myFunction.getRole() contains the resolved ARN string
```

```
var role = new Role(this, "MyRole", new RoleProps
{
    AssumedBy = new ServicePrincipal("lambda.amazonaws.com"),
    ManagedPolicies = new[]
    {
        ManagedPolicy.FromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    }
});

var myFunction = new CfnFunction(this, "HelloWorldFunction", new CfnFunctionProps
{
    Runtime = "nodejs24.x",
    Role = role,  // CDK resolves to role ARN automatically
    Handler = "index.handler",
    Code = new CfnFunction.CodeProperty
    {
        ZipFile = @"
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        "
    }
});

// After creation, myFunction.Role contains the resolved ARN string
```

```
role := awsiam.NewRole(stack, jsii.String("MyRole"), &awsiam.RoleProps{
	AssumedBy: awsiam.NewServicePrincipal(jsii.String("lambda.amazonaws.com"), nil),
	ManagedPolicies: &[]awsiam.IManagedPolicy{
		awsiam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("service-role/AWSLambdaBasicExecutionRole")),
	},
})

myFunction := awslambda.NewCfnFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.CfnFunctionProps{
	Runtime: jsii.String("nodejs24.x"),
	Role:    role, // CDK resolves to role ARN automatically
	Handler: jsii.String("index.handler"),
	Code: &awslambda.CfnFunction_CodeProperty{
		ZipFile: jsii.String(`
		exports.handler = async function(event) {
		  return {
		    statusCode: 200,
		    body: JSON.stringify('Hello World!'),
		  };
		};
		`),
	},
})

// After creation, *myFunction.Role() contains the resolved ARN string
```

### L2 コンストラクトの使用
<a name="constructs-using"></a>

以下の例では、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html) L2 コンストラクトからオブジェクトを作成して、Amazon S3 バケットを定義します。

**Example**  

```
import * as s3 from 'aws-cdk-lib/aws-s3';

// "this" is HelloCdkStack
new s3.Bucket(this, 'MyFirstBucket', {
  versioned: true
});
```

```
const s3 = require('aws-cdk-lib/aws-s3');

// "this" is HelloCdkStack
new s3.Bucket(this, 'MyFirstBucket', {
  versioned: true
});
```

```
import aws_cdk.aws_s3 as s3

# "self" is HelloCdkStack
s3.Bucket(self, "MyFirstBucket", versioned=True)
```

```
import software.amazon.awscdk.services.s3.*;

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);

        Bucket.Builder.create(this, "MyFirstBucket")
                .versioned(true).build();
    }
}
```

```
using Amazon.CDK.AWS.S3;

// "this" is HelloCdkStack
new Bucket(this, "MyFirstBucket", new BucketProps
{
    Versioned = true
});
```

```
import (
	"github.com/aws/aws-cdk-go/awscdk/v2/awss3"
	"github.com/aws/jsii-runtime-go"
)

// stack is HelloCdkStack
awss3.NewBucket(stack, jsii.String("MyFirstBucket"), &awss3.BucketProps{
		Versioned: jsii.Bool(true),
	})
```

 `MyFirstBucket` は、 AWS CloudFormation が作成するバケットの名前ではありません。これは、CDK アプリケーションのコンテキスト内で新しいコンストラクトに与えられる論理識別子です。[physicalName](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Resource.html#physicalname) 値は、 AWS CloudFormation リソースに名前を付けるために使用されます。

## サードパーティーのコンストラクトの使用
<a name="constructs-work-third"></a>

 [Construct Hub ](https://constructs.dev/search?q=&cdk=aws-cdk&cdkver=2&sort=downloadsDesc&offset=0)は、、サードパーティー AWS、オープンソース CDK コミュニティから追加のコンストラクトを発見するのに役立つリソースです。

### 独自のコンストラクトの作成
<a name="constructs-author"></a>

既存のコンストラクトを使用するだけでなく、独自のコンストラクトを記述し、誰でもアプリで使用できるようにすることもできます。 AWS CDK では、すべてのコンストラクトが等しくなります。コンストラクトライブラリからの AWS コンストラクトは、NPM、、Mavenまたは を介して公開されたサードパーティーライブラリからのコンストラクトと同じように扱われますPyPI。また、社内のパッケージリポジトリに公開されたコンストラクトも同じように扱われます。

新しいコンストラクトを宣言するには、[Construct](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html) 基底クラスを拡張するクラスを `constructs` パッケージで作成し、初期化引数のパターンに従います。

以下の例は、Amazon S3 バケットを表すコンストラクトを宣言する方法を示しています。S3 バケットは、誰かがファイルをアップロードするたびに Amazon Simple Notiﬁcation Service (Amazon SNS) 通知を送信します。

**Example**  

```
export interface NotifyingBucketProps {
  prefix?: string;
}

export class NotifyingBucket extends Construct {
  constructor(scope: Construct, id: string, props: NotifyingBucketProps = {}) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    const topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(topic),
      { prefix: props.prefix });
  }
}
```

```
class NotifyingBucket extends Construct {
  constructor(scope, id, props = {}) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    const topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(topic),
      { prefix: props.prefix });
  }
}

module.exports = { NotifyingBucket }
```

```
class NotifyingBucket(Construct):

    def __init__(self, scope: Construct, id: str, *, prefix=None):
        super().__init__(scope, id)
        bucket = s3.Bucket(self, "bucket")
        topic = sns.Topic(self, "topic")
        bucket.add_object_created_notification(s3notify.SnsDestination(topic),
            s3.NotificationKeyFilter(prefix=prefix))
```

```
public class NotifyingBucket extends Construct {

    public NotifyingBucket(final Construct scope, final String id) {
        this(scope, id, null, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props) {
        this(scope, id, props, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final String prefix) {
        this(scope, id, null, prefix);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props, final String prefix) {
        super(scope, id);

        Bucket bucket = new Bucket(this, "bucket");
        Topic topic = new Topic(this, "topic");
        if (prefix != null)
            bucket.addObjectCreatedNotification(new SnsDestination(topic),
                NotificationKeyFilter.builder().prefix(prefix).build());
     }
}
```

```
public class NotifyingBucketProps : BucketProps
{
    public string Prefix { get; set; }
}

public class NotifyingBucket : Construct
{
    public NotifyingBucket(Construct scope, string id, NotifyingBucketProps props = null) : base(scope, id)
    {
        var bucket = new Bucket(this, "bucket");
        var topic = new Topic(this, "topic");
        bucket.AddObjectCreatedNotification(new SnsDestination(topic), new NotificationKeyFilter
        {
            Prefix = props?.Prefix
        });
    }
}
```

```
type NotifyingBucketProps struct {
	awss3.BucketProps
	Prefix *string
}

func NewNotifyingBucket(scope constructs.Construct, id *string, props *NotifyingBucketProps) awss3.Bucket {
	var bucket awss3.Bucket
	if props == nil {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), nil)
	} else {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), &props.BucketProps)
	}
	topic := awssns.NewTopic(scope, jsii.String(*id+"Topic"), nil)
	if props == nil {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic))
	} else {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic), &awss3.NotificationKeyFilter{
			Prefix: props.Prefix,
		})
	}
	return bucket
}
```

**注記**  
`NotifyingBucket` コンストラクトは、`Bucket` ではなく、`Construct` を継承しています。これは、Amazon S3 バケットと Amazon SNS トピックをバンドルするために、継承ではなく構成を使用しているためです。一般的に、 AWS CDK コンストラクトを開発する場合、コンポジションは継承よりも優先されます。

`NotifyingBucket` コンストラクターは、`scope`、`id`、`props` という典型的なコンストラクトの署名を持っています。最後に挙げた引数 `props` は、props はすべてオプションであるため、オプション (デフォルト値 `{}`) になります。(規定クラス `Construct` は `props` 引数を取りません)。このコンストラクトのインスタンスは、`props` なしでアプリに定義できます。たとえば以下のようになります。

**Example**  

```
new NotifyingBucket(this, 'MyNotifyingBucket');
```

```
new NotifyingBucket(this, 'MyNotifyingBucket');
```

```
NotifyingBucket(self, "MyNotifyingBucket")
```

```
new NotifyingBucket(this, "MyNotifyingBucket");
```

```
new NotifyingBucket(this, "MyNotifyingBucket");
```

```
NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), nil)
```

または、`props` (Java では追加パラメータ) を使用して、フィルタリングするパスプレフィックスを指定できます。たとえば以下のようになります。

**Example**  

```
new NotifyingBucket(this, 'MyNotifyingBucket', { prefix: 'images/' });
```

```
new NotifyingBucket(this, 'MyNotifyingBucket', { prefix: 'images/' });
```

```
NotifyingBucket(self, "MyNotifyingBucket", prefix="images/")
```

```
new NotifyingBucket(this, "MyNotifyingBucket", "/images");
```

```
new NotifyingBucket(this, "MyNotifyingBucket", new NotifyingBucketProps
{
    Prefix = "/images"
});
```

```
NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), &NotifyingBucketProps{
	Prefix: jsii.String("images/"),
})
```

通常、コンストラクト上のいくつかのプロパティまたはメソッドも公開する必要があります。コンストラクトの背後にトピックが隠れてしまう形では、コンストラクトのユーザーがサブスクライブできなくなるため、あまり有益とは言えません。`topic` プロパティを追加すると、以下の例に示すように、利用者が内部トピックにアクセスできるようになります。

**Example**  

```
export class NotifyingBucket extends Construct {
  public readonly topic: sns.Topic;

  constructor(scope: Construct, id: string, props: NotifyingBucketProps) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    this.topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(this.topic), { prefix: props.prefix });
  }
}
```

```
class NotifyingBucket extends Construct {

  constructor(scope, id, props) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    this.topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(this.topic), { prefix: props.prefix });
  }
}

module.exports = { NotifyingBucket };
```

```
class NotifyingBucket(Construct):

    def __init__(self, scope: Construct, id: str, *, prefix=None, **kwargs):
        super().__init__(scope, id)
        bucket = s3.Bucket(self, "bucket")
        self.topic = sns.Topic(self, "topic")
        bucket.add_object_created_notification(s3notify.SnsDestination(self.topic),
            s3.NotificationKeyFilter(prefix=prefix))
```

```
public class NotifyingBucket extends Construct {

    public Topic topic = null;

    public NotifyingBucket(final Construct scope, final String id) {
        this(scope, id, null, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props) {
        this(scope, id, props, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final String prefix) {
        this(scope, id, null, prefix);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props, final String prefix) {
        super(scope, id);

        Bucket bucket = new Bucket(this, "bucket");
        topic = new Topic(this, "topic");
        if (prefix != null)
            bucket.addObjectCreatedNotification(new SnsDestination(topic),
                NotificationKeyFilter.builder().prefix(prefix).build());
     }
}
```

```
public class NotifyingBucket : Construct
{
    public readonly Topic topic;

    public NotifyingBucket(Construct scope, string id, NotifyingBucketProps props = null) : base(scope, id)
    {
        var bucket = new Bucket(this, "bucket");
        topic = new Topic(this, "topic");
        bucket.AddObjectCreatedNotification(new SnsDestination(topic), new NotificationKeyFilter
        {
            Prefix = props?.Prefix
        });
    }
}
```
Go でこれを実行するには、少し追加の準備が必要です。元の `NewNotifyingBucket` 関数は、そのままでは `awss3.Bucket` を返します。そこで、`NotifyingBucket` 構造体を作成して、`topic` メンバーを含めるように `Bucket` を拡張する必要があります。そうすることで、この関数はこの型を返すようになります。  

```
type NotifyingBucket struct {
	awss3.Bucket
	topic awssns.Topic
}

func NewNotifyingBucket(scope constructs.Construct, id *string, props *NotifyingBucketProps) NotifyingBucket {
	var bucket awss3.Bucket
	if props == nil {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), nil)
	} else {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), &props.BucketProps)
	}
	topic := awssns.NewTopic(scope, jsii.String(*id+"Topic"), nil)
	if props == nil {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic))
	} else {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic), &awss3.NotificationKeyFilter{
			Prefix: props.Prefix,
		})
	}
	var nbucket NotifyingBucket
	nbucket.Bucket = bucket
	nbucket.topic = topic
	return nbucket
}
```

これで、利用者はトピックをサブスクライブできるようになりました。たとえば以下のようになります。

**Example**  

```
const queue = new sqs.Queue(this, 'NewImagesQueue');
const images = new NotifyingBucket(this, '/images');
images.topic.addSubscription(new sns_sub.SqsSubscription(queue));
```

```
const queue = new sqs.Queue(this, 'NewImagesQueue');
const images = new NotifyingBucket(this, '/images');
images.topic.addSubscription(new sns_sub.SqsSubscription(queue));
```

```
queue = sqs.Queue(self, "NewImagesQueue")
images = NotifyingBucket(self, prefix="Images")
images.topic.add_subscription(sns_sub.SqsSubscription(queue))
```

```
NotifyingBucket images = new NotifyingBucket(this, "MyNotifyingBucket", "/images");
images.topic.addSubscription(new SqsSubscription(queue));
```

```
var queue = new Queue(this, "NewImagesQueue");
var images = new NotifyingBucket(this, "MyNotifyingBucket", new NotifyingBucketProps
{
    Prefix = "/images"
});
images.topic.AddSubscription(new SqsSubscription(queue));
```

```
	queue := awssqs.NewQueue(stack, jsii.String("NewImagesQueue"), nil)
	images := NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), &NotifyingBucketProps{
		Prefix: jsii.String("/images"),
	})
	images.topic.AddSubscription(awssnssubscriptions.NewSqsSubscription(queue, nil))
```

## 詳細情報
<a name="constructs-learn"></a>

以下のビデオでは、CDK コンストラクトの包括的な概要と、CDK アプリケーションでの CDK コンストラクトの使用方法について説明します。

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/PzU-i0rJPGw?rel=0/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/PzU-i0rJPGw?rel=0)


# 混合
<a name="mixins"></a>

ミキサーは、 `.with()`メソッドを使用してコンストラクトに適用する再利用可能な機能です。バージョニング、オブジェクトの自動削除、パブリックアクセスのブロックなど、L1 (CloudFormation レベル) コンストラクトと L2 (インテントベース) コンストラクトの両方に機能を追加します。各ミキサーは 1 つのリソースで機能します。2 つのリソースを接続するには、代わりに[ファサード](facades.md)を使用します。

各ミックスインは特定のリソースタイプをターゲットとし、そのリソースにちなんで命名されます。たとえば、 は Amazon S3 バケットを`BucketVersioning`ターゲットにします。などの各サービスモジュール`mixins`の名前空間からミックスインにアクセスします`s3.mixins`。

## ミキサーの適用
<a name="mixins-basic"></a>

すべてのコンストラクトで使用できる `.with()`メソッドを使用して、ミキサーを適用します。複数のミキサーを連結できます。

**Example**  

```
import * as s3 from 'aws-cdk-lib/aws-s3';

const bucket = new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());
```

```
const s3 = require('aws-cdk-lib/aws-s3');

const bucket = new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());
```

```
import aws_cdk.aws_s3 as s3

bucket = s3.CfnBucket(self, "MyBucket") \
    .with_(s3.mixins.BucketVersioning()) \
    .with_(s3.mixins.BucketBlockPublicAccess())
```

```
import software.amazon.awscdk.services.s3.*;

CfnBucket bucket = new CfnBucket(this, "MyBucket");
bucket.with(new BucketVersioning());
bucket.with(new BucketBlockPublicAccess());
```

```
using Amazon.CDK.AWS.S3;

var bucket = new CfnBucket(this, "MyBucket");
bucket.With(new BucketVersioning());
bucket.With(new BucketBlockPublicAccess());
```

```
bucket := awss3.NewCfnBucket(stack, jsii.String("MyBucket"), nil)
bucket.With(awss3.NewBucketVersioning())
bucket.With(awss3.NewBucketBlockPublicAccess())
```

各 mixin は、サポートするリソースタイプを宣言します。サポートされていないコンストラクトにミックスインを適用すると、サイレントにスキップされます。つまり、タイプの不一致を気にすることなく、ミクシンを広範囲に安全に適用できます。ミキサーが適用されていることを確認する必要がある場合は、 [`requireAll()`または `requireAny()`](#mixins-advanced)を使用します。

## L1 および L2 コンストラクトで Mixins を使用する
<a name="mixins-l1-l2"></a>

ミキサーは L1 コンストラクトと L2 コンストラクトの両方で機能します。ミックスインを L2 コンストラクトに適用すると、その背後にある L1 リソースにも適用されます。

次の例は、L1 コンストラクトと L2 コンストラクトの両方にミクシンを適用する方法を示しています。

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

// Using a mixin with an L1 construct
new s3.CfnBucket(this, 'L1Bucket')
  .with(new s3.mixins.BucketVersioning());

// Using a mixin with an L2 construct
new s3.Bucket(this, 'L2Bucket', {
  removalPolicy: cdk.RemovalPolicy.DESTROY,
}).with(new s3.mixins.BucketAutoDeleteObjects());
```

```
const cdk = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

// Using a mixin with an L1 construct
new s3.CfnBucket(this, 'L1Bucket')
  .with(new s3.mixins.BucketVersioning());

// Using a mixin with an L2 construct
new s3.Bucket(this, 'L2Bucket', {
  removalPolicy: cdk.RemovalPolicy.DESTROY,
}).with(new s3.mixins.BucketAutoDeleteObjects());
```

```
import aws_cdk as cdk
import aws_cdk.aws_s3 as s3

# Using a mixin with an L1 construct
s3.CfnBucket(self, "L1Bucket") \
    .with_(s3.mixins.BucketVersioning())

# Using a mixin with an L2 construct
s3.Bucket(self, "L2Bucket",
    removal_policy=cdk.RemovalPolicy.DESTROY,
).with_(s3.mixins.BucketAutoDeleteObjects())
```

```
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.s3.*;

// Using a mixin with an L1 construct
CfnBucket l1Bucket = new CfnBucket(this, "L1Bucket");
l1Bucket.with(new BucketVersioning());

// Using a mixin with an L2 construct
Bucket l2Bucket = Bucket.Builder.create(this, "L2Bucket")
        .removalPolicy(RemovalPolicy.DESTROY)
        .build();
l2Bucket.with(new BucketAutoDeleteObjects());
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

// Using a mixin with an L1 construct
var l1Bucket = new CfnBucket(this, "L1Bucket");
l1Bucket.With(new BucketVersioning());

// Using a mixin with an L2 construct
var l2Bucket = new Bucket(this, "L2Bucket", new BucketProps
{
    RemovalPolicy = RemovalPolicy.DESTROY
});
l2Bucket.With(new BucketAutoDeleteObjects());
```

```
l1Bucket := awss3.NewCfnBucket(stack, jsii.String("L1Bucket"), nil)
l1Bucket.With(awss3.NewBucketVersioning())

l2Bucket := awss3.NewBucket(stack, jsii.String("L2Bucket"), &awss3.BucketProps{
    RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
})
l2Bucket.With(awss3.NewBucketAutoDeleteObjects())
```

## 混合とコンストラクトのプロパティ
<a name="mixins-vs-props"></a>

混合プロパティとコンストラクトプロパティは連携します。L2 コンストラクトプロパティは、作成時にリソースを設定します。ミキサーはいつでも適用できます。

次の場合に L2 コンストラクトプロパティを使用する  
L2 コンストラクトを使用しており、必要な プロパティを使用できます。これは最も簡単なアプローチです。

次の場合に Mixins を使用する  
+ L1 コンストラクトを使用していて、L2-like機能が必要です。
+ プロパティとして使用できない L2 コンストラクトに機能を追加します。
+ 異なるタイプの複数のコンストラクトに同じ機能を適用する場合。

Mixins はコンストラクトプロパティを置き換えません。必須プロパティをオプションにしたり、デフォルト値を変更したりすることはできません。

## 複数のコンストラクトに Mixins を適用する
<a name="mixins-advanced"></a>

`Mixins.of()` API は、スコープ全体にミクシンがどのように適用されるかをより詳細に制御します。個々のコンストラクト`.with()`を呼び出す代わりに、スタックまたはスコープ内のすべての一致するコンストラクトに一度にミックスインを適用できます。

**Example**  

```
import { Mixins } from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

// Apply to all supported constructs in the stack
Mixins.of(stack).apply(new s3.mixins.BucketVersioning());
```

```
const { Mixins } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

// Apply to all supported constructs in the stack
Mixins.of(stack).apply(new s3.mixins.BucketVersioning());
```

```
from aws_cdk import Mixins
import aws_cdk.aws_s3 as s3

# Apply to all supported constructs in the stack
Mixins.of(stack).apply(s3.mixins.BucketVersioning())
```

```
import software.amazon.awscdk.Mixins;
import software.amazon.awscdk.services.s3.*;

// Apply to all supported constructs in the stack
Mixins.of(stack).apply(new BucketVersioning());
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

// Apply to all supported constructs in the stack
Mixins.Of(stack).Apply(new BucketVersioning());
```

```
awscdk.Mixins_Of(stack, nil).Apply(awss3.NewBucketVersioning())
```

デフォルトでは、ミキサーをサポートしていないコンストラクトはサイレントにスキップされます。`requireAll()` を使用して、ミキサーが選択内のすべてのコンストラクトに適用されることをアサート`requireAny()`するか、少なくとも 1 つに適用されることをアサートします。これは、リソースに必要な設定を強制するのに役立ちます。

**Example**  

```
// Throws an error if any construct in the scope doesn't support the mixin
Mixins.of(stack)
  .requireAll()
  .apply(new s3.mixins.BucketVersioning());
```

```
// Throws an error if any construct in the scope doesn't support the mixin
Mixins.of(stack)
  .requireAll()
  .apply(new s3.mixins.BucketVersioning());
```

```
# Throws an error if any construct in the scope doesn't support the mixin
Mixins.of(stack) \
    .require_all() \
    .apply(s3.mixins.BucketVersioning())
```

```
// Throws an error if any construct in the scope doesn't support the mixin
Mixins.of(stack)
        .requireAll()
        .apply(new BucketVersioning());
```

```
// Throws an error if any construct in the scope doesn't support the mixin
Mixins.Of(stack)
    .RequireAll()
    .Apply(new BucketVersioning());
```

```
awscdk.Mixins_Of(stack, nil).RequireAll().Apply(awss3.NewBucketVersioning())
```

## 混合と側面
<a name="mixins-aspects"></a>

ミックスと[アスペクト](aspects.md)は関連していますが、目的は異なります。
+  **混合**は、 を呼び出すとすぐに適用されます`.with()`。適用するコンストラクトを正確に選択します。
+  **アスペクトは**、合成中にスコープ内のすべてのコンストラクトに適用されます。広範なポリシーとチェックに使用します。

Mixins を使用して、特定のコンストラクトに機能を追加します。アスペクトを使用して、アプリケーション全体にルールを適用したり、変更を適用したりします。

## 関連リソース
<a name="mixins-related"></a>
+  [ファサード](facades.md) – リソースを IAM プリンシパルやその他のサービスに接続します。
+  [側面](aspects.md) – アプリケーション全体に変更を適用するか、コンストラクトを検証します。
+  [コンストラクト](constructs.md) – L1, L2、L3 コンストラクトについて説明します。
+  [コンストラクトのカスタマイズ](cfn-layer.md) – エスケープハッチと raw オーバーライドを使用してコンストラクトをカスタマイズします。

# ファサード
<a name="facades"></a>

ファサードは、リソースをアプリケーションの他の部分に接続するクラスです。各ファサードは 1 つのリソースタイプを対象としています。例えば、クラス は Amazon S3 バケットへのアクセスを許可する`BucketGrants`ため、 という名前が付けられます。ファサードは、L1 (CloudFormation レベル) コンストラクトと L2 (インテントベース) コンストラクトの両方で機能します。

一部のファサードが生成され、メトリクスやリフレクションクラスなど、ほとんどのリソースで使用できるようになります。その他の は、 Grants クラスなど、カスタムロジックを必要とするリソースに対して手動で作成されます。

## クラスを付与します
<a name="facades-grants"></a>

最も広く使用されているファサードは Grants クラスです。これにより、シンプルな方法を使用して AWS リソースへのアクセスを許可できます。例えば、Amazon S3 バケット`BucketGrants`には を、Amazon SNS トピック`TopicGrants`には を使用できます。 Amazon SNS 

L2 コンストラクトには、アクセスしやすい`grants`プロパティがあります。ファクトリメソッドを使用して、L1 コンストラクトから Grants クラスを作成することもできます。次の例は、両方のアプローチを示しています。

**Example**  

```
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';

// myRole is an IAM role defined elsewhere in your app

// Using grants on an L2 construct (via the grants property)
const l2Bucket = new s3.Bucket(this, 'L2Bucket');
l2Bucket.grants.read(myRole);

// Using grants on an L1 construct (via the factory method)
const l1Bucket = new s3.CfnBucket(this, 'L1Bucket');
s3.BucketGrants.fromBucket(l1Bucket).read(myRole);
```

```
const s3 = require('aws-cdk-lib/aws-s3');
const iam = require('aws-cdk-lib/aws-iam');

// myRole is an IAM role defined elsewhere in your app

// Using grants on an L2 construct (via the grants property)
const l2Bucket = new s3.Bucket(this, 'L2Bucket');
l2Bucket.grants.read(myRole);

// Using grants on an L1 construct (via the factory method)
const l1Bucket = new s3.CfnBucket(this, 'L1Bucket');
s3.BucketGrants.fromBucket(l1Bucket).read(myRole);
```

```
import aws_cdk.aws_s3 as s3
import aws_cdk.aws_iam as iam

# my_role is an IAM role defined elsewhere in your app

# Using grants on an L2 construct (via the grants property)
l2_bucket = s3.Bucket(self, "L2Bucket")
l2_bucket.grants.read(my_role)

# Using grants on an L1 construct (via the factory method)
l1_bucket = s3.CfnBucket(self, "L1Bucket")
s3.BucketGrants.from_bucket(l1_bucket).read(my_role)
```

```
import software.amazon.awscdk.services.s3.*;
import software.amazon.awscdk.services.iam.*;

// myRole is an IAM role defined elsewhere in your app

// Using grants on an L2 construct (via the grants property)
Bucket l2Bucket = new Bucket(this, "L2Bucket");
l2Bucket.getGrants().read(myRole);

// Using grants on an L1 construct (via the factory method)
CfnBucket l1Bucket = new CfnBucket(this, "L1Bucket");
BucketGrants.fromBucket(l1Bucket).read(myRole);
```

```
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.IAM;

// myRole is an IAM role defined elsewhere in your app

// Using grants on an L2 construct (via the grants property)
var l2Bucket = new Bucket(this, "L2Bucket");
l2Bucket.Grants.Read(myRole);

// Using grants on an L1 construct (via the factory method)
var l1Bucket = new CfnBucket(this, "L1Bucket");
BucketGrants.FromBucket(l1Bucket).Read(myRole);
```

```
import (
	"github.com/aws/jsii-runtime-go"
	awss3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3"
)

// myRole is an IAM role defined elsewhere in your app

l2Bucket := awss3.NewBucket(stack, jsii.String("L2Bucket"), nil)
l2Bucket.Grants().Read(myRole, nil)

l1Bucket := awss3.NewCfnBucket(stack, jsii.String("L1Bucket"), nil)
awss3.BucketGrants_FromBucket(l1Bucket).Read(myRole, nil)
```

権限とアクセス許可の詳細については、[「 権限](permissions.md#permissions-grants)」を参照してください。

## ミックスでファサードを使用する
<a name="facades-mixins-together"></a>

Facades を [Mixins](mixins.md) と組み合わせることで、L2-like完全なエクスペリエンスを得ることができます。 L1 Mixins を使用してリソースを設定し、Facades を使用してアクセスを許可します。

**Example**  

```
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';

// Configure the resource with Mixins
const bucket = new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());

// Grant permissions using a Facade
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
s3.BucketGrants.fromBucket(bucket).read(role);
```

```
const s3 = require('aws-cdk-lib/aws-s3');
const iam = require('aws-cdk-lib/aws-iam');

// Configure the resource with Mixins
const bucket = new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());

// Grant permissions using a Facade
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
s3.BucketGrants.fromBucket(bucket).read(role);
```

```
import aws_cdk.aws_s3 as s3
import aws_cdk.aws_iam as iam

# Configure the resource with Mixins
bucket = s3.CfnBucket(self, "MyBucket") \
    .with_(s3.mixins.BucketVersioning()) \
    .with_(s3.mixins.BucketBlockPublicAccess())

# Grant permissions using a Facade
role = iam.Role(self, "MyRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
)
s3.BucketGrants.from_bucket(bucket).read(role)
```

```
import software.amazon.awscdk.services.s3.*;
import software.amazon.awscdk.services.iam.*;

// Configure the resource with Mixins
CfnBucket bucket = new CfnBucket(this, "MyBucket");
bucket.with(new BucketVersioning());
bucket.with(new BucketBlockPublicAccess());

// Grant permissions using a Facade
Role role = Role.Builder.create(this, "MyRole")
        .assumedBy(new ServicePrincipal("lambda.amazonaws.com"))
        .build();
BucketGrants.fromBucket(bucket).read(role);
```

```
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.IAM;

// Configure the resource with Mixins
var bucket = new CfnBucket(this, "MyBucket");
bucket.With(new BucketVersioning());
bucket.With(new BucketBlockPublicAccess());

// Grant permissions using a Facade
var role = new Role(this, "MyRole", new RoleProps
{
    AssumedBy = new ServicePrincipal("lambda.amazonaws.com")
});
BucketGrants.FromBucket(bucket).Read(role);
```

```
bucket := awss3.NewCfnBucket(stack, jsii.String("MyBucket"), nil)
bucket.With(awss3.NewBucketVersioning())
bucket.With(awss3.NewBucketBlockPublicAccess())

role := awsiam.NewRole(stack, jsii.String("MyRole"), &awsiam.RoleProps{
    AssumedBy: awsiam.NewServicePrincipal(jsii.String("lambda.amazonaws.com"), nil),
})
awss3.BucketGrants_FromBucket(bucket).Read(role, nil)
```

## 関連リソース
<a name="facades-related"></a>
+  [Mixins](mixins.md) – L1 および L2 コンストラクトに再利用可能な機能を追加します。
+  [Grants](permissions.md#permissions-grants) – リソース間のアクセス許可を付与します。
+  [コンストラクト](constructs.md) – L1, L2、L3 コンストラクトについて説明します。

# AWS CDK の環境
<a name="environments"></a>

環境は、AWS Cloud Development Kit (AWS CDK) スタックをデプロイする AWS アカウントと AWS リージョンで構成されます。

 **AWS アカウント**   
AWS アカウントを作成するとアカウント ID が与えられます。この ID は、**012345678901** のような、ユーザーのアカウントを一意に識別する 12 桁の数字です。詳細については、「*AWS アカウント管理リファレンスガイド*」の「[AWS アカウント識別子の表示](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-identifiers.html)」を参照してください。

 **AWS リージョン**   
 AWS リージョンは、地理的位置とリージョンのアベイラビリティーゾーンを表す数値の組み合わせを使用して命名されます。例えば、**us-east-1** は米国東部 (バージニア北部) リージョンのアベイラビリティーゾーンを表します。AWS リージョンの詳細については、「[リージョンとアベイラビリティーゾーン](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/)」を参照してください。リージョンコードのリストについては、「*AWS 全般のリファレンス*」リファレンスガイドの「[リージョンエンドポイント](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints)」を参照してください。

AWS CDK は、認証情報と設定ファイルから環境を特定できます。これらのファイルは、AWS コマンドラインインターフェイス (AWS CLI) を使用して作成および管理できます。これらのファイルの基本的な例を以下に示します。

 **認証情報ファイル**:   

```
[default]
aws_access_key_id=ASIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
aws_session_token = IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZVERYLONGSTRINGEXAMPLE

[user1]
aws_access_key_id=ASIAI44QH8DHBEXAMPLE
aws_secret_access_key=je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY
aws_session_token = fcZib3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZVERYLONGSTRINGEXAMPLE
```

 **[Configuration file] (設定ファイル**) –   

```
[default]
region=us-west-2
output=json

[profile user1]
region=us-east-1
output=text
```

これらのファイルからの環境情報は、CDK が提供する環境変数を介して、CDK コード内に渡されます。`cdk deploy` などの CDK CLI コマンドを実行する際は、環境情報を収集するために、認証情報と設定ファイルからプロファイルを提供します。

CDK コードでこれらの環境変数を指定する場合の例を以下に示します。

```
new MyDevStack(app, 'dev', {
  env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: process.env.CDK_DEFAULT_REGION
}});
```

以下は、`--profile` オプションを使用して、`user1` プロファイルに関連付けられた値を、認証情報と設定ファイルから CDK CLI に渡す場合の例です。これらのファイルからの値は、環境変数に渡されます。

```
$ cdk deploy <myStack> --profile <user1>
```

認証情報と設定ファイルの値を使用する代わりに、CDK コード内で環境値をハードコーディングすることもできます。以下に例を示します。

```
const envEU = { account: '238383838383', region: 'eu-west-1' };
const envUSA = { account: '837873873873', region: 'us-west-2' };

new MyFirstStack(app, 'first-stack-us', { env: envUSA });
new MyFirstStack(app, 'first-stack-eu', { env: envEU });
```

## 詳細
<a name="environments-learn"></a>

AWS CDK で環境の使用を開始するには、「[AWS CDK で使用する環境を設定する](configure-env.md)」を参照してください。

# AWS CDK ブートストラップ
<a name="bootstrapping"></a>

 *ブートストラップ*は、AWS Cloud Development Kit (AWS CDK) で使用するために AWS 環境を準備するプロセスです。CDK スタックを AWS 環境にデプロイする前に、まず環境をブートストラップする必要があります。

## ブートストラップとは
<a name="bootstrapping-what"></a>

ブートストラップは、AWS CDK が使用する AWS 環境内の特定の AWS リソースをプロビジョニングすることで、この環境を準備します。これらのリソースは、一般に*ブートストラップリソース*と呼ばれます。これには以下のものが含まれます。
+  **Amazon Simple Storage Service (Amazon S3) バケット** – AWS Lambda 関数コードやアセットなどの CDK プロジェクトファイルを保存するために使用します。
+  **Amazon Elastic Container Registry (Amazon ECR) リポジトリ** – 主に Docker イメージの保存に使用されます。
+  **AWS Identity and Access Management (IAM) ロール** – デプロイを実行するために必要なアクセス許可を AWS CDK に付与するように設定されています。ブートストラップ中に作成された IAM ロールの詳細については、「[ブートストラップ中に作成された IAM ロール](bootstrapping-env.md#bootstrapping-env-roles)」を参照してください。

## ブートストラップの仕組み
<a name="bootstrapping-how"></a>

CDK で使用されるリソースとその設定は、AWS CloudFormation テンプレートで定義されます。このテンプレートは CDK チームによって作成および管理されます。このテンプレートの最新バージョンについては、「*aws-cdk-cli GitHub リポジトリ*」の「[https://github.com/aws/aws-cdk-cli/blob/main/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml](https://github.com/aws/aws-cdk-cli/blob/main/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml)」を参照してください。

環境をブートストラップするには、AWS コマンドラインインターフェイス (AWS CDK CLI) の `cdk bootstrap` CDK コマンドを使用します。CDK CLI はテンプレートを取得し、*ブートストラップスタック*と呼ばれるスタックとして AWS CloudFormation にデプロイします。デフォルトでは、スタック名は `CDKToolkit` です。このテンプレートをデプロイすることで、CloudFormation は環境内のリソースをプロビジョニングします。デプロイ後、ブートストラップスタックが環境の AWS CloudFormation コンソールに表示されます。

テンプレートを変更するか、`cdk bootstrap` コマンドで CDK CLI オプションを使用することで、ブートストラップをカスタマイズすることもできます。

 AWS 環境は独立しています。AWS CDK で使用する各環境は、まずブートストラップする必要があります。

## 詳細
<a name="bootstrapping-learn"></a>

環境をブートストラップする手順については、「[AWS CDK で使用する環境のブートストラップ](bootstrapping-env.md)」を参照してください。

# リソースと AWS CDK
<a name="resources"></a>

 *リソース*は、アプリケーションで AWS サービスを使用するように設定したものです。リソースは AWS CloudFormation の機能です。 AWS CloudFormation テンプレートでリソースとそのプロパティを設定することで、 AWS CloudFormation にデプロイしてリソースをプロビジョニングできます。 AWS Cloud Development Kit (AWS CDK) を使用すると、 コンストラクトを使用してリソースを設定できます。次に、CDK アプリケーションをデプロイします。これには、 AWS CloudFormation テンプレートを合成し、 AWS CloudFormation にデプロイしてリソースをプロビジョニングします。

## コンストラクトを使用したリソースの設定
<a name="resources-configure"></a>

[AWS CDK コンストラクト](constructs.md)で説明されているように、 AWS CDK は、すべての AWS リソースを表す*コンストラクト*と呼ばれるコンストラクトの豊富なクラスライブラリを提供します。

対応するコンストラクトを使用してリソースのインスタンスを作成するには、最初の引数、コンストラクトの論理 ID、一連の設定プロパティ (props) としてスコープを渡します。たとえば、 コンストラクトライブラリの [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_sqs.Queue.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_sqs.Queue.html)コンストラクトを使用して KMS AWS 暗号化で Amazon SQS AWS キューを作成する方法を説明します。

**Example**  

```
import * as sqs from '@aws-cdk/aws-sqs';

new sqs.Queue(this, 'MyQueue', {
    encryption: sqs.QueueEncryption.KMS_MANAGED
});
```

```
const sqs = require('@aws-cdk/aws-sqs');

new sqs.Queue(this, 'MyQueue', {
    encryption: sqs.QueueEncryption.KMS_MANAGED
});
```

```
import aws_cdk.aws_sqs as sqs

sqs.Queue(self, "MyQueue", encryption=sqs.QueueEncryption.KMS_MANAGED)
```

```
import software.amazon.awscdk.services.sqs.*;

Queue.Builder.create(this, "MyQueue").encryption(
        QueueEncryption.KMS_MANAGED).build();
```

```
using Amazon.CDK.AWS.SQS;

new Queue(this, "MyQueue", new QueueProps
{
    Encryption = QueueEncryption.KMS_MANAGED
});
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs"
)

sqs.NewQueue(stack, jsii.String("MyQueue"), &sqs.QueueProps{
  Encryption: sqs.QueueEncryption_KMS_MANAGED,
})
```

一部の設定 props はオプションであり、多くの場合デフォルト値があります。場合によってはすべての props がオプションであり、最後の引数は完全に省略できます。

### リソース属性
<a name="resources-attributes"></a>

 AWS コンストラクトライブラリのほとんどのリソースは、 AWS CloudFormation によってデプロイ時に解決される属性を公開します。タイプ名をプレフィックスとして持つリソースクラスのプロパティの形式で、属性は公開されます。次の例では、`queueUrl` (Python: `queue_url`) プロパティを使用し、Amazon SQS キューの URL を取得する方法を示しています。

**Example**  

```
import * as sqs from '@aws-cdk/aws-sqs';

const queue = new sqs.Queue(this, 'MyQueue');
const url = queue.queueUrl; // => A string representing a deploy-time value
```

```
const sqs = require('@aws-cdk/aws-sqs');

const queue = new sqs.Queue(this, 'MyQueue');
const url = queue.queueUrl; // => A string representing a deploy-time value
```

```
import aws_cdk.aws_sqs as sqs

queue = sqs.Queue(self, "MyQueue")
url = queue.queue_url # => A string representing a deploy-time value
```

```
Queue queue = new Queue(this, "MyQueue");
String url = queue.getQueueUrl();    // => A string representing a deploy-time value
```

```
var queue = new Queue(this, "MyQueue");
var url = queue.QueueUrl; // => A string representing a deploy-time value
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs"
)

queue := sqs.NewQueue(stack, jsii.String("MyQueue"), &sqs.QueueProps{})
url := queue.QueueUrl() // => A string representing a deploy-time value
```

[AWS CDK がデプロイ時間属性を文字列としてエンコードする方法の詳細については、「トークンと](tokens.md) AWS CDK」を参照してください。

## リソースの参照
<a name="resources-referencing"></a>

リソースを設定するとき、多くの場合は別のリソースのプロパティを参照する必要があります。次に例を示します。
+ Amazon Elastic Container Service (Amazon ECS) リソースは、実行するクラスターへのリファレンスが必要です。
+ Amazon CloudFront ディストリビューションは、ソースコードを含む Amazon Simple Storage Service (Amazon S3) バケットへのリファレンスが必要です。

次のいずれかの方法でリソースを参照できます。
+ CDK アプリの同じスタックまたは別のスタックのいずれかに対し、定義されたリソースを渡す
+  AWS アカウントで定義されたリソースを参照し、リソースの一意の識別子 (ARN など) から作成されたプロキシオブジェクトを渡す

コンストラクトのプロパティが別のリソースのコンストラクトを表す場合、タイプは コンストラクトのインターフェイスタイプのものです。例えば、Amazon ECS コンストラクトは `ecs.ICluster` タイプの `cluster` プロパティを取得します。もう 1 つの例は、`s3.IBucket` タイプの `sourceBucket` プロパティ (Python: `source_bucket`) を取得する CloudFront ディストリビューションコンストラクトです。

同じ AWS CDK アプリで定義されている適切なタイプのリソースオブジェクトを直接渡すことができます。次の例では、Amazon ECS クラスターを定義し、それを使用して Amazon ECS サービスを定義します。

**Example**  

```
const cluster = new ecs.Cluster(this, 'Cluster', { /*...*/ });

const service = new ecs.Ec2Service(this, 'Service', { cluster: cluster });
```

```
const cluster = new ecs.Cluster(this, 'Cluster', { /*...*/ });

const service = new ecs.Ec2Service(this, 'Service', { cluster: cluster });
```

```
cluster = ecs.Cluster(self, "Cluster")

service = ecs.Ec2Service(self, "Service", cluster=cluster)
```

```
Cluster cluster = new Cluster(this, "Cluster");
Ec2Service service = new Ec2Service(this, "Service",
        new Ec2ServiceProps.Builder().cluster(cluster).build());
```

```
var cluster = new Cluster(this, "Cluster");
var service = new Ec2Service(this, "Service", new Ec2ServiceProps { Cluster = cluster });
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  ecs "github.com/aws/aws-cdk-go/awscdk/v2/awsecs"
)

cluster := ecs.NewCluster(stack, jsii.String("MyCluster"), &ecs.ClusterProps{})
service := ecs.NewEc2Service(stack, jsii.String("MyService"), &ecs.Ec2ServiceProps{
  Cluster: cluster,
})
```

### 別のスタックでリソースの参照
<a name="resource-stack"></a>

同じアプリケーションで定義され、同じ AWS 環境にある限り、別のスタックのリソースを参照できます。一般的に、次のパターンが使用されます。
+ リソースを生成するスタックの属性として、コンストラクトへのリファレンスを保存します。(現在のコンストラクトのスタックへのリファレンスを取得するには、`Stack.of(this)` を使用します)
+ リソースをパラメータまたはプロパティとして消費するスタックのコンストラクターに対し、このリファレンスを渡します。次に、消費スタックは、それを必要とする任意のコンストラクトにプロパティとして渡します。

次の例では、スタック `stack1` を定義します。このスタックは Amazon S3 バケットを定義し、バケットコンストラクトへの参照をスタックの属性として保存します。次に、アプリケーションはインスタンス化時にバケット`stack2`を受け入れる 2 番目のスタック を定義します。 `stack2`は、たとえば、データストレージにバケットを使用する AWS Glue テーブルを定義します。

**Example**  

```
const prod = { account: '123456789012', region: 'us-east-1' };

const stack1 = new StackThatProvidesABucket(app, 'Stack1', { env: prod });

// stack2 will take a property { bucket: IBucket }
const stack2 = new StackThatExpectsABucket(app, 'Stack2', {
  bucket: stack1.bucket,
  env: prod
});
```

```
const prod = { account: '123456789012', region: 'us-east-1' };

const stack1 = new StackThatProvidesABucket(app, 'Stack1', { env: prod });

// stack2 will take a property { bucket: IBucket }
const stack2 = new StackThatExpectsABucket(app, 'Stack2', {
  bucket: stack1.bucket,
  env: prod
});
```

```
prod = core.Environment(account="123456789012", region="us-east-1")

stack1 = StackThatProvidesABucket(app, "Stack1", env=prod)

# stack2 will take a property "bucket"
stack2 = StackThatExpectsABucket(app, "Stack2", bucket=stack1.bucket, env=prod)
```

```
// Helper method to build an environment
static Environment makeEnv(String account, String region) {
    return Environment.builder().account(account).region(region)
            .build();
}

App app = new App();

Environment prod = makeEnv("123456789012", "us-east-1");

StackThatProvidesABucket stack1 = new StackThatProvidesABucket(app, "Stack1",
        StackProps.builder().env(prod).build());

// stack2 will take an argument "bucket"
StackThatExpectsABucket stack2 = new StackThatExpectsABucket(app, "Stack,",
        StackProps.builder().env(prod).build(), stack1.bucket);
```

```
Amazon.CDK.Environment makeEnv(string account, string region)
{
    return new Amazon.CDK.Environment { Account = account, Region = region };
}

var prod = makeEnv(account: "123456789012", region: "us-east-1");

var stack1 = new StackThatProvidesABucket(app, "Stack1", new StackProps { Env = prod });

// stack2 will take a property "bucket"
var stack2 = new StackThatExpectsABucket(app, "Stack2", new StackProps { Env = prod,
    bucket = stack1.Bucket});
```

 AWS CDK は、リソースが同じ環境にあり、別のスタックにあると判断した場合、生成スタックの AWS CloudFormation [エクスポート](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html)と消費スタック[https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html)の を自動的に合成して、その情報を 1 つのスタックから別のスタックに転送します。

#### 依存関係のデッドロックの解決
<a name="resources-deadlock"></a>

別のスタックで 1 つのスタックからリソースを参照すると、2 つのスタック間に依存関係が作成されます。これにより、確実に正しい順序でデプロイされます。スタックがデプロイされたら、この依存関係は明確になります。その後、共有リソースを消費スタックから削除すると、予期しないデプロイの失敗が発生する可能性があります。2 つのスタック間に同じ順序でデプロイを強制する別の依存関係がある場合、失敗が発生します。生成スタックを最初にデプロイするように CDK Toolkit が選択しただけでも、依存関係がなくても発生する可能性があります。 AWS CloudFormation エクスポートは、不要になったため生成スタックから削除されますが、更新がまだデプロイされていないため、エクスポートされたリソースは消費スタックでまだ使用されています。したがって、生成スタックのデプロイは失敗します。

このデッドロックを解除するには、共有リソースの使用を消費スタックから削除します。(生成スタックから自動エクスポートが削除されます) 次に、自動生成されたエクスポートとまったく同じ論理 ID を使用し、生成スタックに同じエクスポートを手動で追加します。消費スタックの共有リソースの使用を削除し、両方のスタックをデプロイします。次に、手動エクスポート (共有リソースが不要になった場合、それも削除します) を削除し、両方のスタックを再度デプロイします。スタックの [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#exportwbrvalueexportedvalue-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#exportwbrvalueexportedvalue-options) メソッドは、この目的のために手動エクスポートを作成する便利な方法です。(リンクされたメソッドリファレンスで例を参照してください)

### AWS アカウントのリソースの参照
<a name="resources-external"></a>

 AWS CDK アプリの AWS アカウントで既に利用可能なリソースを使用するとします。これは、コンソール、 AWS SDK、 AWS CloudFormation で直接、または別の AWS CDK アプリケーションで定義されたリソースである場合があります。リソースの ARN (または別の識別属性か属性のグループ) をプロキシオブジェクトに変換できます。プロキシオブジェクトはリソースのクラスで静的ファクトリメソッドを呼び出すことにより、リソースへの参照として機能します。

このようなプロキシを作成すると、外部リソース**は CDK アプリの一部**にはなりません。 AWS したがって、 AWS CDK アプリでプロキシに加えた変更は、デプロイされたリソースには影響しません。ただし、プロキシは、そのタイプのリソースを必要とする任意の AWS CDK メソッドに渡すことができます。

次の例では、ARN `arn:aws:s3:::amzn-s3-demo-bucket1` を持つ既存のバケット、ならびに特定の ID を持つ既存の VPC に基づく Amazon Virtual Private Cloud に基づいてバケットを参照する方法が示されています。

**Example**  

```
// Construct a proxy for a bucket by its name (must be same account)
s3.Bucket.fromBucketName(this, 'MyBucket', 'amzn-s3-demo-bucket1');

// Construct a proxy for a bucket by its full ARN (can be another account)
s3.Bucket.fromBucketArn(this, 'MyBucket', 'arn:aws:s3:::amzn-s3-demo-bucket1');

// Construct a proxy for an existing VPC from its attribute(s)
ec2.Vpc.fromVpcAttributes(this, 'MyVpc', {
  vpcId: 'vpc-1234567890abcde',
});
```

```
// Construct a proxy for a bucket by its name (must be same account)
s3.Bucket.fromBucketName(this, 'MyBucket', 'amzn-s3-demo-bucket1');

// Construct a proxy for a bucket by its full ARN (can be another account)
s3.Bucket.fromBucketArn(this, 'MyBucket', 'arn:aws:s3:::amzn-s3-demo-bucket1');

// Construct a proxy for an existing VPC from its attribute(s)
ec2.Vpc.fromVpcAttributes(this, 'MyVpc', {
  vpcId: 'vpc-1234567890abcde'
});
```

```
# Construct a proxy for a bucket by its name (must be same account)
s3.Bucket.from_bucket_name(self, "MyBucket", "amzn-s3-demo-bucket1")

# Construct a proxy for a bucket by its full ARN (can be another account)
s3.Bucket.from_bucket_arn(self, "MyBucket", "arn:aws:s3:::amzn-s3-demo-bucket1")

# Construct a proxy for an existing VPC from its attribute(s)
ec2.Vpc.from_vpc_attributes(self, "MyVpc", vpc_id="vpc-1234567890abcdef")
```

```
// Construct a proxy for a bucket by its name (must be same account)
Bucket.fromBucketName(this, "MyBucket", "amzn-s3-demo-bucket1");

// Construct a proxy for a bucket by its full ARN (can be another account)
Bucket.fromBucketArn(this, "MyBucket",
        "arn:aws:s3:::amzn-s3-demo-bucket1");

// Construct a proxy for an existing VPC from its attribute(s)
Vpc.fromVpcAttributes(this, "MyVpc", VpcAttributes.builder()
        .vpcId("vpc-1234567890abcdef").build());
```

```
// Construct a proxy for a bucket by its name (must be same account)
Bucket.FromBucketName(this, "MyBucket", "amzn-s3-demo-bucket1");

// Construct a proxy for a bucket by its full ARN (can be another account)
Bucket.FromBucketArn(this, "MyBucket", "arn:aws:s3:::amzn-s3-demo-bucket1");

// Construct a proxy for an existing VPC from its attribute(s)
Vpc.FromVpcAttributes(this, "MyVpc", new VpcAttributes
{
    VpcId = "vpc-1234567890abcdef"
});
```

```
// Define a proxy for a bucket by its name (must be same account)
s3.Bucket_FromBucketName(stack, jsii.String("MyBucket"), jsii.String("amzn-s3-demo-bucket1"))

// Define a proxy for a bucket by its full ARN (can be another account)
s3.Bucket_FromBucketArn(stack, jsii.String("MyBucket"), jsii.String("arn:aws:s3:::amzn-s3-demo-bucket1"))

// Define a proxy for an existing VPC from its attributes
ec2.Vpc_FromVpcAttributes(stack, jsii.String("MyVpc"), &ec2.VpcAttributes{
  VpcId: jsii.String("vpc-1234567890abcde"),
})
```

[https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ec2.Vpc.html#static-fromwbrlookupscope-id-options](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ec2.Vpc.html#static-fromwbrlookupscope-id-options) メソッドを詳しく見てみましょう。`ec2.Vpc` コンストラクトが複雑なため、CDK アプリで使用する VPC を選択する方法は多数あります。これに対処するために、VPC `fromLookup` コンストラクトには静的メソッド (Python: `from_lookup`) があり、合成時に AWS アカウントをクエリして目的の Amazon VPC を検索できます。

`Vpc.fromLookup()` を使用するには、スタックを合成するシステムが Amazon VPC を所有するアカウントにアクセスする必要があります。CDK Toolkit がアカウントをクエリし、合成時に適切な Amazon VPC を探すためです。

さらに、 は明示的な**アカウント**と**リージョン**で定義されたスタックでのみ`Vpc.fromLookup()`機能します ([AWS 「CDK の環境](environments.md)」を参照）。 AWS CDK が[環境に依存しないスタック](stacks.md#stack-api)から Amazon VPC を検索しようとすると、CDK Toolkit は VPC を見つけるためにクエリする環境を認識しません。

 AWS アカウント内の VPC を一意に識別するのに十分な`Vpc.fromLookup()`属性を指定する必要があります。例えば、デフォルトの VPC は 1 つしか存在できないため、VPC をデフォルトとして指定すれば十分です。

**Example**  

```
ec2.Vpc.fromLookup(this, 'DefaultVpc', {
  isDefault: true
});
```

```
ec2.Vpc.fromLookup(this, 'DefaultVpc', {
  isDefault: true
});
```

```
ec2.Vpc.from_lookup(self, "DefaultVpc", is_default=True)
```

```
Vpc.fromLookup(this, "DefaultVpc", VpcLookupOptions.builder()
        .isDefault(true).build());
```

```
Vpc.FromLookup(this, id = "DefaultVpc", new VpcLookupOptions { IsDefault = true });
```

```
ec2.Vpc_FromLookup(this, jsii.String("DefaultVpc"), &ec2.VpcLookupOptions{
  IsDefault: jsii.Bool(true),
})
```

`tags` プロパティを使用し、タグで VPC をクエリすることもできます。 AWS CloudFormation または AWS CDK を使用して、作成時に Amazon VPC にタグを追加できます。タグは、 AWS マネジメントコンソール、 CLI、または AWS SDK AWS を使用して、作成後にいつでも編集できます。自分で追加したタグに加えて、 AWS CDK は作成するすべての VPCsします。
+  **名前** – VPC の名前。
+  **aws-cdk:subnet-name** – サブネットの名前。
+  **aws-cdk:subnet-type** – サブネットのタイプ: パブリック、プライベート、隔離。

**Example**  

```
ec2.Vpc.fromLookup(this, 'PublicVpc',
    {tags: {'aws-cdk:subnet-type': "Public"}});
```

```
ec2.Vpc.fromLookup(this, 'PublicVpc',
    {tags: {'aws-cdk:subnet-type': "Public"}});
```

```
ec2.Vpc.from_lookup(self, "PublicVpc",
    tags={"aws-cdk:subnet-type": "Public"})
```

```
Vpc.fromLookup(this, "PublicVpc", VpcLookupOptions.builder()
        .tags(java.util.Map.of("aws-cdk:subnet-type", "Public"))  // Java 9 or later
        .build());
```

```
Vpc.FromLookup(this, id: "PublicVpc", new VpcLookupOptions
{
    Tags = new Dictionary<string, string> { ["aws-cdk:subnet-type"] = "Public" }
});
```

```
ec2.Vpc_FromLookup(this, jsii.String("DefaultVpc"), &ec2.VpcLookupOptions{
  Tags: &map[string]*string{"aws-cdk:subnet-type": jsii.String("Public")},
})
```

`Vpc.fromLookup()` の結果は、プロジェクトの `cdk.context.json` ファイルにキャッシュされます。([コンテキスト値と AWS CDK ](context.md)を参照してください）。アプリが同じ Amazon VPC を参照し続けるように、このファイルをバージョン管理にコミットします。別の VPC が選択されるように、後で VPCsの属性を変更しても機能します。これは、[CDK Pipelines](cdk-pipeline.md) などの VPC を定義する AWS アカウントにアクセスできない環境にスタックをデプロイする場合に特に重要です。

 AWS CDK アプリで定義された同様のリソースを使用する任意の場所で外部リソースを使用できますが、変更することはできません。例えば、外部 `s3.Bucket` で `addToResourcePolicy` (Python: `add_to_resource_policy`) を呼び出しても何も行われません。

## リソースの物理名
<a name="resources-physical-names"></a>

 AWS CloudFormation のリソースの論理名は、CloudFormation によってデプロイされた後に AWS マネジメントコンソールに表示されるリソースの名前とは異なります。 AWS CloudFormation AWS CDK は、これらの最終名の*物理名*を呼び出します。

例えば、 AWS CloudFormation は論理 ID `Stack2MyBucket4DD88B4F`と物理名 を使用して Amazon S3 バケットを作成する場合があります`stack2MyBucket4dd88b4f-iuv1rbv9z3to`。

プロパティ `<resourceType>Name` を使用し、リソースを表すコンストラクトを作成するときに物理名を指定できます。次の例では、物理名の `amzn-s3-demo-bucket` を持つ Amazon S3 バケットを作成します。

**Example**  

```
const bucket = new s3.Bucket(this, 'MyBucket', {
  bucketName: 'amzn-s3-demo-bucket',
});
```

```
const bucket = new s3.Bucket(this, 'MyBucket', {
  bucketName: 'amzn-s3-demo-bucket'
});
```

```
bucket = s3.Bucket(self, "MyBucket", bucket_name="amzn-s3-demo-bucket")
```

```
Bucket bucket = Bucket.Builder.create(this, "MyBucket")
        .bucketName("amzn-s3-demo-bucket").build();
```

```
var bucket = new Bucket(this, "MyBucket", new BucketProps { BucketName = "amzn-s3-demo-bucket" });
```

```
bucket := s3.NewBucket(this, jsii.String("MyBucket"), &s3.BucketProps{
  BucketName: jsii.String("amzn-s3-demo-bucket"),
})
```

リソースに物理名を割り当てると、 AWS CloudFormation にいくつかの欠点があります。最も重要なのは、リソースの作成後に変更できないリソースのプロパティの変更など、リソースの置き換えを必要とするデプロイされたリソースへの変更は、リソースに物理名が割り当てられている場合は失敗することです。その状態になった場合の唯一の解決策は、 AWS CloudFormation スタックを削除し、 AWS CDK アプリを再度デプロイすることです。詳細については、「[AWS CloudFormation ドキュメント](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-name.html)」を参照してください。

環境間の参照を使用して AWS CDK アプリを作成する場合など、 AWS CDK が正しく機能するには物理名が必要です。このような場合、自分で物理名を入力したくない場合は、 AWS CDK に名前を付けることができます。これを行うには、次のように特別な値の `PhysicalName.GENERATE_IF_NEEDED` を使用します。

**Example**  

```
const bucket = new s3.Bucket(this, 'MyBucket', {
  bucketName: core.PhysicalName.GENERATE_IF_NEEDED,
});
```

```
const bucket = new s3.Bucket(this, 'MyBucket', {
  bucketName: core.PhysicalName.GENERATE_IF_NEEDED
});
```

```
bucket = s3.Bucket(self, "MyBucket",
                         bucket_name=core.PhysicalName.GENERATE_IF_NEEDED)
```

```
Bucket bucket = Bucket.Builder.create(this, "MyBucket")
        .bucketName(PhysicalName.GENERATE_IF_NEEDED).build();
```

```
var bucket = new Bucket(this, "MyBucket", new BucketProps
    { BucketName = PhysicalName.GENERATE_IF_NEEDED });
```

```
bucket := s3.NewBucket(this, jsii.String("MyBucket"), &s3.BucketProps{
  BucketName: awscdk.PhysicalName_GENERATE_IF_NEEDED(),
})
```

## 一意のリソース識別子を渡す
<a name="resources-identifiers"></a>

前のセクションで説明したように、可能な限り、リソースをリファレンスで渡す必要があります。ただし、属性の 1 つでリソースを参照する以外に選択肢がない場合があります。ユースケースの例には次の内容が含まれます。
+ 低レベルの AWS CloudFormation リソースを使用している場合。
+ 環境変数を介して Lambda 関数を参照する場合など、 AWS CDK アプリケーションのランタイムコンポーネントにリソースを公開する必要がある場合。

これらの識別子は、次のようなリソースの属性として利用できます。

**Example**  

```
bucket.bucketName
lambdaFunc.functionArn
securityGroup.groupArn
```

```
bucket.bucketName
lambdaFunc.functionArn
securityGroup.groupArn
```

```
bucket.bucket_name
lambda_func.function_arn
security_group_arn
```
Java AWS CDK バインディングは、属性に getter メソッドを使用します。  

```
bucket.getBucketName()
lambdaFunc.getFunctionArn()
securityGroup.getGroupArn()
```

```
bucket.BucketName
lambdaFunc.FunctionArn
securityGroup.GroupArn
```

```
bucket.BucketName()
fn.FunctionArn()
```

次の例は、生成されたバケット名を AWS Lambda 関数に渡す方法を示しています。

**Example**  

```
const bucket = new s3.Bucket(this, 'Bucket');

new lambda.Function(this, 'MyLambda', {
  // ...
  environment: {
    BUCKET_NAME: bucket.bucketName,
  },
});
```

```
const bucket = new s3.Bucket(this, 'Bucket');

new lambda.Function(this, 'MyLambda', {
  // ...
  environment: {
    BUCKET_NAME: bucket.bucketName
  }
});
```

```
bucket = s3.Bucket(self, "Bucket")

lambda.Function(self, "MyLambda", environment=dict(BUCKET_NAME=bucket.bucket_name))
```

```
final Bucket bucket = new Bucket(this, "Bucket");

Function.Builder.create(this, "MyLambda")
        .environment(java.util.Map.of(    // Java 9 or later
                "BUCKET_NAME", bucket.getBucketName()))
        .build();
```

```
var bucket = new Bucket(this, "Bucket");

new Function(this, "MyLambda", new FunctionProps
{
    Environment = new Dictionary<string, string>
    {
        ["BUCKET_NAME"] = bucket.BucketName
    }
});
```

```
bucket := s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{})
lambda.NewFunction(this, jsii.String("MyLambda"), &lambda.FunctionProps{
  Environment: &map[string]*string{"BUCKET_NAME": bucket.BucketName()},
})
```

## リソース間にアクセス許可の付与
<a name="resources-grants"></a>

上位レベルのコンストラクトは、アクセス許可要件を表現するために単純でインテントベースの API を提供することにより、最小特権のアクセス許可を実現できるようにします。例えば、多くのコンストラクトは、IAM アクセス許可ステートメントを手動で作成することなく、リソースを操作するアクセス許可をエンティティ (IAM ロールやユーザーなど) に付与するために使用できる付与メソッドを提供します。

グラントメソッドは、グラントクラス (`BucketGrants`Amazon S3 バケットの場合など) を通じて使用できます。これらのクラスは、L1 コンストラクトと L2 コンストラクトの両方で機能します。L2 コンストラクトは便宜上`grants`プロパティを公開しますが、L1 コンストラクトから直接 Grants クラスを作成することもできます。Grants クラスを [Mixins](mixins.md) と組み合わせて、L2-like利便性を得ることができます。 L1 

次の例では、Lambda 関数の実行ロールが特定の Amazon S3 バケットにオブジェクトに読み取りや書き込みをできるようにするアクセス許可を作成します。Amazon S3 バケットが KMS AWS キーで暗号化されている場合、このメソッドは Lambda 関数の実行ロールにキーで復号するためのアクセス許可も付与します。

**Example**  

```
if (bucket.grants.readWrite(func).success) {
  // ...
}
```

```
if ( bucket.grants.readWrite(func).success) {
  // ...
}
```

```
if bucket.grants.read_write(func).success:
    # ...
```

```
if (bucket.getGrants().readWrite(func).getSuccess()) {
    // ...
}
```

```
if (bucket.Grants.ReadWrite(func).Success)
{
    // ...
}
```

```
if *bucket.Grants().ReadWrite(function, nil).Success() {
  // ...
}
```

付与メソッドは `iam.Grant` オブジェクトを返します。`Grant` オブジェクトの `success` 属性を使用し、付与が効果的に適用された (例えば、[外部リソース](#resources-referencing)に適用されていない場合がある) かどうかを判定します。`Grant` オブジェクトの `assertSuccess` (Python: `assert_success`) メソッドを使用し、付与が正常に適用されるように強制することもできます。

特定の付与メソッドが特定のユースケースで利用できない場合、汎用の付与メソッドを使用して指定されたアクションのリストで新しいグラントを定義できます。

次の例では、Lambda 関数に Amazon DynamoDB `CreateBackup` アクションへのアクセスを許可する方法を示しています。

**Example**  

```
table.grants.actions(func, 'dynamodb:CreateBackup');
```

```
table.grants.actions(func, 'dynamodb:CreateBackup');
```

```
table.grants.actions(func, "dynamodb:CreateBackup")
```

```
table.getGrants().actions(func, "dynamodb:CreateBackup");
```

```
table.Grants.Actions(func, "dynamodb:CreateBackup");
```

```
table := dynamodb.NewTable(this, jsii.String("MyTable"), &dynamodb.TableProps{})
table.Grants().Actions(function, jsii.String("dynamodb:CreateBackup"))
```

Lambda 関数などの多くのリソースは、コードの実行時にロールを引き受ける必要があります。設定プロパティを使用すると、`iam.IRole` を指定できます。ロールが指定されていない場合、関数はこの用途に特化したロールを自動的に作成します。その後、リソースに付与メソッドを使用し、ロールにステートメントを追加できます。

付与メソッドは、IAM ポリシーで処理するための下位レベルの APIs を使用して構築されます。ポリシーは [PolicyDocument](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyDocument.html) オブジェクトとしてモデル化されます。`addToRolePolicy` メソッド (Python: `add_to_role_policy`) を使用して ロール (またはコンストラクトのアタッチされたロール)、あるいは `addToResourcePolicy` (Python: `add_to_resource_policy`) メソッドを使用してリソースのポリシー (`Bucket` ポリシーなど) にステートメントを直接追加するか。

## リソースメトリクスとアラーム
<a name="resources-metrics"></a>

多くのリソースは CloudWatch メトリクスを出力し、モニタリングダッシュボードおよびアラームの設定に使用できます。上位レベルのコンストラクトには、使用する正しい名前を検索せずにメトリクスにアクセスできるメトリクスメソッドがあります。

次の例では、Amazon SQS キューの `ApproximateNumberOfMessagesNotVisible` が 100 を超えたときのアラームを定義する方法を示しています。

**Example**  

```
import * as cw from '@aws-cdk/aws-cloudwatch';
import * as sqs from '@aws-cdk/aws-sqs';
import { Duration } from '@aws-cdk/core';

const queue = new sqs.Queue(this, 'MyQueue');

const metric = queue.metricApproximateNumberOfMessagesNotVisible({
  label: 'Messages Visible (Approx)',
  period: Duration.minutes(5),
  // ...
});
metric.createAlarm(this, 'TooManyMessagesAlarm', {
  comparisonOperator: cw.ComparisonOperator.GREATER_THAN_THRESHOLD,
  threshold: 100,
  // ...
});
```

```
const cw = require('@aws-cdk/aws-cloudwatch');
const sqs = require('@aws-cdk/aws-sqs');
const { Duration } = require('@aws-cdk/core');

const queue = new sqs.Queue(this, 'MyQueue');

const metric = queue.metricApproximateNumberOfMessagesNotVisible({
  label: 'Messages Visible (Approx)',
  period: Duration.minutes(5)
  // ...
});
metric.createAlarm(this, 'TooManyMessagesAlarm', {
  comparisonOperator: cw.ComparisonOperator.GREATER_THAN_THRESHOLD,
  threshold: 100
  // ...
});
```

```
import aws_cdk.aws_cloudwatch as cw
import aws_cdk.aws_sqs as sqs
from aws_cdk.core import Duration

queue = sqs.Queue(self, "MyQueue")
metric = queue.metric_approximate_number_of_messages_not_visible(
    label="Messages Visible (Approx)",
    period=Duration.minutes(5),
    # ...
)
metric.create_alarm(self, "TooManyMessagesAlarm",
    comparison_operator=cw.ComparisonOperator.GREATER_THAN_THRESHOLD,
    threshold=100,
    # ...
)
```

```
import software.amazon.awscdk.core.Duration;
import software.amazon.awscdk.services.sqs.Queue;
import software.amazon.awscdk.services.cloudwatch.Metric;
import software.amazon.awscdk.services.cloudwatch.MetricOptions;
import software.amazon.awscdk.services.cloudwatch.CreateAlarmOptions;
import software.amazon.awscdk.services.cloudwatch.ComparisonOperator;

Queue queue = new Queue(this, "MyQueue");

Metric metric = queue
        .metricApproximateNumberOfMessagesNotVisible(MetricOptions.builder()
                .label("Messages Visible (Approx)")
                .period(Duration.minutes(5)).build());

metric.createAlarm(this, "TooManyMessagesAlarm", CreateAlarmOptions.builder()
                .comparisonOperator(ComparisonOperator.GREATER_THAN_THRESHOLD)
                .threshold(100)
                // ...
                .build());
```

```
using cdk = Amazon.CDK;
using cw = Amazon.CDK.AWS.CloudWatch;
using sqs = Amazon.CDK.AWS.SQS;

var queue = new sqs.Queue(this, "MyQueue");
var metric = queue.MetricApproximateNumberOfMessagesNotVisible(new cw.MetricOptions
{
    Label = "Messages Visible (Approx)",
    Period = cdk.Duration.Minutes(5),
    // ...
});
metric.CreateAlarm(this, "TooManyMessagesAlarm", new cw.CreateAlarmOptions
{
    ComparisonOperator = cw.ComparisonOperator.GREATER_THAN_THRESHOLD,
    Threshold = 100,
    // ..
});
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  cw "github.com/aws/aws-cdk-go/awscdk/v2/awscloudwatch"
  sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs"
)

queue := sqs.NewQueue(this, jsii.String("MyQueue"), &sqs.QueueProps{})
metric := queue.MetricApproximateNumberOfMessagesNotVisible(&cw.MetricOptions{
  Label: jsii.String("Messages Visible (Approx)"),
  Period: awscdk.Duration_Minutes(jsii.Number(5)),
})

metric.CreateAlarm(this, jsii.String("TooManyMessagesAlarm"), &cw.CreateAlarmOptions{
  ComparisonOperator: cw.ComparisonOperator_GREATER_THAN_THRESHOLD,
  Threshold: jsii.Number(100),
})
```

特定のメトリクスにメソッドがない場合、一般的なメトリクスメソッドを使用してメトリクス名を手動で指定できます。

メトリクスは CloudWatch ダッシュボードにも追加できます。「[CloudWatch](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudwatch-readme.html)」を参照してください。

## ネットワークトラフィック
<a name="resources-traffic"></a>

多くの場合、コンピューティングインフラストラクチャが永続化レイヤーにアクセスする必要があるときなど、アプリケーションが機能するためにネットワークにアクセス許可を有効にする必要があります。接続を確立または聞くリソースは、セキュリティグループルールやネットワーク ACL などのトラフィックフローを有効にするメソッドを公開します。

 [IConnectable](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.IConnectable.html) リソースには、ネットワークトラフィックのルール設定のゲートウェイである `connections` プロパティがあります。

`allow` メソッドを使用し、特定のネットワークパスでデータが流れるようにします。次の例では、ウェブへの HTTPS 接続および Amazon EC2 Auto Scaling の `fleet2` グループからの受信接続を有効にします。

**Example**  

```
import * as asg from '@aws-cdk/aws-autoscaling';
import * as ec2 from '@aws-cdk/aws-ec2';

const fleet1: asg.AutoScalingGroup = asg.AutoScalingGroup(/*...*/);

// Allow surfing the (secure) web
fleet1.connections.allowTo(new ec2.Peer.anyIpv4(), new ec2.Port({ fromPort: 443, toPort: 443 }));

const fleet2: asg.AutoScalingGroup = asg.AutoScalingGroup(/*...*/);
fleet1.connections.allowFrom(fleet2, ec2.Port.AllTraffic());
```

```
const asg = require('@aws-cdk/aws-autoscaling');
const ec2 = require('@aws-cdk/aws-ec2');

const fleet1 = asg.AutoScalingGroup();

// Allow surfing the (secure) web
fleet1.connections.allowTo(new ec2.Peer.anyIpv4(), new ec2.Port({ fromPort: 443, toPort: 443 }));

const fleet2 = asg.AutoScalingGroup();
fleet1.connections.allowFrom(fleet2, ec2.Port.AllTraffic());
```

```
import aws_cdk.aws_autoscaling as asg
import aws_cdk.aws_ec2 as ec2

fleet1 = asg.AutoScalingGroup( ... )

# Allow surfing the (secure) web
fleet1.connections.allow_to(ec2.Peer.any_ipv4(),
  ec2.Port(PortProps(from_port=443, to_port=443)))

fleet2 = asg.AutoScalingGroup( ... )
fleet1.connections.allow_from(fleet2, ec2.Port.all_traffic())
```

```
import software.amazon.awscdk.services.autoscaling.AutoScalingGroup;
import software.amazon.awscdk.services.ec2.Peer;
import software.amazon.awscdk.services.ec2.Port;

AutoScalingGroup fleet1 = AutoScalingGroup.Builder.create(this, "MyFleet")
        /* ... */.build();

// Allow surfing the (secure) Web
fleet1.getConnections().allowTo(Peer.anyIpv4(),
        Port.Builder.create().fromPort(443).toPort(443).build());

AutoScalingGroup fleet2 = AutoScalingGroup.Builder.create(this, "MyFleet2")
        /* ... */.build();
fleet1.getConnections().allowFrom(fleet2, Port.allTraffic());
```

```
using cdk = Amazon.CDK;
using asg = Amazon.CDK.AWS.AutoScaling;
using ec2 = Amazon.CDK.AWS.EC2;

// Allow surfing the (secure) Web
var fleet1 = new asg.AutoScalingGroup(this, "MyFleet", new asg.AutoScalingGroupProps { /* ... */ });
fleet1.Connections.AllowTo(ec2.Peer.AnyIpv4(), new ec2.Port(new ec2.PortProps
  { FromPort = 443, ToPort = 443 }));

var fleet2 = new asg.AutoScalingGroup(this, "MyFleet2", new asg.AutoScalingGroupProps { /* ... */ });
fleet1.Connections.AllowFrom(fleet2, ec2.Port.AllTraffic());
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  autoscaling "github.com/aws/aws-cdk-go/awscdk/v2/awsautoscaling"
  ec2 "github.com/aws/aws-cdk-go/awscdk/v2/awsec2"
)

fleet1 := autoscaling.NewAutoScalingGroup(this, jsii.String("MyFleet1"), &autoscaling.AutoScalingGroupProps{})
fleet1.Connections().AllowTo(ec2.Peer_AnyIpv4(),ec2.NewPort(&ec2.PortProps{ FromPort: jsii.Number(443), ToPort: jsii.Number(443) }),jsii.String("secure web"))

fleet2 := autoscaling.NewAutoScalingGroup(this, jsii.String("MyFleet2"), &autoscaling.AutoScalingGroupProps{})
fleet1.Connections().AllowFrom(fleet2, ec2.Port_AllTraffic(),jsii.String("all traffic"))
```

特定のリソースには、デフォルトのポートが関連付けられています。例としては、パブリックポートのロードバランサーのリスナー、ならびにデータベースエンジンが Amazon RDS データベースのインスタンスの接続を受け入れるポートなどがあります。このような場合、ポートを手動で指定しなくても、厳密なネットワーク制御を強制できます。これを行うには、`allowDefaultPortFrom` および `allowToDefaultPort` メソッド (Python: `allow_default_port_from`、`allow_to_default_port`) を使用します。

次の例では、任意の IPV4 アドレスからの接続、ならびにデータベースにアクセスするために Auto Scaling グループからの接続を有効にする方法を示しています。

**Example**  

```
listener.connections.allowDefaultPortFromAnyIpv4('Allow public access');

fleet.connections.allowToDefaultPort(rdsDatabase, 'Fleet can access database');
```

```
listener.connections.allowDefaultPortFromAnyIpv4('Allow public access');

fleet.connections.allowToDefaultPort(rdsDatabase, 'Fleet can access database');
```

```
listener.connections.allow_default_port_from_any_ipv4("Allow public access")

fleet.connections.allow_to_default_port(rds_database, "Fleet can access database")
```

```
listener.getConnections().allowDefaultPortFromAnyIpv4("Allow public access");

fleet.getConnections().AllowToDefaultPort(rdsDatabase, "Fleet can access database");
```

```
listener.Connections.AllowDefaultPortFromAnyIpv4("Allow public access");

fleet.Connections.AllowToDefaultPort(rdsDatabase, "Fleet can access database");
```

```
listener.Connections().AllowDefaultPortFromAnyIpv4(jsii.String("Allow public Access"))
fleet.Connections().AllowToDefaultPort(rdsDatabase, jsii.String("Fleet can access database"))
```

## イベントの処理
<a name="resources-events"></a>

一部のリソースはイベントソースとして機能します。`addEventNotification` メソッド (Python: `add_event_notification`) を使用し、リソースによって出力される特定のイベントタイプにイベントターゲットを登録します。これに加え、`addXxxNotification` メソッドは一般的なイベントタイプにハンドラーを簡単に登録する方法を提供します。

次の例では、オブジェクトが Amazon S3 バケットに追加されるときに Lambda 関数をトリガーする方法を示しています。

**Example**  

```
import * as s3nots from '@aws-cdk/aws-s3-notifications';

const handler = new lambda.Function(this, 'Handler', { /*…*/ });
const bucket = new s3.Bucket(this, 'Bucket');
bucket.addObjectCreatedNotification(new s3nots.LambdaDestination(handler));
```

```
const s3nots = require('@aws-cdk/aws-s3-notifications');

const handler = new lambda.Function(this, 'Handler', { /*…*/ });
const bucket = new s3.Bucket(this, 'Bucket');
bucket.addObjectCreatedNotification(new s3nots.LambdaDestination(handler));
```

```
import aws_cdk.aws_s3_notifications as s3_nots

handler = lambda_.Function(self, "Handler", ...)
bucket = s3.Bucket(self, "Bucket")
bucket.add_object_created_notification(s3_nots.LambdaDestination(handler))
```

```
import software.amazon.awscdk.services.s3.Bucket;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.s3.notifications.LambdaDestination;

Function handler = Function.Builder.create(this, "Handler")/* ... */.build();
Bucket bucket = new Bucket(this, "Bucket");
bucket.addObjectCreatedNotification(new LambdaDestination(handler));
```

```
using lambda = Amazon.CDK.AWS.Lambda;
using s3 = Amazon.CDK.AWS.S3;
using s3Nots = Amazon.CDK.AWS.S3.Notifications;

var handler = new lambda.Function(this, "Handler", new lambda.FunctionProps { .. });
var bucket = new s3.Bucket(this, "Bucket");
bucket.AddObjectCreatedNotification(new s3Nots.LambdaDestination(handler));
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  s3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3"
  s3nots "github.com/aws/aws-cdk-go/awscdk/v2/awss3notifications"
)

handler := lambda.NewFunction(this, jsii.String("MyFunction"), &lambda.FunctionProps{})
bucket := s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{})
bucket.AddObjectCreatedNotification(s3nots.NewLambdaDestination(handler), nil)
```

## 削除ポリシー
<a name="resources-removal"></a>

データベース、Amazon S3 バケット、Amazon ECR レジストリなどの永続データを維持するリソースには、*削除ポリシー *があります。削除ポリシーは、永続オブジェクトを含む AWS CDK スタックが破棄されたときに永続オブジェクトを削除するかどうかを示します。削除ポリシーを指定する値は、 AWS CDK `RemovalPolicy` `core`モジュールの列挙を通じて使用できます。

**注記**  
データを継続的に保存するリソース以外のリソースには、別の目的で使用される `removalPolicy` もある場合があります。例えば、Lambda 関数バージョンは `removalPolicy` 属性を使用し、新しいバージョンがデプロイされたときに特定のバージョンが保持されているかどうかを判定します。これらは、Amazon S3 バケットまたは DynamoDB テーブルの削除ポリシーとは異なる意味およびデフォルトを持ちます。


| 値 | 意味 | 
| --- | --- | 
|   `RemovalPolicy.RETAIN`   |  スタックを破棄するとき、リソースの内容を保持します (デフォルト)。リソースはスタックから孤立しているため、手動で削除する必要があります。リソースがまだ存在する間にスタックを再デプロイしようとした場合、名前の競合によってエラーメッセージが表示されます。  | 
|   `RemovalPolicy.DESTROY`   |  リソースはスタックとともに破棄されます。  | 

 AWS CloudFormation は、削除ポリシーが に設定されている場合でも、ファイルを含む Amazon S3 バケットを削除しません`DESTROY`。これを試みると、 AWS CloudFormation エラーが発生します。 AWS CDK でバケットからすべてのファイルを削除してから破棄するには、バケットの `autoDeleteObjects`プロパティを に設定します`true`。

次の内容は、`DESTROY` の `RemovalPolicy` および `autoDeleteOjbects` を `true` に設定して Amazon S3 バケットを作成する例を示します。

**Example**  

```
import * as cdk from '@aws-cdk/core';
import * as s3 from '@aws-cdk/aws-s3';

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

    const bucket = new s3.Bucket(this, 'Bucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      autoDeleteObjects: true
    });
  }
}
```

```
const cdk = require('@aws-cdk/core');
const s3 = require('@aws-cdk/aws-s3');

class CdkTestStack extends cdk.Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    const bucket = new s3.Bucket(this, 'Bucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      autoDeleteObjects: true
    });
  }
}

module.exports = { CdkTestStack }
```

```
import aws_cdk.core as cdk
import aws_cdk.aws_s3 as s3

class CdkTestStack(cdk.stack):
    def __init__(self, scope: cdk.Construct, id: str, **kwargs):
        super().__init__(scope, id, **kwargs)

        bucket = s3.Bucket(self, "Bucket",
            removal_policy=cdk.RemovalPolicy.DESTROY,
            auto_delete_objects=True)
```

```
software.amazon.awscdk.core.*;
import software.amazon.awscdk.services.s3.*;

public class CdkTestStack extends Stack {
    public CdkTestStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkTestStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        Bucket.Builder.create(this, "Bucket")
                .removalPolicy(RemovalPolicy.DESTROY)
                .autoDeleteObjects(true).build();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

public CdkTestStack(Construct scope, string id, IStackProps props) : base(scope, id, props)
{
    new Bucket(this, "Bucket", new BucketProps {
        RemovalPolicy = RemovalPolicy.DESTROY,
        AutoDeleteObjects = true
    });
}
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  s3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3"
)

s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{
  RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
  AutoDeleteObjects: jsii.Bool(true),
})
```

`applyRemovalPolicy()` メソッドを使用して、基になる AWS CloudFormation リソースに削除ポリシーを直接適用することもできます。このメソッドは、L2 リソースの props に `removalPolicy` プロパティを持たないステートフルリソースで利用できます。次に例を示します。
+  AWS CloudFormation スタック
+ Amazon Cognito ユーザープール
+ Amazon DocumentDB データベースインスタンス
+ Amazon EC2 ボリューム
+ Amazon OpenSearch Service ドメイン
+ Amazon FSx ファイルシステム
+ Amazon SQS キュー

**Example**  

```
const resource = bucket.node.findChild('Resource') as cdk.CfnResource;
resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
```

```
const resource = bucket.node.findChild('Resource');
resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
```

```
resource = bucket.node.find_child('Resource')
resource.apply_removal_policy(cdk.RemovalPolicy.DESTROY);
```

```
CfnResource resource = (CfnResource)bucket.node.findChild("Resource");
resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
```

```
var resource = (CfnResource)bucket.node.findChild('Resource');
resource.ApplyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
```

**注記**  
 AWS CDK は AWS CloudFormation の `RemovalPolicy`に変換されます`DeletionPolicy`。ただし、 AWS CDK のデフォルトはデータを保持することであり、 AWS CloudFormation のデフォルトとは逆です。

# 識別子と AWS CDK
<a name="identifiers"></a>

 AWS Cloud Development Kit (AWS CDK) アプリケーションを構築するときは、さまざまなタイプの識別子と名前を使用します。 AWS CDK を効果的に使用し、エラーを回避するには、識別子のタイプを理解することが重要です。

識別子は、作成された範囲内で一意である必要があります。 AWS CDK アプリケーションでグローバルに一意である必要はありません。

同じスコープ内で同じ値を持つ識別子を作成しようとすると、 AWS CDK は例外をスローします。

## コンストラクト ID
<a name="identifiers-construct-ids"></a>

最も一般的な識別子の `id` は、コンストラクトオブジェクトをインスタンス化するときに 2 番目の引数として渡される識別子です。この識別子は、すべての識別子と同様に、作成先の範囲内でのみ一意である必要があり、コンストラクトオブジェクトをインスタンス化するときの最初の引数です。

**注記**  
スタックの `id` は、[AWS CDK CLI リファレンス](cli.md)で参照するために使用する識別子でもあります。

アプリで `MyBucket` 識別子を持つ 2 つのコンストラクトがある例を見てみましょう。1 つ目は、`Stack1` 識別子を持つスタックのスコープで定義されます。2 番目は、`Stack2` 識別子を持つスタックのスコープで定義されます。これらは異なるスコープで定義されているため、競合を引き起こすことはなく、問題なく同じアプリに共存できます。

**Example**  

```
import { App, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';

class MyStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps = {}) {
    super(scope, id, props);

    new s3.Bucket(this, 'MyBucket');
  }
}

const app = new App();
new MyStack(app, 'Stack1');
new MyStack(app, 'Stack2');
```

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

class MyStack extends Stack {
  constructor(scope, id, props = {}) {
    super(scope, id, props);

    new s3.Bucket(this, 'MyBucket');
  }
}

const app = new App();
new MyStack(app, 'Stack1');
new MyStack(app, 'Stack2');
```

```
from aws_cdk import App, Construct, Stack, StackProps
from constructs import Construct
from aws_cdk import aws_s3 as s3

class MyStack(Stack):

    def __init__(self, scope: Construct, id: str, **kwargs):

        super().__init__(scope, id, **kwargs)
        s3.Bucket(self, "MyBucket")

app = App()
MyStack(app, 'Stack1')
MyStack(app, 'Stack2')
```

```
// MyStack.java
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.constructs.Construct;
import software.amazon.awscdk.services.s3.Bucket;

public class MyStack extends Stack {
    public MyStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public MyStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);
        new Bucket(this, "MyBucket");
    }
}

// Main.java
package com.myorg;

import software.amazon.awscdk.App;

public class Main {
    public static void main(String[] args) {
        App app = new App();
        new MyStack(app, "Stack1");
        new MyStack(app, "Stack2");
    }
}
```

```
using Amazon.CDK;
using constructs;
using Amazon.CDK.AWS.S3;

public class MyStack : Stack
{
    public MyStack(Construct scope, string id, IStackProps props) : base(scope, id, props)
    {
        new Bucket(this, "MyBucket");
    }
}

class Program
{
    static void Main(string[] args)
    {
        var app = new App();
        new MyStack(app, "Stack1");
        new MyStack(app, "Stack2");
    }
}
```

## パス
<a name="identifiers-paths"></a>

 AWS CDK アプリケーションのコンストラクトは、 `App` クラスにルートされた階層を形成します。特定のコンストラクト、その親コンストラクト、その祖父母などの ID のコレクションを、*パス*としてコンストラクトツリーのルートに参照します。

 AWS CDK は通常、テンプレート内のパスを文字列として表示します。レベルからの ID は、通常はスタックであるルート `App` インスタンスのすぐ下のノードから始まるスラッシュで区切られます。例えば、前のコード例にある 2 つの Amazon S3 バケットリソースのパスは `Stack1/MyBucket` および `Stack2/MyBucket` です。

次の例で示すように、プログラムですべてのコンストラクトのパスにアクセスできます。これは `myConstruct` (Python デベロッパーは `my_construct` と記述します) のパスを取得します。IDs は作成されるスコープ内で一意である必要があるため、パスは常に AWS CDK アプリケーション内で一意です。

**Example**  

```
const path: string = myConstruct.node.path;
```

```
const path = myConstruct.node.path;
```

```
path = my_construct.node.path
```

```
String path = myConstruct.getNode().getPath();
```

```
string path = myConstruct.Node.Path;
```

## 一意の ID
<a name="identifiers-unique-ids"></a>

 AWS CloudFormation では、テンプレート内のすべての論理 IDs が一意である必要があります。このため、 AWS CDK はアプリケーション内のコンストラクトごとに一意の識別子を生成できる必要があります。リソースには、グローバルに一意のパス (スタックから特定のリソースへの範囲で、すべてのスコープの名前) があります。したがって、 AWS CDK はパスの要素を連結し、8 桁のハッシュを追加することで、必要な一意の識別子を生成します。(ハッシュは、同じ AWS CloudFormation 識別子になる `A/B/C`や などの個別のパスを区別するために必要です。 AWS CloudFormation 識別子は英数字であり`A/BC`、スラッシュやその他の区切り文字を含めることはできません）。 AWS CDK はこの文字列をコンストラクトの*一意の ID* と呼び出します。

一般的に、 AWS CDK アプリは一意の IDs について知る必要はありません。ただし、次の例で示すように、任意のコンストラクトの一意の ID にプログラムでアクセスできます。

**Example**  

```
const uid: string = Names.uniqueId(myConstruct);
```

```
const uid = Names.uniqueId(myConstruct);
```

```
uid = Names.unique_id(my_construct)
```

```
String uid = Names.uniqueId(myConstruct);
```

```
string uid = Names.Uniqueid(myConstruct);
```

*アドレス*は、CDK リソースを一意に区別する別な種類の一意の識別子です。パスの SHA-1 ハッシュから派生し、人間が読み取れません。ただし、定数で比較的に短い長さ (常に 42 個の 16 進数文字) は、「従来」の一意の ID が長すぎる状況で役立ちます。一部のコンストラクトでは、一意の ID の代わりに合成された AWS CloudFormation テンプレートのアドレスを使用する場合があります。繰り返しになりますが、アプリは一般的にコンストラクトのアドレスを知る必要はありませんが、次のようにコンストラクトのアドレスを取得できます。

**Example**  

```
const addr: string = myConstruct.node.addr;
```

```
const addr = myConstruct.node.addr;
```

```
addr = my_construct.node.addr
```

```
String addr = myConstruct.getNode().getAddr();
```

```
string addr = myConstruct.Node.Addr;
```

## 論理 ID
<a name="identifiers-logical-ids"></a>

 AWS CDK がアプリケーションを AWS CloudFormation テンプレートに合成すると、リソースごとに*論理 ID* が生成されます。 AWS CloudFormation は論理 IDs を使用してテンプレート内のリソースを識別し、デプロイ間でリソースを追跡します。論理 IDs の生成方法を理解することで、CDK コードをリファクタリングする際の意図しないリソースの置き換えを回避できます。

### 論理 IDs の生成方法
<a name="identifiers-logical-id-generation"></a>

 AWS CDK は、次のアルゴリズムを使用してコンストラクトパスから論理 IDs を生成します。

1. スタック自体を除き、コンストラクトツリーからパスコンポーネントを連結します。

1. ヒューリスティックを適用して読みやすさを向上させます ([「論理 ID パスコンポーネントのヒューリスティック](#identifiers-logical-id-heuristics)」を参照）。

1. 一意性を確保するために、フルパスの 8 文字のハッシュを追加します。

結果の形式は次のとおりです。

```
<human-readable-portion><8-character-hash>
```

たとえば、VPC プライベートサブネットルートテーブルは論理 ID を生成する場合があります`VPCPrivateSubnet2RouteTable0A19E10E`。

論理 ID の生成には、次のルールが適用されます。
+ 最大長は 255 文字です。人間が読める部分は 240 文字に制限されています。
+ 8 文字のハッシュにより、同じ文字列に連結する `A/B/C`や `A/BC` などのパスが異なる論理 IDs を生成するようになります。
+ スタックの直接の子であるリソース (単一コンポーネントパス) は、名前が 255 文字以下であれば、ハッシュなしで直接名前を使用します。

### 論理 ID パスコンポーネントのヒューリスティック
<a name="identifiers-logical-id-heuristics"></a>

 AWS CDK は、論理 IDs。

 `Default` — 完全に削除  
パスコンポーネントが の場合`Default`、CDK は人間が読み取り可能な部分とハッシュ入力の両方からそのコンポーネントを削除します。つまり、既存のコンストラクトを新しいコンストラクト内にラップし、内部コンストラクトに名前を付けると、元のラップされていないコンストラクトとまったく同じ論理 ID `Default`が生成されます。これは、デプロイされたリソース ID を変更せずにフラットコードを上位レベルのコンストラクトに安全にリファクタリングするための重要なメカニズムです。

 `Resource` — 人間が読み取り可能な部分からのみ非表示  
パスコンポーネントが の場合`Resource`、CDK はそれを人間が読み取り可能な部分から省略しますが、ハッシュ計算に含めます。L1 (CloudFormation) コンストラクトは、規則によってコンストラクト ID `Resource`として を使用します。これにより、一意性を失うことなく論理 IDs短くすることができます。

重複する連続コンポーネント — 重複排除  
上記のパスコンポーネント名が現在のコンポーネント名で終わると、CDK は現在のコンポーネントをスキップします。これにより、論理 IDs。

### リファクタリング時に論理 IDs を保持するには、 `Default`を使用します。
<a name="identifiers-logical-id-refactoring"></a>

フラットスタックを上位レベルのコンストラクトにリファクタリングする場合、プライマリリソースのコンストラクト ID `Default`として を使用して論理 ID を保持できます。これにより、 AWS CloudFormation はデプロイ中にリソースを置き換えることができません。

次の例は、リソースが直接定義されているスタックを示しています。

**Example**  

```
export class MyStack extends cdk.Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);
    new s3.Bucket(this, 'DataBucket');
    new lambda.Function(this, 'ProcessFunction', { /* ... */ });
  }
}
```

```
class MyStack extends cdk.Stack {
  constructor(scope, id) {
    super(scope, id);
    new s3.Bucket(this, 'DataBucket');
    new lambda.Function(this, 'ProcessFunction', { /* ... */ });
  }
}
```

```
from aws_cdk import (
    Stack,
    aws_s3 as s3,
    aws_lambda as _lambda,
)
from constructs import Construct

class MyStack(Stack):
    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)
        s3.Bucket(self, "DataBucket")
        _lambda.Function(self, "ProcessFunction", # ...
        )
```

```
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.lambda.Function;

public class MyStack extends Stack {
    public MyStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public MyStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);
        new Bucket(this, "DataBucket");
        Function.Builder.create(this, "ProcessFunction")
            // ...
            .build();
    }
}
```

```
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.Lambda;

namespace MyApp
{
    public class MyStack : Stack
    {
        public MyStack(Construct scope, string id, StackProps props = null) : base(scope, id, props)
        {
            new Bucket(this, "DataBucket");
            new Function(this, "ProcessFunction", new FunctionProps
            {
                // ...
            });
        }
    }
}
```

```
package main

import (
	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
	"github.com/aws/aws-cdk-go/awscdk/v2/awss3"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type MyStackProps struct {
	awscdk.StackProps
}

func NewMyStack(scope constructs.Construct, id string, props *MyStackProps) awscdk.Stack {
	stack := awscdk.NewStack(scope, &id, &props.StackProps)

	awss3.NewBucket(stack, jsii.String("DataBucket"), &awss3.BucketProps{})
	awslambda.NewFunction(stack, jsii.String("ProcessFunction"), &awslambda.FunctionProps{
		// ...
	})

	return stack
}
```

バケットのパスは で`MyStack/DataBucket/Resource`、論理 ID は になります`DataBucket<hash>`。

バケットを上位レベルのコンストラクトに抽出し、内部コンストラクト に名前を付けることで同じ論理 ID を保持できます`Default`。

**Example**  

```
class DataPipeline extends Construct {
  constructor(scope: Construct, id: string) {
    super(scope, id);
    new s3.Bucket(this, 'Default');  // 'Default' is hidden from logical ID
    new lambda.Function(this, 'ProcessFunction', { /* ... */ });
  }
}

export class MyStack extends cdk.Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);
    new DataPipeline(this, 'DataBucket');
  }
}
```

```
class DataPipeline extends Construct {
  constructor(scope, id) {
    super(scope, id);
    new s3.Bucket(this, 'Default');  // 'Default' is hidden from logical ID
    new lambda.Function(this, 'ProcessFunction', { /* ... */ });
  }
}

class MyStack extends cdk.Stack {
  constructor(scope, id) {
    super(scope, id);
    new DataPipeline(this, 'DataBucket');
  }
}
```

```
from aws_cdk import (
    Stack,
    aws_s3 as s3,
    aws_lambda as _lambda,
)
from constructs import Construct

class DataPipeline(Construct):
    def __init__(self, scope: Construct, id: str) -> None:
        super().__init__(scope, id)
        s3.Bucket(self, "Default")  # 'Default' is hidden from logical ID
        _lambda.Function(self, "ProcessFunction", # ...
        )

class MyStack(Stack):
    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)
        DataPipeline(self, "DataBucket")
```

```
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.lambda.Function;

public class DataPipeline extends Construct {
    public DataPipeline(final Construct scope, final String id) {
        super(scope, id);
        new Bucket(this, "Default");  // 'Default' is hidden from logical ID
        Function.Builder.create(this, "ProcessFunction")
            // ...
            .build();
    }
}

public class MyStack extends Stack {
    public MyStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public MyStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);
        new DataPipeline(this, "DataBucket");
    }
}
```

```
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.Lambda;

namespace MyApp
{
    public class DataPipeline : Construct
    {
        public DataPipeline(Construct scope, string id) : base(scope, id)
        {
            new Bucket(this, "Default");  // 'Default' is hidden from logical ID
            new Function(this, "ProcessFunction", new FunctionProps
            {
                // ...
            });
        }
    }

    public class MyStack : Stack
    {
        public MyStack(Construct scope, string id, StackProps props = null) : base(scope, id, props)
        {
            new DataPipeline(this, "DataBucket");
        }
    }
}
```

```
package main

import (
	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
	"github.com/aws/aws-cdk-go/awscdk/v2/awss3"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type DataPipeline struct {
	constructs.Construct
}

func NewDataPipeline(scope constructs.Construct, id string) constructs.Construct {
	this := constructs.NewConstruct(scope, &id)

	// 'Default' is hidden from logical ID
	awss3.NewBucket(this, jsii.String("Default"), &awss3.BucketProps{})
	awslambda.NewFunction(this, jsii.String("ProcessFunction"), &awslambda.FunctionProps{
		// ...
	})

	return this
}

type MyStackProps struct {
	awscdk.StackProps
}

func NewMyStack(scope constructs.Construct, id string, props *MyStackProps) awscdk.Stack {
	stack := awscdk.NewStack(scope, &id, &props.StackProps)

	NewDataPipeline(stack, "DataBucket")

	return stack
}
```

バケットのパスは になりました`MyStack/DataBucket/Default/Resource`。`Default` は人間が読み取り可能な部分とハッシュ入力の両方から削除されるため、論理 ID は元の ID `DataBucket<hash>` と同じままになります。

**重要**  
コンストラクトスコープ`Default`ごとに ID を持つ子を 1 つだけ持つことができます。同じレベルで複数のリソースが必要な場合は、わかりやすい IDsを指定します。この`Default`パターンは、1 つのプライマリリソースを持つ単一責任構造に最適です。

### 制約事項と考慮事項
<a name="identifiers-logical-id-considerations"></a>

論理 IDs を使用する場合は、次の点に注意してください。
+ `Default` コンストラクト ID は、スコープごとに 1 つの子のみを割り当てることができます。
+ デプロイ後にコンストラクト ID を変更すると、論理 ID が変更され、 AWS CloudFormation がリソースを置き換えます。デプロイする前に`cdk diff`、 を使用して変更を確認します。
+ 論理 IDs がすでに変更されている場合は、 `cdk refactor` コマンドを使用して古い論理 ID を新しい論理 IDs にマッピングできます。詳細については、「[CDK コードのリファクタリング時にデプロイされたリソースを保持する](refactor.md)」を参照してください。
+ 合成されたテンプレートに論理 IDs がどのように表示されるかの詳細については、[AWS CloudFormation テンプレートのIDs](configure-synth.md#how-synth-default-logical-ids)」を参照してください。

### 論理 ID の安定性
<a name="identifiers-logical-id-stability"></a>

リソースの作成後に論理 ID を変更しないでください。 AWS CloudFormation はリソースを論理 ID で識別します。したがって、リソースの論理 ID を変更すると、 AWS CloudFormation は新しい論理 ID を使用して新しいリソースを作成し、 は既存のリソースを削除します。リソースのタイプによっては、サービスの中断、データ損失、その両方が発生する場合があります。

# トークンと AWS CDK
<a name="tokens"></a>

AWS Cloud Development Kit (AWS CDK) では、*トークン*は、コンストラクトの定義やスタックの合成時にわからない値のプレースホルダーです。実際のインフラストラクチャが作成されると、これらの値はデプロイ時に完全に解決されます。AWS CDK アプリケーションを開発するとき、トークンを使用してアプリケーション全体でこれらの値を管理します。

## トークンの例
<a name="tokens-example"></a>

次の内容は、Amazon Simple Storage Service (Amazon S3) バケットのコンストラクトを定義する CDK スタックの例です。バケットの名前はまだ不明なため、`bucketName` の値はトークンとして保存されます。

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';

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

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // Store value of the S3 bucket name
    const myBucketName = myBucket.bucketName;

    // Print the current value for the S3 bucket name at synthesis
    console.log("myBucketName: " + myBucketName);
  }
}
```

```
const { Stack, Duration } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // Store value of the S3 bucket name
    const myBucketName = myBucket.bucketName;

    // Print the current value for the S3 bucket name at synthesis
    console.log("myBucketName: " + myBucketName);
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Stack
)
from constructs import Construct
from aws_cdk import aws_s3 as s3

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define an S3 bucket
        my_bucket = s3.Bucket(self, "myBucket")

        # Store the value of the S3 bucket name
        my_bucket_name = my_bucket.bucket_name

        # Print the current value for the S3 bucket name at synthesis
        print(f"myBucketName: {my_bucket_name}")
```

```
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 java.util.Map;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define an S3 bucket
        Bucket myBucket = Bucket.Builder.create(this, "myBucket")
            .build();

        // Store the token for the bucket name
        String myBucketName = myBucket.getBucketName();

        // Print the token at synthesis
        System.out.println("myBucketName: " + myBucketName);
    }
}
```

```
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.S3;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define an S3 bucket
            var myBucket = new Bucket(this, "myBucket");

            // Store the token for the bucket name
            var myBucketName = myBucket.BucketName;

            // Print the token at synthesis
            System.Console.WriteLine($"myBucketName: {myBucketName}");
        }
    }
}
```

```
package main

import (
	"fmt"

	"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 CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define an S3 bucket
	myBucket := awss3.NewBucket(stack, jsii.String("myBucket"), &awss3.BucketProps{})

	// Store the token for the bucket name
	myBucketName := myBucket.BucketName()

	// Print the token at synthesis
	fmt.Println("myBucketName: ", *myBucketName)

	return stack
}

// ...
```
スタックを合成するために `cdk synth` を実行するとき、`myBucketName` の値は `${Token[TOKEN.<1234>]}` のトークン形式で表示されます。このトークン形式は、AWS CDK がトークンをエンコードする方法の結果です。この例では、トークンは文字列としてエンコードされます。  

```
$ cdk synth --quiet
myBucketName: ${Token[TOKEN.21]}
```
バケット名の値は合成時にわからないため、トークンは `myBucket<unique-hash>` としてレンダリングされます。AWS CloudFormation テンプレートは `Ref` 組み込み関数を使用してその値を参照し、デプロイ時に判明されます。  

```
Resources:
  myBucket<5AF9C99B>:
    # ...
Outputs:
  bucketNameOutput:
    Description: The name of the S3 bucket
    Value:
      Ref: myBucket<5AF9C99B>
```

一意のハッシュの生成方法の詳細については、「[AWS CloudFormation テンプレートの生成された論理 ID](configure-synth.md#how-synth-default-logical-ids)」を参照してください。

## トークンを渡す
<a name="tokens-passing"></a>

トークンが表す実際の値であるかのように、渡すことができます。次の内容は、バケット名のトークンを AWS Lambda 関数の コンストラクトに渡す例です。

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as lambda from 'aws-cdk-lib/aws-lambda';

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

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // ...

    // Define a Lambda function
    const myFunction = new lambda.Function(this, "myFunction", {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: "index.handler",
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
      `),
      functionName: myBucketName + "Function", // Pass token for the S3 bucket name
      environment: {
        BUCKET_NAME: myBucketName, // Pass token for the S3 bucket name
      }
    });
  }
}
```

```
const { Stack, Duration } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');
const lambda = require('aws-cdk-lib/aws-lambda');

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // ...

    // Define a Lambda function
    const myFunction = new lambda.Function(this, 'myFunction', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
      `),
      functionName: myBucketName + 'Function', // Pass token for the S3 bucket name
      environment: {
        BUCKET_NAME: myBucketName, // Pass token for the S3 bucket name
      }
    });
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Stack
)
from constructs import Construct
from aws_cdk import aws_s3 as s3
from aws_cdk import aws_lambda as _lambda

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define an S3 bucket
        my_bucket = s3.Bucket(self, "myBucket")

        # ...

        # Define a Lambda function
        my_function = _lambda.Function(self, "myFunction",
            runtime=_lambda.Runtime.NODEJS_20_X,
            handler="index.handler",
            code=_lambda.Code.from_inline("""
                exports.handler = async function(event) {
                  return {
                    statusCode: 200,
                    body: JSON.stringify('Hello World!'),
                  };
                };
            """),
            function_name=f"{my_bucket_name}Function",  # Pass token for the S3 bucket name
            environment={
                "BUCKET_NAME": my_bucket_name  # Pass token for the S3 bucket name
            }
        )
```

```
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.lambda.Code;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;

import java.util.Map;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define an S3 bucket
        Bucket myBucket = Bucket.Builder.create(this, "myBucket")
            .build();

        // ...

        // Define a Lambda function
        Function myFunction = Function.Builder.create(this, "myFunction")
            .runtime(Runtime.NODEJS_20_X)
            .handler("index.handler")
            .code(Code.fromInline(
                "exports.handler = async function(event) {" +
                "return {" +
                "statusCode: 200," +
                "body: JSON.stringify('Hello World!')," +
                "};" +
                "};"
            ))
            .functionName(myBucketName + "Function") // Pass the token for the s3 bucket to the function construct
            .environment(Map.of("BUCKET_NAME", myBucketName))  // Pass the bucket name as environment variable
            .build();
    }
}
```

```
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.Lambda;
using System;
using System.Collections.Generic;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define an S3 bucket
            var myBucket = new Bucket(this, "myBucket");

            // ...

            // Define a Lambda function
            var myFunction = new Function(this, "myFunction", new FunctionProps
            {
                 Runtime = Runtime.NODEJS_20_X,
                 Handler = "index.handler",
                 Code = Code.FromInline(@"
                     exports.handler = async function(event) {
                       return {
                         statusCode: 200,
                         body: JSON.stringify('Hello World!'),
                       };
                     };
                 "),
                 // Pass the token for the S3 bucket name
                 Environment = new Dictionary<string, string>
                 {
                     { "BUCKET_NAME", myBucketName }
                 },
                 FunctionName = $"{myBucketName}Function" // Pass the token for the s3 bucket to the function construct
            });
        }
    }
}
```

```
package main

import (
	"fmt"

	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
	"github.com/aws/aws-cdk-go/awscdk/v2/awss3"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define an S3 bucket
	myBucket := awss3.NewBucket(stack, jsii.String("myBucket"), &awss3.BucketProps{})

	// ...

	// Define a Lambda function
	myFunction := awslambda.NewFunction(stack, jsii.String("myFunction"), &awslambda.FunctionProps{
		Runtime: awslambda.Runtime_NODEJS_20_X(),
		Handler: jsii.String("index.handler"),
		Code: awslambda.Code_FromInline(jsii.String(`
			exports.handler = async function(event) {
				return {
					statusCode: 200,
					body: JSON.stringify('Hello World!'),
				};
			};
		`)),
		FunctionName: jsii.String(fmt.Sprintf("%sFunction", *myBucketName)), // Pass the token for the S3 bucket to the function name
		Environment: &map[string]*string{
			"BUCKET_NAME": myBucketName,
		},
	})

	return stack
}
// ...
```
テンプレートを合成するときに `Ref` および `Fn::Join` の組み込み関数を使用して値を指定し、デプロイ時に判明されます。  

```
Resources:
  myBucket<5AF9C99B>:
    Type: AWS::S3::Bucket
    # ...
  myFunction<884E1557>:
    Type: AWS::Lambda::Function
    Properties:
      # ...
      Environment:
        Variables:
          BUCKET_NAME:
            Ref: myBucket<5AF9C99B>
      FunctionName:
        Fn::Join:
          - ""
          - - Ref: myBucket<5AF9C99B>
            - Function
      # ...
```

## トークンエンコーディングの仕組み
<a name="tokens-work"></a>

トークンは、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.IResolvable.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.IResolvable.html) インターフェイスを実装するオブジェクトであり、1 つの `resolve` メソッドが含まれています。合成中、AWS CDK はこのメソッドを呼び出して CloudFormation テンプレートのトークンの最終値を生成します。

**注記**  
`IResolvable` インターフェイスを直接操作することはめったにありません。ほとんどの場合、トークンの文字列エンコードされたバージョンのみが表示されます。

### トークンエンコードのタイプ
<a name="tokens-work-types"></a>

トークンは合成プロセスに関与し、すべてのタイプにおける任意の値を生成します。通常、他の関数は `string` や `number` などの基本的なタイプの引数のみを受け入れます。このような場合にトークンを使用するには、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html) クラスの静的メソッドを使用して 3 つのタイプのいずれかにトークンをエンコードできます。
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrstringvalue-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrstringvalue-options) で文字列エンコーディング (またはトークンオブジェクトで `.toString()` を呼び出す) を生成します。
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrlistvalue-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrlistvalue-options) でリストエンコーディングを生成します。
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrnumbervalue](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrnumbervalue) で数値エンコーディングを生成します。

`IResolvable` の可能性がある任意の値を取得し、指定されたタイプのプリミティブ値にエンコードします。

**重要**  
前のタイプのいずれかがエンコードされたトークンである可能性があるため、内容を解析または読み取ろうとするときは注意してください。例えば、文字列を解析してそこから値を抽出しようとし、文字列がエンコードされたトークンである場合、解析は失敗します。同様に、配列の長さをクエリしたり、数値で数学演算を実行したりした場合は、最初にエンコードされたトークンではないことを確認する必要があります。

## アプリでトークンを確認する方法
<a name="tokens-check"></a>

値に未解決のトークンが含まれているかどうかを確認するには、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-iswbrunresolvedobj](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-iswbrunresolvedobj) (Python: `is_unresolved`) メソッドを呼び出します。次の内容は、Amazon S3 バケット名の値がトークンであるかどうかをチェックする例です。トークンではない場合、バケット名の長さを検証します。

**Example**  

```
// ...

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

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');
    // ...

    // Check if bucket name is a token. If not, check if length is less than 10 characters
    if (cdk.Token.isUnresolved(myBucketName)) {
      console.log("Token identified.");
    } else if (!cdk.Token.isUnresolved(myBucketName) && myBucketName.length > 10) {
      throw new Error('Maximum length for name is 10 characters.');
    };

    // ...
  }
}
```

```
const { Stack, Duration, Token, CfnOutput } = require('aws-cdk-lib');
// ...

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // ...

    // Check if bucket name is a token. If not, check if length is less than 10 characters
    if (Token.isUnresolved(myBucketName)) {
      console.log("Token identified.");
    } else if (!Token.isUnresolved(myBucketName) && myBucketName.length > 10) {
      throw new Error('Maximum length for name is 10 characters.');
    };

    // ...
  }
}
```

```
from aws_cdk import (
    Stack,
    Token
)
# ...

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define an S3 bucket
        my_bucket = s3.Bucket(self, "myBucket")

        # ...

        # Check if bucket name is a token. If not, check if length is less than 10 characters
        if Token.is_unresolved(my_bucket_name):
            print("Token identified.")
        elif not Token.is_unresolved(my_bucket_name) and len(my_bucket_name) < 10:
            raise ValueError("Maximum length for name is 10 characters.")

        # ...
```

```
// ...
import software.amazon.awscdk.Token;
import software.amazon.awscdk.services.s3.Bucket;
// ...

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define an S3 bucket
        Bucket myBucket = Bucket.Builder.create(this, "myBucket")
            .build();

        // ...

        // Get the bucket name
        String myBucketName = myBucket.getBucketName();

        // Check if the bucket name is a token. If not, check if length is less than 10 characters
        if (Token.isUnresolved(myBucketName)) {
            System.out.println("Token identified.");
        } else if (!Token.isUnresolved(myBucketName) && myBucketName.length() > 10) {
            throw new IllegalArgumentException("Maximum length for name is 10 characters.");
        }

        // ...
      }
    }
  }
```

```
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.Lambda;
using System;
using System.Collections.Generic;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define an S3 bucket
            var myBucket = new Bucket(this, "myBucket");

            // ...

            // Get the bucket name
            var myBucketName = myBucket.BucketName;

            // Check if bucket name is a token. If not, check if length is less than 10 characters
            if (Token.IsUnresolved(myBucketName))
            {
                System.Console.WriteLine("Token identified.");
            }
            else if (!Token.IsUnresolved(myBucketName) && myBucketName.Length > 10)
            {
                throw new System.Exception("Maximum length for name is 10 characters.");
            }

            // ...
        }
    }
}
```

```
// ...

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define an S3 bucket
	myBucket := awss3.NewBucket(stack, jsii.String("myBucket"), &awss3.BucketProps{})

	// ...

	// Check if the bucket name is unresolved (a token)
	if tokenUnresolved := awscdk.Token_IsUnresolved(myBucketName); tokenUnresolved != nil && *tokenUnresolved {
		fmt.Println("Token identified.")
	} else if tokenUnresolved != nil && !*tokenUnresolved && len(*myBucketName) > 10 {
		panic("Maximum length for name is 10 characters.")
	}

	// ...
}
```

`cdk synth` を実行するとき、`myBucketName` はトークンとして識別されます。

```
$ cdk synth --quiet
Token identified.
```

**注記**  
トークンエンコーディングを使用し、タイプシステムからエスケープできます。例えば、合成時に数値を生成するトークンを文字列エンコードできます。これらの関数を使用する場合、合成後にテンプレートが使用可能な状態に解決されていることを確認するのがユーザーの責任です。

## 文字列エンコードされたトークンの使用
<a name="tokens-string"></a>

文字列エンコードされたトークンは次のようになります。

```
${TOKEN[Bucket.Name.1234]}
```

次の例で示すように、通常の文字列のように渡して連結できます。

**Example**  

```
const functionName = bucket.bucketName + 'Function';
```

```
const functionName = bucket.bucketName + 'Function';
```

```
function_name = bucket.bucket_name + "Function"
```

```
String functionName = bucket.getBucketName().concat("Function");
```

```
string functionName = bucket.BucketName + "Function";
```

```
functionName := *bucket.BucketName() + "Function"
```

次の例で示すように、言語が文字列補間をサポートしている場合、文字列補間も使用できます。

**Example**  

```
const functionName = `${bucket.bucketName}Function`;
```

```
const functionName = `${bucket.bucketName}Function`;
```

```
function_name = f"{bucket.bucket_name}Function"
```

```
String functionName = String.format("%sFunction". bucket.getBucketName());
```

```
string functionName = $"${bucket.bucketName}Function";
```
同様の機能には `fmt.Sprintf` を使用します。  

```
functionName := fmt.Sprintf("%sFunction", *bucket.BucketName())
```

他の方法で文字列を操作しないでください。例えば、文字列の部分文字列を取ると、文字列トークンが壊れる可能性があります。

## リストエンコードされたトークンの使用
<a name="tokens-list"></a>

リストエンコードされたトークンは次のようになります。

```
["#{TOKEN[Stack.NotificationArns.1234]}"]
```

これらのリストにする唯一の安全なことは、他のコンストラクトに直接渡すことです。文字列リスト形式のトークンは連結することも、トークンから要素を取得することもできません。安全に操作する唯一の方法は、[https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html) などの AWS CloudFormation 組み込み関数を使用することです。

## 番号エンコードされたトークンの使用
<a name="tokens-number"></a>

数値エンコードされたトークンは、次のような小さな負の浮動小数点数のセットです。

```
-1.8881545897087626e+289
```

リストトークンと同様に、数値トークンが壊れる可能性があるため、数値は変更できません。

次の内容は、数値としてエンコードされたトークンを含むコンストラクトの例です。

**Example**  

```
import { Stack, Duration, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as rds from 'aws-cdk-lib/aws-rds';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

export class CdkDemoAppStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // Define a new VPC
    const vpc = new ec2.Vpc(this, 'MyVpc', {
      maxAzs: 3,  // Maximum number of availability zones to use
    });

    // Define an RDS database cluster
    const dbCluster = new rds.DatabaseCluster(this, 'MyRDSCluster', {
      engine: rds.DatabaseClusterEngine.AURORA,
      instanceProps: {
        vpc,
      },
    });

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // Print the value for our token at synthesis
    console.log("portToken: " + portToken);
  }
}
```

```
const { Stack, Duration } = require('aws-cdk-lib');
const lambda = require('aws-cdk-lib/aws-lambda');
const rds = require('aws-cdk-lib/aws-rds');
const ec2 = require('aws-cdk-lib/aws-ec2');

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define a new VPC
    const vpc = new ec2.Vpc(this, 'MyVpc', {
      maxAzs: 3,  // Maximum number of availability zones to use
    });

    // Define an RDS database cluster
    const dbCluster = new rds.DatabaseCluster(this, 'MyRDSCluster', {
      engine: rds.DatabaseClusterEngine.AURORA,
      instanceProps: {
        vpc,
      },
    });

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // Print the value for our token at synthesis
    console.log("portToken: " + portToken);
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Duration,
    Stack,
)
from aws_cdk import aws_rds as rds
from aws_cdk import aws_ec2 as ec2
from constructs import Construct

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define a new VPC
        vpc = ec2.Vpc(self, 'MyVpc',
            max_azs=3  # Maximum number of availability zones to use
        )

        # Define an RDS database cluster
        db_cluster = rds.DatabaseCluster(self, 'MyRDSCluster',
            engine=rds.DatabaseClusterEngine.AURORA,
            instance_props=rds.InstanceProps(
                vpc=vpc
            )
        )

        # Get the port token (this is a token encoded as a number)
        port_token = db_cluster.cluster_endpoint.port

        # Print the value for our token at synthesis
        print(f"portToken: {port_token}")
```

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.ec2.Vpc;
import software.amazon.awscdk.services.rds.DatabaseCluster;
import software.amazon.awscdk.services.rds.DatabaseClusterEngine;
import software.amazon.awscdk.services.rds.InstanceProps;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define a new VPC
        Vpc vpc = Vpc.Builder.create(this, "MyVpc")
            .maxAzs(3) // Maximum number of availability zones to use
            .build();

        // Define an RDS database cluster
        DatabaseCluster dbCluster = DatabaseCluster.Builder.create(this, "MyRDSCluster")
            .engine(DatabaseClusterEngine.AURORA)
            .instanceProps(InstanceProps.builder()
                .vpc(vpc)
                .build())
            .build();

        // Get the port token (this is a token encoded as a number)
        Number portToken = dbCluster.getClusterEndpoint().getPort();

        // Print the value for our token at synthesis
        System.out.println("portToken: " + portToken);
    }
}
```

```
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.EC2;
using Amazon.CDK.AWS.RDS;
using System;
using System.Collections.Generic;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define a new VPC
            var vpc = new Vpc(this, "MyVpc", new VpcProps
            {
                MaxAzs = 3  // Maximum number of availability zones to use
            });

            // Define an RDS database cluster
            var dbCluster = new DatabaseCluster(this, "MyRDSCluster", new DatabaseClusterProps
            {
                Engine = DatabaseClusterEngine.AURORA,  // Remove parentheses
                InstanceProps = new Amazon.CDK.AWS.RDS.InstanceProps // Specify RDS InstanceProps
                {
                    Vpc = vpc
                }
            });

            // Get the port token (this is a token encoded as a number)
            var portToken = dbCluster.ClusterEndpoint.Port;

            // Print the value for our token at synthesis
            System.Console.WriteLine($"portToken: {portToken}");
        }
    }
}
```

```
package main

import (
	"fmt"

	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsec2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsrds"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define a new VPC
	vpc := awsec2.NewVpc(stack, jsii.String("MyVpc"), &awsec2.VpcProps{
		MaxAzs: jsii.Number(3), // Maximum number of availability zones to use
	})

	// Define an RDS database cluster
	dbCluster := awsrds.NewDatabaseCluster(stack, jsii.String("MyRDSCluster"), &awsrds.DatabaseClusterProps{
		Engine: awsrds.DatabaseClusterEngine_AURORA(),
		InstanceProps: &awsrds.InstanceProps{
			Vpc: vpc,
		},
	})

	// Get the port token (this is a token encoded as a number)
	portToken := dbCluster.ClusterEndpoint().Port()

	// Print the value for our token at synthesis
	fmt.Println("portToken: ", portToken)

	return stack
}

// ...
```

`cdk synth` を実行するとき、`portToken` の値が数値エンコードされたトークンとして表示されます。

```
$ cdk synth --quiet
portToken: -1.8881545897087968e+289
```

### 数値エンコードされたトークンを渡す
<a name="tokens-number-pass"></a>

数値エンコードされたトークンを他のコンストラクトに渡すとき、最初に文字列に変換するのが理にかなっている場合があります。例えば、数値エンコードされた文字列の値を連結文字列の一部として使用する場合、変換すると読みやすくなります。

次の例では、`portToken` は `connectionString` の一部として Lambda 関数に渡す数値エンコードされたトークンです。

**Example**  

```
import { Stack, Duration, CfnOutput, StackProps } from 'aws-cdk-lib';
// ...
import * as lambda from 'aws-cdk-lib/aws-lambda';

export class CdkDemoAppStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // Define a new VPC
    // ...

    // Define an RDS database cluster
    // ...

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // ...

    // Example connection string with the port token as a number
    const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portToken}/mydatabase`;

    // Use the connection string as an environment variable in a Lambda function
    const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
      `),
      environment: {
        DATABASE_CONNECTION_STRING: connectionString,  // Using the port token as part of the string
      },
    });

    // Output the value of our connection string at synthesis
    console.log("connectionString: " + connectionString);

    // Output the connection string
    new CfnOutput(this, 'ConnectionString', {
      value: connectionString,
    });
  }
}
```

```
const { Stack, Duration, CfnOutput } = require('aws-cdk-lib');
// ...
const lambda = require('aws-cdk-lib/aws-lambda');

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define a new VPC
    // ...

    // Define an RDS database cluster
    // ...

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // ...

    // Example connection string with the port token as a number
    const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portToken}/mydatabase`;

    // Use the connection string as an environment variable in a Lambda function
    const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
      `),
      environment: {
        DATABASE_CONNECTION_STRING: connectionString,  // Using the port token as part of the string
      },
    });

    // Output the value of our connection string at synthesis
    console.log("connectionString: " + connectionString);

    // Output the connection string
    new CfnOutput(this, 'ConnectionString', {
      value: connectionString,
    });
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Duration,
    Stack,
    CfnOutput,
)
from aws_cdk import aws_lambda as _lambda
# ...

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define a new VPC
        # ...

        # Define an RDS database cluster
        # ...

        # Get the port token (this is a token encoded as a number)
        port_token = db_cluster.cluster_endpoint.port

        # ...

        # Example connection string with the port token as a number
        connection_string = f"jdbc:mysql://mydb.cluster.amazonaws.com:{port_token}/mydatabase"

        # Use the connection string as an environment variable in a Lambda function
        my_function = _lambda.Function(self, 'MyLambdaFunction',
            runtime=_lambda.Runtime.NODEJS_20_X,
            handler='index.handler',
            code=_lambda.Code.from_inline("""
                exports.handler = async function(event) {
                    return {
                        statusCode: 200,
                        body: JSON.stringify('Hello World!'),
                    };
                };
            """),
            environment={
                'DATABASE_CONNECTION_STRING': connection_string  # Using the port token as part of the string
            }
        )

        # Output the value of our connection string at synthesis
        print(f"connectionString: {connection_string}")

        # Output the connection string
        CfnOutput(self, 'ConnectionString',
            value=connection_string
        )
```

```
// ...
import software.amazon.awscdk.CfnOutput;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;
import software.amazon.awscdk.services.lambda.Code;

import java.util.Map;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define a new VPC
        // ...

        // Define an RDS database cluster
        // ...

        // Get the port token (this is a token encoded as a number)
        Number portToken = dbCluster.getClusterEndpoint().getPort();

        // ...

        // Example connection string with the port token as a number
        String connectionString = "jdbc:mysql://mydb.cluster.amazonaws.com:" + portToken + "/mydatabase";

        // Use the connection string as an environment variable in a Lambda function
        Function myFunction = Function.Builder.create(this, "MyLambdaFunction")
            .runtime(Runtime.NODEJS_20_X)
            .handler("index.handler")
            .code(Code.fromInline(
                "exports.handler = async function(event) {\n" +
                "  return {\n" +
                "    statusCode: 200,\n" +
                "    body: JSON.stringify('Hello World!'),\n" +
                "  };\n" +
                "};"))
            .environment(Map.of(
                "DATABASE_CONNECTION_STRING", connectionString // Using the port token as part of the string
            ))
            .build();

        // Output the value of our connection string at synthesis
        System.out.println("connectionString: " + connectionString);

        // Output the connection string
        CfnOutput.Builder.create(this, "ConnectionString")
            .value(connectionString)
            .build();
    }
}
```

```
// ...
using Amazon.CDK.AWS.Lambda;
using Amazon.CDK.AWS.RDS;
using Amazon.CDK;
using Constructs;
using System;
using System.Collections.Generic;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define a new VPC
            // ...

            // Define an RDS database cluster
            var dbCluster = new DatabaseCluster(this, "MyRDSCluster", new DatabaseClusterProps
            {
                // ... properties would go here
            });

            // Get the port token (this is a token encoded as a number)
            var portToken = dbCluster.ClusterEndpoint.Port;

            // ...

            // Example connection string with the port token as a number
            var connectionString = $"jdbc:mysql://mydb.cluster.amazonaws.com:{portToken}/mydatabase";

            // Use the connection string as an environment variable in a Lambda function
            var myFunction = new Function(this, "MyLambdaFunction", new FunctionProps
            {
                Runtime = Runtime.NODEJS_20_X,
                Handler = "index.handler",
                Code = Code.FromInline(@"
                    exports.handler = async function(event) {
                        return {
                            statusCode: 200,
                            body: JSON.stringify('Hello World!'),
                        };
                    };
                "),
                Environment = new Dictionary<string, string>
                {
                    { "DATABASE_CONNECTION_STRING", connectionString }  // Using the port token as part of the string
                }
            });

            // Output the value of our connection string at synthesis
            Console.WriteLine($"connectionString: {connectionString}");

            // Output the connection string
            new CfnOutput(this, "ConnectionString", new CfnOutputProps
            {
                Value = connectionString
            });
        }
    }
}
```

```
// ...
	"github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
)

type CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define a new VPC
	// ...

	// Define an RDS database cluster
	// ...

	// Get the port token (this is a token encoded as a number)
	portToken := dbCluster.ClusterEndpoint().Port()

	// ...

	// Example connection string with the port token as a number
	 connectionString := fmt.Sprintf("jdbc:mysql://mydb.cluster.amazonaws.com:%s/mydatabase", portToken)

	// Use the connection string as an environment variable in a Lambda function
	myFunction := awslambda.NewFunction(stack, jsii.String("MyLambdaFunction"), &awslambda.FunctionProps{
		Runtime: awslambda.Runtime_NODEJS_20_X(),
		Handler: jsii.String("index.handler"),
		Code: awslambda.Code_FromInline(jsii.String(`
			exports.handler = async function(event) {
				return {
					statusCode: 200,
					body: JSON.stringify('Hello World!'),
				};
			};
		`)),
		Environment: &map[string]*string{
			"DATABASE_CONNECTION_STRING": jsii.String(connectionString), // Using the port token as part of the string
		},
	})

	// Output the value of our connection string at synthesis
	fmt.Println("connectionString: ", connectionString)

	// Output the connection string
	awscdk.NewCfnOutput(stack, jsii.String("ConnectionString"), &awscdk.CfnOutputProps{
		Value: jsii.String(connectionString),
	})

	return stack
}

// ...
```

この値を `connectionString` に渡す場合、数値エンコードされた文字列により、`cdk synth` の実行時の出力値が混乱を招く場合があります。

```
$ cdk synth --quiet
connectionString: jdbc:mysql://mydb.cluster.amazonaws.com:-1.888154589708796e+289/mydatabase
```

数値エンコードされたトークンを文字列に変換するには、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tokenization.html#static-stringifywbrnumberx](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tokenization.html#static-stringifywbrnumberx) を使用します。次の例では、接続文字列を定義する前に、数値エンコードされたトークンを文字列に変換します。

**Example**  

```
import { Stack, Duration, Tokenization, CfnOutput, StackProps } from 'aws-cdk-lib';
// ...

export class CdkDemoAppStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // Define a new VPC
    // ...

    // Define an RDS database cluster
    // ...

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // ...

    // Convert the encoded number to an encoded string for use in the connection string
    const portAsString = Tokenization.stringifyNumber(portToken);

    // Example connection string with the port token as a string
    const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portAsString}/mydatabase`;

    // Use the connection string as an environment variable in a Lambda function
    const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
      // ...
      environment: {
        DATABASE_CONNECTION_STRING: connectionString,  // Using the port token as part of the string
      },
    });

    // Output the value of our connection string at synthesis
    console.log("connectionString: " + connectionString);

    // Output the connection string
    new CfnOutput(this, 'ConnectionString', {
      value: connectionString,
    });
  }
}
```

```
const { Stack, Duration, Tokenization, CfnOutput } = require('aws-cdk-lib');
// ...

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define a new VPC
    // ...

    // Define an RDS database cluster
    // ...

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // ...

    // Convert the encoded number to an encoded string for use in the connection string
    const portAsString = Tokenization.stringifyNumber(portToken);

    // Example connection string with the port token as a string
    const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portAsString}/mydatabase`;

    // Use the connection string as an environment variable in a Lambda function
    const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
      // ...
      environment: {
        DATABASE_CONNECTION_STRING: connectionString,  // Using the port token as part of the string
      },
    });

    // Output the value of our connection string at synthesis
    console.log("connectionString: " + connectionString);

    // Output the connection string
    new CfnOutput(this, 'ConnectionString', {
      value: connectionString,
    });
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Duration,
    Stack,
    Tokenization,
    CfnOutput,
)
# ...

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define a new VPC
        # ...

        # Define an RDS database cluster
        # ...

        # Get the port token (this is a token encoded as a number)
        port_token = db_cluster.cluster_endpoint.port

        # Convert the encoded number to an encoded string for use in the connection string
        port_as_string = Tokenization.stringify_number(port_token)

        # Example connection string with the port token as a string
        connection_string = f"jdbc:mysql://mydb.cluster.amazonaws.com:{port_as_string}/mydatabase"

        # Use the connection string as an environment variable in a Lambda function
        my_function = _lambda.Function(self, 'MyLambdaFunction',
            # ...
            environment={
                'DATABASE_CONNECTION_STRING': connection_string  # Using the port token as part of the string
            }
        )

        # Output the value of our connection string at synthesis
        print(f"connectionString: {connection_string}")

        # Output the connection string
        CfnOutput(self, 'ConnectionString',
            value=connection_string
        )
```

```
// ...
import software.amazon.awscdk.Tokenization;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define a new VPC
        // ...

        // Define an RDS database cluster
        // ...

        // Get the port token (this is a token encoded as a number)
        Number portToken = dbCluster.getClusterEndpoint().getPort();

        // ...

        // Convert the encoded number to an encoded string for use in the connection string
        String portAsString = Tokenization.stringifyNumber(portToken);

        // Example connection string with the port token as a string
        String connectionString = "jdbc:mysql://mydb.cluster.amazonaws.com:" + portAsString + "/mydatabase";

        // Use the connection string as an environment variable in a Lambda function
        Function myFunction = Function.Builder.create(this, "MyLambdaFunction")
            // ...
            .environment(Map.of(
                "DATABASE_CONNECTION_STRING", connectionString // Using the port token as part of the string
            ))
            .build();

        // Output the value of our connection string at synthesis
        System.out.println("connectionString: " + connectionString);

        // Output the connection string
        CfnOutput.Builder.create(this, "ConnectionString")
            .value(connectionString)
            .build();
    }
}
```

```
// ...

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define a new VPC
            // ...

            // Define an RDS database cluster
            // ...

            // Get the port token (this is a token encoded as a number)
            var portToken = dbCluster.ClusterEndpoint.Port;

            // ...

            // Convert the encoded number to an encoded string for use in the connection string
            var portAsString = Tokenization.StringifyNumber(portToken);

            // Example connection string with the port token as a string
            var connectionString = $"jdbc:mysql://mydb.cluster.amazonaws.com:{portAsString}/mydatabase";

            // Use the connection string as an environment variable in a Lambda function
            var myFunction = new Function(this, "MyLambdaFunction", new FunctionProps
            {
                // ...
                Environment = new Dictionary<string, string>
                {
                    { "DATABASE_CONNECTION_STRING", connectionString }  // Using the port token as part of the string
                }
            });

            // Output the value of our connection string at synthesis
            Console.WriteLine($"connectionString: {connectionString}");

            // Output the connection string
            new CfnOutput(this, "ConnectionString", new CfnOutputProps
            {
                Value = connectionString
            });
        }
    }
}
```

```
// ...

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define a new VPC
	// ...

	// Define an RDS database cluster
	// ...

	// Get the port token (this is a token encoded as a number)
	portToken := dbCluster.ClusterEndpoint().Port()

	// ...

	// Convert the encoded number to an encoded string for use in the connection string
	portAsString := awscdk.Tokenization_StringifyNumber(portToken)

	// Example connection string with the port token as a string
	connectionString := fmt.Sprintf("jdbc:mysql://mydb.cluster.amazonaws.com:%s/mydatabase", portAsString)

	// Use the connection string as an environment variable in a Lambda function
	myFunction := awslambda.NewFunction(stack, jsii.String("MyLambdaFunction"), &awslambda.FunctionProps{
		// ...
		Environment: &map[string]*string{
			"DATABASE_CONNECTION_STRING": jsii.String(connectionString), // Using the port token as part of the string
		},
	})

	// Output the value of our connection string at synthesis
	fmt.Println("connectionString: ", connectionString)

	// Output the connection string
	awscdk.NewCfnOutput(stack, jsii.String("ConnectionString"), &awscdk.CfnOutputProps{
		Value: jsii.String(connectionString),
	})

	fmt.Println(myFunction)

	return stack
}

// ...
```

`cdk synth` を実行するとき、接続文字列の値はより簡潔で明確な形式で表されます。

```
$ cdk synth --quiet
connectionString: jdbc:mysql://mydb.cluster.amazonaws.com:${Token[TOKEN.242]}/mydatabase
```

## 遅延値
<a name="tokens-lazy"></a>

AWS CloudFormation [パラメータ](parameters.md)などのデプロイ時間値を表すだけではなく、トークンは合成時間の遅延値を表すためにも一般的に使用されます。合成が完了する前に最終値が決定される値ですが、値が構築された時点では決定されません。トークンを使用してリテラル文字列または数値を別のコンストラクトに渡しますが、合成時の実際の値はまだ発生していない計算に依存する場合があります。

[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Lazy.html#static-stringproducer-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Lazy.html#static-stringproducer-options) や [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Lazy.html#static-numberproducer](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Lazy.html#static-numberproducer) などの `Lazy` クラスの静的メソッドを使用して、合成時間の遅延値を表すトークンを構成できます。これらのメソッドは、`produce` プロパティがコンテキスト引数を受け入れる関数であるオブジェクトを受け入れ、呼び出されたときに最終値を返します。

次の例では Auto Scaling グループを作成し、作成後に容量が決定されます。

**Example**  

```
let actualValue: number;

new AutoScalingGroup(this, 'Group', {
  desiredCapacity: Lazy.numberValue({
    produce(context) {
      return actualValue;
    }
  })
});

// At some later point
actualValue = 10;
```

```
let actualValue;

new AutoScalingGroup(this, 'Group', {
  desiredCapacity: Lazy.numberValue({
    produce(context) {
      return (actualValue);
    }
  })
});

// At some later point
actualValue = 10;
```

```
class Producer:
    def __init__(self, func):
        self.produce = func

actual_value = None

AutoScalingGroup(self, "Group",
    desired_capacity=Lazy.number_value(Producer(lambda context: actual_value))
)

# At some later point
actual_value = 10
```

```
double actualValue = 0;

class ProduceActualValue implements INumberProducer {

    @Override
    public Number produce(IResolveContext context) {
        return actualValue;
    }
}

AutoScalingGroup.Builder.create(this, "Group")
    .desiredCapacity(Lazy.numberValue(new ProduceActualValue())).build();

// At some later point
actualValue = 10;
```

```
public class NumberProducer : INumberProducer
{
    Func<Double> function;

    public NumberProducer(Func<Double> function)
    {
        this.function = function;
    }

    public Double Produce(IResolveContext context)
    {
        return function();
    }
}

double actualValue = 0;

new AutoScalingGroup(this, "Group", new AutoScalingGroupProps
{
    DesiredCapacity = Lazy.NumberValue(new NumberProducer(() => actualValue))
});

// At some later point
actualValue = 10;
```

## JSON への変換
<a name="tokens-json"></a>

任意のデータの JSON 文字列を生成し、データにトークンが含まれているかどうかわからない場合があります。次の例で示すように、トークンが含まれているかどうかを問わず、データ構造を適切に JSON エンコードするには、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#towbrjsonwbrstringobj-space](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#towbrjsonwbrstringobj-space) メソッドを使用します。

**Example**  

```
const stack = Stack.of(this);
const str = stack.toJsonString({
  value: bucket.bucketName
});
```

```
const stack = Stack.of(this);
const str = stack.toJsonString({
  value: bucket.bucketName
});
```

```
stack = Stack.of(self)
string = stack.to_json_string(dict(value=bucket.bucket_name))
```

```
Stack stack = Stack.of(this);
String stringVal = stack.toJsonString(java.util.Map.of(    // Map.of requires Java 9+
        put("value", bucket.getBucketName())));
```

```
var stack = Stack.Of(this);
var stringVal = stack.ToJsonString(new Dictionary<string, string>
{
    ["value"] = bucket.BucketName
});
```

# パラメータと AWS CDK
<a name="parameters"></a>

 *パラメータ*はデプロイ時に提供されるカスタム値です。[パラメータ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html)は AWS CloudFormation の機能です。AWS Cloud Development Kit (AWS CDK) は AWS CloudFormation テンプレートを合成するため、デプロイ時間パラメータもサポートします。

## パラメータについて
<a name="parameters-about"></a>

AWS CDK を使用してパラメータを定義したら、作成したコンストラクトのプロパティで使用できます。パラメータを含むスタックをデプロイすることもできます。

AWS CDK CLI を使用して AWS CloudFormation テンプレートをデプロイするとき、コマンドラインにパラメータ値を指定します。AWS CloudFormation コンソールを介してテンプレートをデプロイする場合、パラメータ値の入力を求められます。

一般的に、AWS CDK で AWS CloudFormation パラメータを使用しないことをお勧めします。AWS CDK アプリに値を渡す通常の方法は、[コンテキスト値](context.md)および環境変数です。合成時に利用できないため、CDK アプリでフロー制御やその他の目的にパラメータ値を簡単に使用することはできません。

**注記**  
パラメータを使用してフローを制御するには、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.CfnCondition.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.CfnCondition.html) コンストラクトを使用できますが、ネイティブ `if` ステートメントと比較してこれは厄介です。

パラメータを使用すると、記述するコードがデプロイ時および合成時にどのように動作するか注意する必要があります。多くの場合、AWS CDK アプリケーションに対する理解や理由の説明が難しくなりますが、得られる利点はほとんどありません。

一般的に、CDK アプリが必要な情報を明確に定義された方法で受け入れ、CDK アプリのコンストラクトを宣言するために直接使用することをお勧めします。理想的に AWS CDK で生成された AWS CloudFormation テンプレートは具体的であり、デプロイ時に指定する値は残りません。

ただし、AWS CloudFormation パラメータが一意に適しているユースケースがあります。例えば、インフラストラクチャを定義してデプロイする別のチームがある場合、パラメータを使用して生成されたテンプレートをより広範囲に約立つようにすることができます。また、AWS CDK は AWS CloudFormation パラメータをサポートしているため、AWS CloudFormation テンプレート (サービスカタログなど) を使用する AWS のサービスで AWS CDK を使用できます。これらの AWS のサービスは、パラメータを使用してデプロイされているテンプレートを設定します。

## 詳細
<a name="parameters-learn"></a>

パラメータを使用して CDK アプリを開発する手順については、「[CloudFormation パラメータを使用して CloudFormation 値を取得する](get-cfn-param.md)」を参照してください。

# タグと AWS CDK
<a name="tagging"></a>

タグは、AWS CDK アプリのコンストラクトに追加できる情報を含んだキーと値の要素です。特定のコンストラクトに適用されるタグは、タグ付け可能なすべての子にも適用されます。タグは、アプリから合成された AWS CloudFormation テンプレートに含まれ、デプロイされる AWS リソースに適用されます。タグを使用し、次の用途でリソースを識別および分類できます。
+ 管理の簡素化
+ コスト配分
+ アクセスコントロール
+ 考案したその他の用途

**ヒント**  
AWS リソースでタグを使用する方法の詳細については、「*AWS ホワイトペーパー*」の「[AWS リソースのタグ付けのベストプラクティス](https://docs.aws.amazon.com/whitepapers/latest/tagging-best-practices/tagging-best-practices.html)」を参照してください。

## タグの使用
<a name="tagging-use"></a>

[タグ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html)クラスには静的メソッドの `of()` が含まれており、これを使用して指定されたコンストラクトにタグを追加したり、タグを削除したりすることができます。
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html#addkey-value-props](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html#addkey-value-props) は、指定されたコンストラクトおよびそのすべての子に新しいタグを適用します。
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html#removekey-props](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html#removekey-props) は、子コンストラクトがそれ自体に適用したタグなど、特定のコンストラクトおよびその子からタグを削除します。

**注記**  
タグ付けは、[アスペクトと AWS CDK を使用して実装されます](aspects.md)。アスペクトは、特定のスコープのすべてのコンストラクトにオペレーション (タグ付けなど) を適用する方法です。

次の例では、**値**を持つタグ**キー**をコンストラクトに適用します。

**Example**  

```
Tags.of(myConstruct).add('key', 'value');
```

```
Tags.of(myConstruct).add('key', 'value');
```

```
Tags.of(my_construct).add("key", "value")
```

```
Tags.of(myConstruct).add("key", "value");
```

```
Tags.Of(myConstruct).Add("key", "value");
```

```
awscdk.Tags_Of(myConstruct).Add(jsii.String("key"), jsii.String("value"), &awscdk.TagProps{})
```

次の例では、コンストラクトからタグ**キー**を削除します。

**Example**  

```
Tags.of(myConstruct).remove('key');
```

```
Tags.of(myConstruct).remove('key');
```

```
Tags.of(my_construct).remove("key")
```

```
Tags.of(myConstruct).remove("key");
```

```
Tags.Of(myConstruct).Remove("key");
```

```
awscdk.Tags_Of(myConstruct).Remove(jsii.String("key"), &awscdk.TagProps{})
```

`Stage` コンストラクトを使用している場合、タグを `Stage` レベル以下で適用します。タグは `Stage` 境界を越えて適用されません。

## タグの優先順位
<a name="tagging-priorities"></a>

AWS CDK はタグを再帰的に適用および削除します。競合がある場合、優先順位が最も高いタグ付けオペレーションが優先されます。(優先順位はオプションの `priority` プロパティを使用して設定されます) 2 つのオペレーションの優先順位が同じである場合、コンストラクトツリーの下部に最も近いタグ付けオペレーションが優先されます。デフォルトでは、タグ適用の優先順位は 100 です (優先順位が 50 の AWS CloudFormation リソースに直接追加されたタグを除く)。タグ削除のデフォルトの優先順位は 200 です。

次の内容は、優先順位が 300 のタグをコンストラクトに適用します。

**Example**  

```
Tags.of(myConstruct).add('key', 'value', {
  priority: 300
});
```

```
Tags.of(myConstruct).add('key', 'value', {
  priority: 300
});
```

```
Tags.of(my_construct).add("key", "value", priority=300)
```

```
Tags.of(myConstruct).add("key", "value", TagProps.builder()
        .priority(300).build());
```

```
Tags.Of(myConstruct).Add("key", "value", new TagProps { Priority = 300 });
```

```
awscdk.Tags_Of(myConstruct).Add(jsii.String("key"), jsii.String("value"), &awscdk.TagProps{
  Priority: jsii.Number(300),
})
```

## オプションプロパティ
<a name="tagging-props"></a>

タグは、リソースへのタグの適用方法、あるいはリソースからのタグの削除方法を微調整する [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.TagProps.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.TagProps.html) をサポートします。すべてのプロパティはオプションです。

 `applyToLaunchedInstances`/ (Python:`apply_to_launched_instances` /)  
add() にのみ利用できます。デフォルトでは、タグは Auto Scaling グループで起動されたインスタンスに適用されます。このプロパティを **false** に設定し、Auto Scaling グループで起動されたインスタンスを無視します。

 `includeResourceTypes`/`excludeResourceTypes` (Python: `include_resource_types`/`exclude_resource_types`)  
AWS CloudFormation リソースタイプに基づき、これらを使用してリソースのサブセットにのみタグを操作します。デフォルトでは、オペレーションはコンストラクトサブツリーのすべてのリソースに適用されますが、特定のリソースタイプを含めるか除外するかによって変更できます。exclude および include の両方が指定された場合、exclude が優先されます。

 `priority`   
これを使用し、他の `Tags.add()` および `Tags.remove()` オペレーションに関するこのオペレーションの優先順位を設定します。大きい値は小さい値よりも優先されます。デフォルトは、追加オペレーションの場合は 100 (AWS CloudFormation リソースに直接適用されるタグの場合は 50)、削除オペレーションの場合は 200 です。

次の例では、コンストラクトの **AWS::Xxx::Yyy** タイプのリソースに、値が **value** で優先度が **100** のタグ **tagname** を適用します。Amazon EC2 Auto Scaling グループで起動されたインスタンスや、**AWS::Xxx::Zzz** 型のリソースにはタグを適用しません。(これらは 2 つの任意で異なる AWS CloudFormation リソースタイプのプレースホルダーです)

**Example**  

```
Tags.of(myConstruct).add('tagname', 'value', {
  applyToLaunchedInstances: false,
  includeResourceTypes: ['AWS::Xxx::Yyy'],
  excludeResourceTypes: ['AWS::Xxx::Zzz'],
  priority: 100,
});
```

```
Tags.of(myConstruct).add('tagname', 'value', {
  applyToLaunchedInstances: false,
  includeResourceTypes: ['AWS::Xxx::Yyy'],
  excludeResourceTypes: ['AWS::Xxx::Zzz'],
  priority: 100
});
```

```
Tags.of(my_construct).add("tagname", "value",
    apply_to_launched_instances=False,
    include_resource_types=["AWS::Xxx::Yyy"],
    exclude_resource_types=["AWS::Xxx::Zzz"],
    priority=100)
```

```
Tags.of(myConstruct).add("tagname", "value", TagProps.builder()
                .applyToLaunchedInstances(false)
                .includeResourceTypes(Arrays.asList("AWS::Xxx::Yyy"))
                .excludeResourceTypes(Arrays.asList("AWS::Xxx::Zzz"))
                .priority(100).build());
```

```
Tags.Of(myConstruct).Add("tagname", "value", new TagProps
{
    ApplyToLaunchedInstances = false,
    IncludeResourceTypes = ["AWS::Xxx::Yyy"],
    ExcludeResourceTypes = ["AWS::Xxx::Zzz"],
    Priority = 100
});
```

```
awscdk.Tags_Of(myConstruct).Add(jsii.String("tagname"), jsii.String("value"), &awscdk.TagProps{
  ApplyToLaunchedInstances: jsii.Bool(false),
  IncludeResourceTypes:     &[]*string{jsii.String("AWS::Xxx:Yyy")},
  ExcludeResourceTypes:     &[]*string{jsii.String("AWS::Xxx:Zzz")},
  Priority:                 jsii.Number(100),
})
```

次の例では、優先度 **200** のタグ **tagname** をコンストラクトの **AWS::Xxx::Yyy** 型のリソースから削除しますが、**AWS::Xxx::Zzz** 型のリソースからは削除しません。

**Example**  

```
Tags.of(myConstruct).remove('tagname', {
  includeResourceTypes: ['AWS::Xxx::Yyy'],
  excludeResourceTypes: ['AWS::Xxx::Zzz'],
  priority: 200,
});
```

```
Tags.of(myConstruct).remove('tagname', {
  includeResourceTypes: ['AWS::Xxx::Yyy'],
  excludeResourceTypes: ['AWS::Xxx::Zzz'],
  priority: 200
});
```

```
Tags.of(my_construct).remove("tagname",
    include_resource_types=["AWS::Xxx::Yyy"],
    exclude_resource_types=["AWS::Xxx::Zzz"],
    priority=200,)
```

```
Tags.of((myConstruct).remove("tagname", TagProps.builder()
        .includeResourceTypes(Arrays.asList("AWS::Xxx::Yyy"))
        .excludeResourceTypes(Arrays.asList("AWS::Xxx::Zzz"))
        .priority(100).build());
        )
```

```
Tags.Of(myConstruct).Remove("tagname", new TagProps
{
    IncludeResourceTypes = ["AWS::Xxx::Yyy"],
    ExcludeResourceTypes = ["AWS::Xxx::Zzz"],
    Priority = 100
});
```

```
awscdk.Tags_Of(myConstruct).Remove(jsii.String("tagname"), &awscdk.TagProps{
  IncludeResourceTypes: &[]*string{jsii.String("AWS::Xxx:Yyy")},
  ExcludeResourceTypes: &[]*string{jsii.String("AWS::Xxx:Zzz")},
  Priority:             jsii.Number(200),
})
```

## 例
<a name="tagging-example"></a>

次の例では、`MarketingSystem` という名前で `Stack` 内に作成されたすべてのリソースに、**TheBest** の値をもつ **StackType** のタグキーを追加します。次に、Amazon EC2 VPC サブネットを除くすべてのリソースから再度削除します。その結果、サブネットのみにタグが適用されます。

**Example**  

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

const app = new App();
const theBestStack = new Stack(app, 'MarketingSystem');

// Add a tag to all constructs in the stack
Tags.of(theBestStack).add('StackType', 'TheBest');

// Remove the tag from all resources except subnet resources
Tags.of(theBestStack).remove('StackType', {
  excludeResourceTypes: ['AWS::EC2::Subnet']
});
```

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

const app = new App();
const theBestStack = new Stack(app, 'MarketingSystem');

// Add a tag to all constructs in the stack
Tags.of(theBestStack).add('StackType', 'TheBest');

// Remove the tag from all resources except subnet resources
Tags.of(theBestStack).remove('StackType', {
  excludeResourceTypes: ['AWS::EC2::Subnet']
});
```

```
from aws_cdk import App, Stack, Tags

app = App();
the_best_stack = Stack(app, 'MarketingSystem')

# Add a tag to all constructs in the stack
Tags.of(the_best_stack).add("StackType", "TheBest")

# Remove the tag from all resources except subnet resources
Tags.of(the_best_stack).remove("StackType",
    exclude_resource_types=["AWS::EC2::Subnet"])
```

```
import software.amazon.awscdk.App;
import software.amazon.awscdk.Tags;

// Add a tag to all constructs in the stack
Tags.of(theBestStack).add("StackType", "TheBest");

// Remove the tag from all resources except subnet resources
Tags.of(theBestStack).remove("StackType", TagProps.builder()
        .excludeResourceTypes(Arrays.asList("AWS::EC2::Subnet"))
        .build());
```

```
using Amazon.CDK;

var app = new App();
var theBestStack = new Stack(app, 'MarketingSystem');

// Add a tag to all constructs in the stack
Tags.Of(theBestStack).Add("StackType", "TheBest");

// Remove the tag from all resources except subnet resources
Tags.Of(theBestStack).Remove("StackType", new TagProps
{
    ExcludeResourceTypes = ["AWS::EC2::Subnet"]
});
```

```
import "github.com/aws/aws-cdk-go/awscdk/v2"
app := awscdk.NewApp(nil)
theBestStack := awscdk.NewStack(app, jsii.String("MarketingSystem"), &awscdk.StackProps{})

// Add a tag to all constructs in the stack
awscdk.Tags_Of(theBestStack).Add(jsii.String("StackType"), jsii.String("TheBest"), &awscdk.TagProps{})

// Remove the tag from all resources except subnet resources
awscdk.Tags_Of(theBestStack).Add(jsii.String("StackType"), jsii.String("TheBest"), &awscdk.TagProps{
  ExcludeResourceTypes: &[]*string{jsii.String("AWS::EC2::Subnet")},
})
```

次のコードは同じ結果を出します。どのアプローチ (包含または除外) が意図をより明確にするか検討します。

**Example**  

```
Tags.of(theBestStack).add('StackType', 'TheBest',
  { includeResourceTypes: ['AWS::EC2::Subnet']});
```

```
Tags.of(theBestStack).add('StackType', 'TheBest',
  { includeResourceTypes: ['AWS::EC2::Subnet']});
```

```
Tags.of(the_best_stack).add("StackType", "TheBest",
    include_resource_types=["AWS::EC2::Subnet"])
```

```
Tags.of(theBestStack).add("StackType", "TheBest", TagProps.builder()
        .includeResourceTypes(Arrays.asList("AWS::EC2::Subnet"))
        .build());
```

```
Tags.Of(theBestStack).Add("StackType", "TheBest", new TagProps {
    IncludeResourceTypes = ["AWS::EC2::Subnet"]
});
```

```
awscdk.Tags_Of(theBestStack).Add(jsii.String("StackType"), jsii.String("TheBest"), &awscdk.TagProps{
  IncludeResourceTypes: &[]*string{jsii.String("AWS::EC2::Subnet")},
})
```

## 1 つのコンストラクトのタグ付け
<a name="tagging-single"></a>

 `Tags.of(scope).add(key, value)` は、AWS CDK のコンストラクトにタグを追加する標準的な方法です。そのツリーウォーキング動作は、特定のスコープですべてのタグ付け可能なリソースを再帰的にタグ付けし、ほぼ常に必要な動作です。ただし、特定の任意のコンストラクト (または複数のコンストラクト) にタグ付けが必要な場合があります。

このようなケースの 1 つには、タグ付けされるコンストラクトの一部のプロパティから値が導出されるタグが適用されます。標準のタグ付けアプローチは、スコープのすべての一致するリソースに同じキーおよび値を再帰的に適用します。ただし、こちらではタグ付けされたコンストラクトごとに値が異なる場合があります。

タグは[アスペクト](aspects.md)を使用して実装され、CDK は `Tags.of(scope)` を使用して指定したスコープで各コンストラクトにタグの `visit()` メソッドを呼び出します。`Tag.visit()` を直接を呼び出し、タグを 1 つのコンストラクトに適用できます。

**Example**  

```
new cdk.Tag(key, value).visit(scope);
```

```
new cdk.Tag(key, value).visit(scope);
```

```
cdk.Tag(key, value).visit(scope)
```

```
Tag.Builder.create(key, value).build().visit(scope);
```

```
new Tag(key, value).Visit(scope);
```

```
awscdk.NewTag(key, value, &awscdk.TagProps{}).Visit(scope)
```

スコープのすべてのコンストラクトにタグ付けすることはできますが、タグの値が各コンストラクトのプロパティから導出させます。これを行うには、前の例で示すように、アスペクトを記述してアスペクトの `visit()` メソッドにタグを適用します。次に、`Aspects.of(scope).add(aspect)` を使用して目的のスコープにアスペクトを追加します。

次の例では、リソースのパスを含むスタックの各リソースにタグを適用します。

**Example**  

```
class PathTagger implements cdk.IAspect {
  visit(node: IConstruct) {
    new cdk.Tag("aws-cdk-path", node.node.path).visit(node);
  }
}

stack = new MyStack(app);
cdk.Aspects.of(stack).add(new PathTagger())
```

```
class PathTagger {
  visit(node) {
    new cdk.Tag("aws-cdk-path", node.node.path).visit(node);
  }
}

stack = new MyStack(app);
cdk.Aspects.of(stack).add(new PathTagger())
```

```
@jsii.implements(cdk.IAspect)
class PathTagger:
    def visit(self, node: IConstruct):
        cdk.Tag("aws-cdk-path", node.node.path).visit(node)

stack = MyStack(app)
cdk.Aspects.of(stack).add(PathTagger())
```

```
final class PathTagger implements IAspect {
	public void visit(IConstruct node) {
		Tag.Builder.create("aws-cdk-path", node.getNode().getPath()).build().visit(node);
	}
}

stack stack = new MyStack(app);
Aspects.of(stack).add(new PathTagger());
```

```
public class PathTagger : IAspect
{
    public void Visit(IConstruct node)
    {
        new Tag("aws-cdk-path", node.Node.Path).Visit(node);
    }
}

var stack = new MyStack(app);
Aspects.Of(stack).Add(new PathTagger);
```

**ヒント**  
優先順位やリソースタイプなど、条件付きタグ付けのロジックは `Tag` クラスに組み込まれています。これらの機能は、任意のリソースにタグを適用するときに使用できます。条件が満たされない場合、タグは適用されません。また、`Tag` クラスはタグ付け可能なリソースのみをタグ付けするため、タグを適用する前にコンストラクトがタグ付け可能であるかどうかをテストする必要はありません。

# アセットと AWS CDK
<a name="assets"></a>

アセットは、 AWS CDK ライブラリとアプリケーションにバンドルできるローカルファイル、ディレクトリ、または Docker イメージです。たとえば、アセットは Lambda AWS 関数のハンドラーコードを含むディレクトリである場合があります。アセットは、アプリが動作するために必要なアーティファクトを表すことができます。

以下のチュートリアルビデオでは、CDK アセットの包括的な概要と、Infrastructure as Code (IaC) でそれらを使用する方法について説明します。

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/jHNtXQmkKfw?rel=0/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/jHNtXQmkKfw?rel=0)


アセットは、特定の AWS コンストラクトによって公開される APIs を通じて追加します。例えば、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html) コンストラクトを定義すると、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html#code](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html#code) プロパティによって [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Code.html#static-fromwbrassetpath-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Code.html#static-fromwbrassetpath-options) (ディレクトリ) を渡すことができます。`Function` はアセットを使用してディレクトリの内容をバンドルし、関数のコードに使用します。同様に、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.ContainerImage.html#static-fromwbrassetdirectory-props](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.ContainerImage.html#static-fromwbrassetdirectory-props) は、Amazon ECS タスク定義を定義するときに、ローカルディレクトリから構築された Docker イメージを使用します。

## アセットの詳細
<a name="assets-details"></a>

アプリでアセットを参照すると、アプリケーションから合成される[クラウドアセンブリ](deploy.md#deploy-how-synth-assemblies)には、 AWS CDK CLI の手順を含むメタデータ情報が含まれます。手順には、ローカルディスク上のアセットの場所と、アセットタイプに基づいて実行するバンドルのタイプが含まれます。たとえば、圧縮するディレクトリ (zip) や構築する Docker イメージなどです。

 AWS CDK はアセットのソースハッシュを生成します。これは構築時に、アセットの内容が変更されたかどうかを判断するために使用できます。

デフォルトでは、 AWS CDK はクラウドアセンブリディレクトリにアセットのコピーを作成します。このディレクトリのデフォルトは`cdk.out`、ソースハッシュの です。これにより、クラウドアセンブリは自己完結型であるため、デプロイのために別のホストに移動してもデプロイできます。詳細については、「[クラウドアセンブリ](deploy.md#deploy-how-synth-assemblies)」を参照してください。

 AWS CDK がアセットを参照するアプリを (アプリケーションコードから直接、またはライブラリを介して) デプロイすると、 AWS CDK CLI はまずアセットを準備し、Amazon S3 バケットまたは Amazon ECR リポジトリに公開します。(S3 バケットまたはリポジトリはブートストラップ中に作成されます)。その後のみ、スタックで定義されたリソースがデプロイされます。

このセクションでは、 フレームワークで使用できる低レベル APIs について説明します。

## アセットタイプ
<a name="assets-types"></a>

 AWS CDK は、次のタイプのアセットをサポートしています。

Amazon S3 アセット  
これらは、 AWS CDK が Amazon S3 にアップロードするローカルファイルとディレクトリです。

Docker イメージ  
これらは、 AWS CDK が Amazon ECR にアップロードする Docker イメージです。

これらのロールについては、以降のセクションで説明します。

## Amazon S3 アセット
<a name="assets-types-s3"></a>

ローカルファイルとディレクトリをアセットとして定義し、 AWS CDK でパッケージ化して、 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets-readme.html)モジュールを介して Amazon S3 にアップロードできます。

以下の例では、ローカルディレクトリアセットとファイルアセットを定義します。

**Example**  

```
import { Asset } from 'aws-cdk-lib/aws-s3-assets';

// Archived and uploaded to Amazon S3 as a .zip file
const directoryAsset = new Asset(this, "SampleZippedDirAsset", {
  path: path.join(__dirname, "sample-asset-directory")
});

// Uploaded to Amazon S3 as-is
const fileAsset = new Asset(this, 'SampleSingleFileAsset', {
  path: path.join(__dirname, 'file-asset.txt')
});
```

```
const { Asset } = require('aws-cdk-lib/aws-s3-assets');

// Archived and uploaded to Amazon S3 as a .zip file
const directoryAsset = new Asset(this, "SampleZippedDirAsset", {
  path: path.join(__dirname, "sample-asset-directory")
});

// Uploaded to Amazon S3 as-is
const fileAsset = new Asset(this, 'SampleSingleFileAsset', {
  path: path.join(__dirname, 'file-asset.txt')
});
```

```
import os.path
dirname = os.path.dirname(__file__)

from aws_cdk.aws_s3_assets import Asset

# Archived and uploaded to Amazon S3 as a .zip file
directory_asset = Asset(self, "SampleZippedDirAsset",
  path=os.path.join(dirname, "sample-asset-directory")
)

# Uploaded to Amazon S3 as-is
file_asset = Asset(self, 'SampleSingleFileAsset',
  path=os.path.join(dirname, 'file-asset.txt')
)
```

```
import java.io.File;

import software.amazon.awscdk.services.s3.assets.Asset;

// Directory where app was started
File startDir = new File(System.getProperty("user.dir"));

// Archived and uploaded to Amazon S3 as a .zip file
Asset directoryAsset = Asset.Builder.create(this, "SampleZippedDirAsset")
                .path(new File(startDir, "sample-asset-directory").toString()).build();

// Uploaded to Amazon S3 as-is
Asset fileAsset = Asset.Builder.create(this, "SampleSingleFileAsset")
                .path(new File(startDir, "file-asset.txt").toString()).build();
```

```
using System.IO;
using Amazon.CDK.AWS.S3.Assets;

// Archived and uploaded to Amazon S3 as a .zip file
var directoryAsset = new Asset(this, "SampleZippedDirAsset", new AssetProps
{
    Path = Path.Combine(Directory.GetCurrentDirectory(), "sample-asset-directory")
});

// Uploaded to Amazon S3 as-is
var fileAsset = new Asset(this, "SampleSingleFileAsset", new AssetProps
{
    Path = Path.Combine(Directory.GetCurrentDirectory(), "file-asset.txt")
});
```

```
dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

awss3assets.NewAsset(stack, jsii.String("SampleZippedDirAsset"), awss3assets.AssetProps{
  Path: jsii.String(path.Join(dirName, "sample-asset-directory")),
})

awss3assets.NewAsset(stack, jsii.String("SampleSingleFileAsset"), awss3assets.AssetProps{
  Path: jsii.String(path.Join(dirName, "file-asset.txt")),
})
```

ほとんどの場合、`aws-s3-assets` モジュールで API を直接使用する必要はありません。`aws-lambda` などのアセットをサポートするモジュールには、アセットを使用できる便利な方法があります。Lambda 関数の場合、静的メソッド [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Code.html#static-fromwbrassetpath-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Code.html#static-fromwbrassetpath-options) を使用すると、ローカルファイルシステム内のディレクトリまたは .zip ファイルを指定できます。

### Lambda 関数の例
<a name="assets-types-s3-lambda"></a>

一般的なユースケースは、ハンドラーコードを Amazon S3 アセットとして指定した Lambda 関数の作成です。

以下の例では、Amazon S3 アセットを使用して、ローカルディレクトリ `handler` に Python ハンドラーを定義します。また、ローカルディレクトリアセットを `code` プロパティとして Lambda 関数を作成します。ハンドラーの Python コードは以下のとおりです。

```
def lambda_handler(event, context):
  message = 'Hello World!'
  return {
    'message': message
  }
```

メイン AWS CDK アプリのコードは次のようになります。

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import { Constructs } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as path from 'path';

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

    new lambda.Function(this, 'myLambdaFunction', {
      code: lambda.Code.fromAsset(path.join(__dirname, 'handler')),
      runtime: lambda.Runtime.PYTHON_3_6,
      handler: 'index.lambda_handler'
    });
  }
}
```

```
const cdk = require('aws-cdk-lib');
const lambda = require('aws-cdk-lib/aws-lambda');
const path = require('path');

class HelloAssetStack extends cdk.Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    new lambda.Function(this, 'myLambdaFunction', {
      code: lambda.Code.fromAsset(path.join(__dirname, 'handler')),
      runtime: lambda.Runtime.PYTHON_3_6,
      handler: 'index.lambda_handler'
    });
  }
}

module.exports = { HelloAssetStack }
```

```
from aws_cdk import Stack
from constructs import Construct
from aws_cdk import aws_lambda as lambda_

import os.path
dirname = os.path.dirname(__file__)

class HelloAssetStack(Stack):
    def __init__(self, scope: Construct, id: str, **kwargs):
        super().__init__(scope, id, **kwargs)

        lambda_.Function(self, 'myLambdaFunction',
            code=lambda_.Code.from_asset(os.path.join(dirname, 'handler')),
            runtime=lambda_.Runtime.PYTHON_3_6,
            handler="index.lambda_handler")
```

```
import java.io.File;

import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;

public class HelloAssetStack extends Stack {

    public HelloAssetStack(final App scope, final String id) {
        this(scope, id, null);
    }

    public HelloAssetStack(final App scope, final String id, final StackProps props) {
        super(scope, id, props);

        File startDir = new File(System.getProperty("user.dir"));

        Function.Builder.create(this, "myLambdaFunction")
                .code(Code.fromAsset(new File(startDir, "handler").toString()))
                .runtime(Runtime.PYTHON_3_6)
                .handler("index.lambda_handler").build();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.Lambda;
using System.IO;

public class HelloAssetStack : Stack
{
    public HelloAssetStack(Construct scope, string id, StackProps props) : base(scope, id, props)
    {
        new Function(this, "myLambdaFunction", new FunctionProps
        {
            Code = Code.FromAsset(Path.Combine(Directory.GetCurrentDirectory(), "handler")),
            Runtime = Runtime.PYTHON_3_6,
            Handler = "index.lambda_handler"
        });
    }
}
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
  "github.com/aws/aws-cdk-go/awscdk/v2/awss3assets"
  "github.com/aws/constructs-go/constructs/v10"
  "github.com/aws/jsii-runtime-go"
)

func HelloAssetStack(scope constructs.Construct, id string, props *HelloAssetStackProps) awscdk.Stack {
  var sprops awscdk.StackProps
  if props != nil {
    sprops = props.StackProps
  }
  stack := awscdk.NewStack(scope, id, sprops)

  dirName, err := os.Getwd()
  if err != nil {
    panic(err)
  }

  awslambda.NewFunction(stack, jsii.String("myLambdaFunction"), awslambda.FunctionProps{
    Code: awslambda.AssetCode_FromAsset(jsii.String(path.Join(dirName, "handler")), awss3assets.AssetOptions{}),
    Runtime: awslambda.Runtime_PYTHON_3_6(),
    Handler: jsii.String("index.lambda_handler"),
  })

  return stack
}
```

`Function` メソッドはアセットを使用してディレクトリの内容をバンドルし、関数のコードに使用します。

**ヒント**  
Java `.jar` ファイルは、異なる拡張子を持つ ZIP ファイルです。これらはそのまま Amazon S3 にアップロードされますが、Lambda 関数としてデプロイされると、含まれているファイルが抽出されます。これは必要ではない場合があります。これを回避するには、`.jar` ファイルをディレクトリに配置し、そのディレクトリをアセットとして指定します。

### デプロイ時間属性の例
<a name="assets-types-s3-deploy"></a>

Amazon S3 アセットタイプは、 AWS CDK ライブラリとアプリケーションで参照できる[デプロイ時間属性](resources.md#resources-attributes)も公開します。 AWS CDK CLI コマンドは、アセットプロパティを AWS CloudFormation パラメータとして`cdk synth`表示します。

以下の例では、デプロイ時間属性を使用して、イメージアセットの場所を環境変数として Lambda 関数に渡します。(ファイルの種類は関係ありません。ここで使用する PNG イメージは例にすぎません)。

**Example**  

```
import { Asset } from 'aws-cdk-lib/aws-s3-assets';
import * as path from 'path';

const imageAsset = new Asset(this, "SampleAsset", {
  path: path.join(__dirname, "images/my-image.png")
});

new lambda.Function(this, "myLambdaFunction", {
  code: lambda.Code.asset(path.join(__dirname, "handler")),
  runtime: lambda.Runtime.PYTHON_3_6,
  handler: "index.lambda_handler",
  environment: {
    'S3_BUCKET_NAME': imageAsset.s3BucketName,
    'S3_OBJECT_KEY': imageAsset.s3ObjectKey,
    'S3_OBJECT_URL': imageAsset.s3ObjectUrl
  }
});
```

```
const { Asset } = require('aws-cdk-lib/aws-s3-assets');
const path = require('path');

const imageAsset = new Asset(this, "SampleAsset", {
  path: path.join(__dirname, "images/my-image.png")
});

new lambda.Function(this, "myLambdaFunction", {
  code: lambda.Code.asset(path.join(__dirname, "handler")),
  runtime: lambda.Runtime.PYTHON_3_6,
  handler: "index.lambda_handler",
  environment: {
    'S3_BUCKET_NAME': imageAsset.s3BucketName,
    'S3_OBJECT_KEY': imageAsset.s3ObjectKey,
    'S3_OBJECT_URL': imageAsset.s3ObjectUrl
  }
});
```

```
import os.path

import aws_cdk.aws_lambda as lambda_
from aws_cdk.aws_s3_assets import Asset

dirname = os.path.dirname(__file__)

image_asset = Asset(self, "SampleAsset",
    path=os.path.join(dirname, "images/my-image.png"))

lambda_.Function(self, "myLambdaFunction",
    code=lambda_.Code.asset(os.path.join(dirname, "handler")),
    runtime=lambda_.Runtime.PYTHON_3_6,
    handler="index.lambda_handler",
    environment=dict(
        S3_BUCKET_NAME=image_asset.s3_bucket_name,
        S3_OBJECT_KEY=image_asset.s3_object_key,
        S3_OBJECT_URL=image_asset.s3_object_url))
```

```
import java.io.File;

import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;
import software.amazon.awscdk.services.s3.assets.Asset;

public class FunctionStack extends Stack {
    public FunctionStack(final App scope, final String id, final StackProps props) {
        super(scope, id, props);

        File startDir = new File(System.getProperty("user.dir"));

        Asset imageAsset = Asset.Builder.create(this, "SampleAsset")
                .path(new File(startDir, "images/my-image.png").toString()).build())

        Function.Builder.create(this, "myLambdaFunction")
                .code(Code.fromAsset(new File(startDir, "handler").toString()))
                .runtime(Runtime.PYTHON_3_6)
                .handler("index.lambda_handler")
                .environment(java.util.Map.of(    // Java 9 or later
                    "S3_BUCKET_NAME", imageAsset.getS3BucketName(),
                    "S3_OBJECT_KEY", imageAsset.getS3ObjectKey(),
                    "S3_OBJECT_URL", imageAsset.getS3ObjectUrl()))
                .build();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.Lambda;
using Amazon.CDK.AWS.S3.Assets;
using System.IO;
using System.Collections.Generic;

var imageAsset = new Asset(this, "SampleAsset", new AssetProps
{
    Path = Path.Combine(Directory.GetCurrentDirectory(), @"images\my-image.png")
});

new Function(this, "myLambdaFunction", new FunctionProps
{
    Code = Code.FromAsset(Path.Combine(Directory.GetCurrentDirectory(), "handler")),
    Runtime = Runtime.PYTHON_3_6,
    Handler = "index.lambda_handler",
    Environment = new Dictionarystring, string
    {
        ["S3_BUCKET_NAME"] = imageAsset.S3BucketName,
        ["S3_OBJECT_KEY"] = imageAsset.S3ObjectKey,
        ["S3_OBJECT_URL"] = imageAsset.S3ObjectUrl
    }
});
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
  "github.com/aws/aws-cdk-go/awscdk/v2/awss3assets"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

imageAsset := awss3assets.NewAsset(stack, jsii.String("SampleAsset"), awss3assets.AssetProps{
  Path: jsii.String(path.Join(dirName, "images/my-image.png")),
})

awslambda.NewFunction(stack, jsii.String("myLambdaFunction"), awslambda.FunctionProps{
  Code: awslambda.AssetCode_FromAsset(jsii.String(path.Join(dirName, "handler"))),
  Runtime: awslambda.Runtime_PYTHON_3_6(),
  Handler: jsii.String("index.lambda_handler"),
  Environment: map[string]*string{
    "S3_BUCKET_NAME": imageAsset.S3BucketName(),
    "S3_OBJECT_KEY": imageAsset.S3ObjectKey(),
    "S3_URL": imageAsset.S3ObjectUrl(),
  },
})
```

### アクセス許可
<a name="assets-types-s3-permissions"></a>

[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets-readme.html) モジュール、IAM ロール、ユーザー、またはグループを介して Amazon S3 アセットを直接使用していて、ランタイムにアセットを読み取る必要がある場合は、それらのアセットに [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets.Asset.html#grantwbrreadgrantee](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets.Asset.html#grantwbrreadgrantee) メソッドを介して IAM アクセス許可を付与します。

以下の例では、ファイルアセットに対する IAM グループの読み取りアクセス許可を付与します。

**Example**  

```
import { Asset } from 'aws-cdk-lib/aws-s3-assets';
import * as path from 'path';

const asset = new Asset(this, 'MyFile', {
  path: path.join(__dirname, 'my-image.png')
});

const group = new iam.Group(this, 'MyUserGroup');
asset.grantRead(group);
```

```
const { Asset } = require('aws-cdk-lib/aws-s3-assets');
const path = require('path');

const asset = new Asset(this, 'MyFile', {
  path: path.join(__dirname, 'my-image.png')
});

const group = new iam.Group(this, 'MyUserGroup');
asset.grantRead(group);
```

```
from aws_cdk.aws_s3_assets import Asset
import aws_cdk.aws_iam as iam

import os.path
dirname = os.path.dirname(__file__)

        asset = Asset(self, "MyFile",
            path=os.path.join(dirname, "my-image.png"))

        group = iam.Group(self, "MyUserGroup")
        asset.grant_read(group)
```

```
import java.io.File;

import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.iam.Group;
import software.amazon.awscdk.services.s3.assets.Asset;

public class GrantStack extends Stack {
    public GrantStack(final App scope, final String id, final StackProps props) {
        super(scope, id, props);

        File startDir = new File(System.getProperty("user.dir"));

        Asset asset = Asset.Builder.create(this, "SampleAsset")
                .path(new File(startDir, "images/my-image.png").toString()).build();

        Group group = new Group(this, "MyUserGroup");
        asset.grantRead(group);   }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.IAM;
using Amazon.CDK.AWS.S3.Assets;
using System.IO;

var asset = new Asset(this, "MyFile", new AssetProps {
    Path = Path.Combine(Path.Combine(Directory.GetCurrentDirectory(), @"images\my-image.png"))
});

var group = new Group(this, "MyUserGroup");
asset.GrantRead(group);
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsiam"
  "github.com/aws/aws-cdk-go/awscdk/v2/awss3assets"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

asset := awss3assets.NewAsset(stack, jsii.String("MyFile"), awss3assets.AssetProps{
  Path: jsii.String(path.Join(dirName, "my-image.png")),
})

group := awsiam.NewGroup(stack, jsii.String("MyUserGroup"), awsiam.GroupProps{})

asset.GrantRead(group)
```

## Docker イメージアセット
<a name="assets-types-docker"></a>

 AWS CDK は、 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets-readme.html)モジュールを介したアセットとしてのローカル Docker イメージのバンドルをサポートしています。

以下の例では、ローカルに構築され、Amazon ECR にプッシュされる Docker イメージを定義します。イメージはローカルの Docker コンテキストディレクトリ (Dockerfile を使用) から構築され、 AWS CDK CLI またはアプリケーションの CI/CD パイプラインによって Amazon ECR にアップロードされます。イメージは AWS CDK アプリで自然に参照できます。

**Example**  

```
import { DockerImageAsset } from 'aws-cdk-lib/aws-ecr-assets';

const asset = new DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image')
});
```

```
const { DockerImageAsset } = require('aws-cdk-lib/aws-ecr-assets');

const asset = new DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image')
});
```

```
from aws_cdk.aws_ecr_assets import DockerImageAsset

import os.path
dirname = os.path.dirname(__file__)

asset = DockerImageAsset(self, 'MyBuildImage',
    directory=os.path.join(dirname, 'my-image'))
```

```
import software.amazon.awscdk.services.ecr.assets.DockerImageAsset;

File startDir = new File(System.getProperty("user.dir"));

DockerImageAsset asset = DockerImageAsset.Builder.create(this, "MyBuildImage")
            .directory(new File(startDir, "my-image").toString()).build();
```

```
using System.IO;
using Amazon.CDK.AWS.ECR.Assets;

var asset = new DockerImageAsset(this, "MyBuildImage", new DockerImageAssetProps
{
    Directory = Path.Combine(Directory.GetCurrentDirectory(), "my-image")
});
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecrassets"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

asset := awsecrassets.NewDockerImageAsset(stack, jsii.String("MyBuildImage"), awsecrassets.DockerImageAssetProps{
  Directory: jsii.String(path.Join(dirName, "my-image")),
})
```

`my-image` ディレクトリには Dockerfile を含める必要があります。 AWS CDK CLI は から Docker イメージを構築し`my-image`、Amazon ECR リポジトリにプッシュし、スタックに AWS CloudFormation パラメータとしてリポジトリの名前を指定します。Docker イメージアセットタイプは、 AWS CDK ライブラリとアプリケーションで参照できる[デプロイ時間属性](resources.md#resources-attributes)を公開します。 AWS CDK CLI コマンドは、アセットプロパティを AWS CloudFormation パラメータとして`cdk synth`表示します。

### Amazon ECS タスク定義 - 例
<a name="assets-types-docker-ecs"></a>

一般的なユースケースは、Docker コンテナを実行する Amazon ECS [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.TaskDefinition.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.TaskDefinition.html) を作成することです。次の例では、 AWS CDK がローカルにビルドして Amazon ECR にプッシュする Docker イメージアセットの場所を指定します。

**Example**  

```
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ecr_assets from 'aws-cdk-lib/aws-ecr-assets';
import * as path from 'path';

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef", {
  memoryLimitMiB: 1024,
  cpu: 512
});

const asset = new ecr_assets.DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image')
});

taskDefinition.addContainer("my-other-container", {
  image: ecs.ContainerImage.fromDockerImageAsset(asset)
});
```

```
const ecs = require('aws-cdk-lib/aws-ecs');
const ecr_assets = require('aws-cdk-lib/aws-ecr-assets');
const path = require('path');

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef", {
  memoryLimitMiB: 1024,
  cpu: 512
});

const asset = new ecr_assets.DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image')
});

taskDefinition.addContainer("my-other-container", {
  image: ecs.ContainerImage.fromDockerImageAsset(asset)
});
```

```
import aws_cdk.aws_ecs as ecs
import aws_cdk.aws_ecr_assets as ecr_assets

import os.path
dirname = os.path.dirname(__file__)

task_definition = ecs.FargateTaskDefinition(self, "TaskDef",
    memory_limit_mib=1024,
    cpu=512)

asset = ecr_assets.DockerImageAsset(self, 'MyBuildImage',
    directory=os.path.join(dirname, 'my-image'))

task_definition.add_container("my-other-container",
    image=ecs.ContainerImage.from_docker_image_asset(asset))
```

```
import java.io.File;

import software.amazon.awscdk.services.ecs.FargateTaskDefinition;
import software.amazon.awscdk.services.ecs.ContainerDefinitionOptions;
import software.amazon.awscdk.services.ecs.ContainerImage;

import software.amazon.awscdk.services.ecr.assets.DockerImageAsset;

File startDir = new File(System.getProperty("user.dir"));

FargateTaskDefinition taskDefinition = FargateTaskDefinition.Builder.create(
        this, "TaskDef").memoryLimitMiB(1024).cpu(512).build();

DockerImageAsset asset = DockerImageAsset.Builder.create(this, "MyBuildImage")
            .directory(new File(startDir, "my-image").toString()).build();

taskDefinition.addContainer("my-other-container",
        ContainerDefinitionOptions.builder()
            .image(ContainerImage.fromDockerImageAsset(asset))
            .build();
)
```

```
using System.IO;
using Amazon.CDK.AWS.ECS;
using Amazon.CDK.AWS.Ecr.Assets;

var taskDefinition = new FargateTaskDefinition(this, "TaskDef", new FargateTaskDefinitionProps
{
    MemoryLimitMiB = 1024,
    Cpu = 512
});

var asset = new DockerImageAsset(this, "MyBuildImage", new DockerImageAssetProps
{
    Directory = Path.Combine(Directory.GetCurrentDirectory(), "my-image")
});

taskDefinition.AddContainer("my-other-container", new ContainerDefinitionOptions
{
    Image = ContainerImage.FromDockerImageAsset(asset)
});
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecrassets"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecs"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

taskDefinition := awsecs.NewTaskDefinition(stack, jsii.String("TaskDef"), awsecs.TaskDefinitionProps{
  MemoryMiB: jsii.String("1024"),
  Cpu: jsii.String("512"),
})

asset := awsecrassets.NewDockerImageAsset(stack, jsii.String("MyBuildImage"), awsecrassets.DockerImageAssetProps{
  Directory: jsii.String(path.Join(dirName, "my-image")),
})

taskDefinition.AddContainer(jsii.String("MyOtherContainer"), awsecs.ContainerDefinitionOptions{
  Image: awsecs.ContainerImage_FromDockerImageAsset(asset),
})
```

### デプロイ時間属性の例
<a name="assets-types-docker-deploy"></a>

次の例は、デプロイ時間属性`repository`と `imageUri` を使用して、 AWS Fargate 起動タイプで Amazon ECS タスク定義を作成する方法を示しています。Amazon ECR リポジトリルックアップには、URI ではなくイメージのタグが必要なため、アセットの URI の末尾からスニップすることに注意してください。

**Example**  

```
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as path from 'path';
import { DockerImageAsset } from 'aws-cdk-lib/aws-ecr-assets';

const asset = new DockerImageAsset(this, 'my-image', {
  directory: path.join(__dirname, "..", "demo-image")
});

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef", {
  memoryLimitMiB: 1024,
  cpu: 512
});

taskDefinition.addContainer("my-other-container", {
  image: ecs.ContainerImage.fromEcrRepository(asset.repository, asset.imageUri.split(":").pop())
});
```

```
const ecs = require('aws-cdk-lib/aws-ecs');
const path = require('path');
const { DockerImageAsset } = require('aws-cdk-lib/aws-ecr-assets');

const asset = new DockerImageAsset(this, 'my-image', {
  directory: path.join(__dirname, "..", "demo-image")
});

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef", {
  memoryLimitMiB: 1024,
  cpu: 512
});

taskDefinition.addContainer("my-other-container", {
  image: ecs.ContainerImage.fromEcrRepository(asset.repository, asset.imageUri.split(":").pop())
});
```

```
import aws_cdk.aws_ecs as ecs
from aws_cdk.aws_ecr_assets import DockerImageAsset

import os.path
dirname = os.path.dirname(__file__)

asset = DockerImageAsset(self, 'my-image',
    directory=os.path.join(dirname, "..", "demo-image"))

task_definition = ecs.FargateTaskDefinition(self, "TaskDef",
    memory_limit_mib=1024, cpu=512)

task_definition.add_container("my-other-container",
    image=ecs.ContainerImage.from_ecr_repository(
        asset.repository, asset.image_uri.rpartition(":")[-1]))
```

```
import java.io.File;

import software.amazon.awscdk.services.ecr.assets.DockerImageAsset;

import software.amazon.awscdk.services.ecs.FargateTaskDefinition;
import software.amazon.awscdk.services.ecs.ContainerDefinitionOptions;
import software.amazon.awscdk.services.ecs.ContainerImage;

File startDir = new File(System.getProperty("user.dir"));

DockerImageAsset asset = DockerImageAsset.Builder.create(this, "my-image")
            .directory(new File(startDir, "demo-image").toString()).build();

FargateTaskDefinition taskDefinition = FargateTaskDefinition.Builder.create(
        this, "TaskDef").memoryLimitMiB(1024).cpu(512).build();

// extract the tag from the asset's image URI for use in ECR repo lookup
String imageUri = asset.getImageUri();
String imageTag = imageUri.substring(imageUri.lastIndexOf(":") + 1);

taskDefinition.addContainer("my-other-container",
        ContainerDefinitionOptions.builder().image(ContainerImage.fromEcrRepository(
                asset.getRepository(), imageTag)).build());
```

```
using System.IO;
using Amazon.CDK.AWS.ECS;
using Amazon.CDK.AWS.ECR.Assets;

var asset = new DockerImageAsset(this, "my-image", new DockerImageAssetProps {
    Directory = Path.Combine(Directory.GetCurrentDirectory(), "demo-image")
});

var taskDefinition = new FargateTaskDefinition(this, "TaskDef", new FargateTaskDefinitionProps
{
    MemoryLimitMiB = 1024,
    Cpu = 512
});

taskDefinition.AddContainer("my-other-container", new ContainerDefinitionOptions
{
    Image = ContainerImage.FromEcrRepository(asset.Repository, asset.ImageUri.Split(":").Last())
});
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecrassets"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecs"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

asset := awsecrassets.NewDockerImageAsset(stack, jsii.String("MyImage"), awsecrassets.DockerImageAssetProps{
  Directory: jsii.String(path.Join(dirName, "demo-image")),
})

taskDefinition := awsecs.NewFargateTaskDefinition(stack, jsii.String("TaskDef"), awsecs.FargateTaskDefinitionProps{
  MemoryLimitMiB: jsii.Number(1024),
  Cpu: jsii.Number(512),
})

taskDefinition.AddContainer(jsii.String("MyOtherContainer"), awsecs.ContainerDefinitionOptions{
  Image: awsecs.ContainerImage_FromEcrRepository(asset.Repository(), asset.ImageTag()),
})
```

### ビルド引数の例
<a name="assets-types-docker-build"></a>

 AWS CDK CLI がデプロイ中にイメージを構築するときに、 `buildArgs` (Python: `build_args`) プロパティオプションを使用して、Docker ビルドステップ用にカスタマイズされたビルド引数を指定できます。

**Example**  

```
const asset = new DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image'),
  buildArgs: {
    HTTP_PROXY: 'http://10.20.30.2:1234'
  }
});
```

```
const asset = new DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image'),
  buildArgs: {
    HTTP_PROXY: 'http://10.20.30.2:1234'
  }
});
```

```
asset = DockerImageAsset(self, "MyBuildImage",
    directory=os.path.join(dirname, "my-image"),
    build_args=dict(HTTP_PROXY="http://10.20.30.2:1234"))
```

```
DockerImageAsset asset = DockerImageAsset.Builder.create(this, "my-image"),
            .directory(new File(startDir, "my-image").toString())
            .buildArgs(java.util.Map.of(    // Java 9 or later
                "HTTP_PROXY", "http://10.20.30.2:1234"))
            .build();
```

```
var asset = new DockerImageAsset(this, "MyBuildImage", new DockerImageAssetProps {
    Directory = Path.Combine(Directory.GetCurrentDirectory(), "my-image"),
    BuildArgs = new Dictionarystring, string
    {
        ["HTTP_PROXY"] = "http://10.20.30.2:1234"
    }
});
```

```
dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

asset := awsecrassets.NewDockerImageAsset(stack, jsii.String("MyBuildImage"), awsecrassets.DockerImageAssetProps{
  Directory: jsii.String(path.Join(dirName, "my-image")),
  BuildArgs: map[string]*string{
    "HTTP_PROXY": jsii.String("http://10.20.30.2:1234"),
  },
})
```

### アクセス許可
<a name="assets-types-docker-permissions"></a>

などの Docker イメージアセットをサポートするモジュールを使用する場合、アセットを直接または ([https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.ContainerImage.html#static-fromwbrecrwbrrepositoryrepository-tag](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.ContainerImage.html#static-fromwbrecrwbrrepositoryrepository-tag)Python: ) 経由で使用する場合[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs-readme.html)、 AWS CDK はアクセス許可を管理します`from_ecr_repository`。Docker イメージアセットを直接使用する場合は、消費元プリンシパルにイメージをプルするアクセス許可があることを確認してください。

ほとんどの場合、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr.Repository.html#grantwbrpullgrantee](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr.Repository.html#grantwbrpullgrantee) メソッド (Python: `grant_pull`) を使用する必要があります。これにより、プリンシパルの IAM ポリシーが変更され、このリポジトリからイメージをプルできるようになります。イメージをプルするプリンシパルが同じアカウントにない場合、またはアカウントでロールを引き受けない AWS サービス ( AWS CodeBuild など) である場合は、プリンシパルのポリシーではなくリソースポリシーに対してプルアクセス許可を付与する必要があります。[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr.Repository.html#addwbrtowbrresourcewbrpolicystatement](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr.Repository.html#addwbrtowbrresourcewbrpolicystatement) メソッド (Python: `add_to_resource_policy`) を使用して、適切なプリンシパルのアクセス許可を付与します。

## AWS CloudFormation リソースメタデータ
<a name="assets-cfn"></a>

**注記**  
このセクションは、コンストラクト作成者にのみ関連します。特定の状況では、特定の CFN リソースがローカルアセットを使用していることをツールが把握している必要があります。たとえば、SAM CLI AWS を使用して、デバッグ目的で Lambda 関数をローカルで呼び出すことができます。詳細については、「[AWS SAM 統合](tools.md#sam)」を参照してください。

このようなユースケースを有効にするために、外部ツールは AWS CloudFormation リソースのメタデータエントリのセットを参照します。
+  `aws:asset:path` – アセットのローカルパスを指します。
+  `aws:asset:property` – アセットが使用されるリソースプロパティの名前。

これら 2 つのメタデータエントリを使用すると、ツールはアセットが特定のリソースによって使用されていることを特定し、高度なローカルエクスペリエンスを実現できます。

これらのメタデータエントリをリソースに追加するには、`asset.addResourceMetadata` (Python: `add_resource_metadata`) メソッドを使用します。

# アクセス許可と AWS CDK
<a name="permissions"></a>

 AWS コンストラクトライブラリは、アクセスとアクセス許可を管理するために、広く実装されているいくつかの一般的なイディオムを使用します。IAM モジュールは、これらのイディオムを使用するために必要なツールを提供します。

 AWS CDK は AWS CloudFormation を使用して変更をデプロイします。すべてのデプロイには、 AWS CloudFormation デプロイを開始するアクター (開発者または自動システム) が含まれます。これを行う過程で、アクターは 1 つ以上の IAM ID (ユーザーまたはロール) を引き受け、オプションで AWS CloudFormation にロールを渡します。

 AWS IAM Identity Center を使用してユーザーとして認証する場合、シングルサインオンプロバイダーは、事前定義された IAM ロールとして動作することを許可する有効期間の短いセッション認証情報を提供します。 AWS CDK が IAM アイデンティティセンター認証から AWS 認証情報を取得する方法については、 SDK およびツールリファレンスガイドの[「IAM アイデンティティセンター認証を理解する](https://docs.aws.amazon.com/sdkref/latest/guide/understanding-sso.html)」を参照してください。 * AWS SDKs *

## プリンシパル
<a name="permissions-principals"></a>

IAM プリンシパルは、API を呼び出すことができるユーザー、サービス、またはアプリケーションを表す認証された AWS エンティティです。 AWS APIs AWS コンストラクトライブラリでは、プリンシパルを複数の柔軟な方法で指定して、 AWS リソースへのアクセスを許可できます。

セキュリティコンテキストでは、「プリンシパル」という用語は特にユーザーなどの認証されたエンティティを指します。グループやロールなどのオブジェクトは、ユーザー (およびその他の認証されたエンティティ) を*表す*のではなく、アクセス許可を付与する目的で間接的に*特定*します。

例えば、IAM グループを作成する場合、グループ (およびそのメンバー) に Amazon RDS テーブルへの書き込みアクセスを許可できます。ただし、グループ自体は単一のエンティティを表していないため、プリンシパルではありません (また、グループにログインすることができません)。

CDK の IAM ライブラリでは、プリンシパルを直接または間接的に特定するクラスが [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.IPrincipal.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.IPrincipal.html) インターフェイスを実装するため、これらのオブジェクトをアクセスポリシーで互換的に使用できるようにします。ただし、セキュリティ上の意味ではすべてがプリンシパルではありません。これらのオブジェクトには次のものが含まれます。

1. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html)、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html)、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html) などの IAM リソース 

1. サービスプリンシパル (`new iam.[ServicePrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ServicePrincipal.html)('service.amazonaws.com')`)

1. フェデレーティッドプリンシパル (`new iam.[FederatedPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.FederatedPrincipal.html)('cognito-identity.amazonaws.com')`)

1. アカウントプリンシパル (`new iam.[AccountPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.AccountPrincipal.html)('0123456789012')`)

1. 正規ユーザープリンシパル (`new iam.[CanonicalUserPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.CanonicalUserPrincipal.html)('79a59d[…​]7ef2be')`)

1.  AWS Organizations プリンシパル (`new iam.[OrganizationPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.OrganizationPrincipal.html)('org-id')`)

1. 任意の ARN プリンシパル (`new iam.[ArnPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ArnPrincipal.html)(res.arn)`)

1. 複数のプリンシパルを信頼するための `iam.[CompositePrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.CompositePrincipal.html)(principal1, principal2, …​)`

## 権限
<a name="permissions-grants"></a>

多くのコンストラクトは、Amazon S3 バケットや Amazon DynamoDB テーブルなど、アクセスできるリソースを表します。その場合は、別のエンティティへのアクセスを許可できます。これを行うには、特定のコンストラクトに応じて、対応する Grants クラス (`BucketGrants`Amazon S3 バケットなど) を使用する方法と、 **grant** で始まる名前を持つコンストラクト自体のメソッドを使用する方法の 2 つの方法があります。前者は、同じ方法で L1 リソースと L2 リソースの両方へのアクセスを許可するために使用できるため、推奨されます。Grants クラスのインスタンスを作成するには、ファクトリメソッドを使用します。

**Example**  

```
BucketGrants.fromBucket(bucket); // bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

```
BucketGrants.fromBucket(bucket); // bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

```
BucketGrants.from_bucket(bucket) # bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

```
BucketGrants.fromBucket(bucket); // bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

```
BucketGrants.FromBucket(bucket); // bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

Grants クラスは、リソースにアクセスするための特定のアクセス許可を付与する方法を提供します。たとえば、 `BucketGrants`には、 エンティティからバケットへの読み取りおよび書き込みアクセスをそれぞれ有効にするメソッド`read`と `readWrite` (Python: `read`、`read_write`) があります。エンティティは、これらの操作を実行するために必要な Amazon S3 IAM アクセス許可を正確に知る必要はありません。

Grants クラス (またはリソース自体の **grant** メソッド) のメソッドの最初の引数は、常にタイプ です[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.IGrantable.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.IGrantable.html)。このインターフェイスは、アクセス許可を付与できるエンティティを表します。つまり、IAM オブジェクトの [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html)、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html)、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html) などのロールを持つリソースを表します。

他のエンティティにもアクセス許可を付与できます。例えば、このトピックの後半では、CodeBuild プロジェクトにAmazon S3 バケットへのアクセスを許可する方法を示します。一般的に、関連付けられたロールは、アクセスが許可されているエンティティの `role` プロパティを介して取得されます。

[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html) などの実行ロールを使用するリソースも `IGrantable` を実装するため、ロールにアクセスを許可するのではなく、直接アクセスを許可できます。例えば、`bucket` が Amazon S3 バケットで `function` が Lambda 関数である場合、次のコードは関数にバケットへの読み取りアクセスを許可します。

便宜上、L2 コンストラクトは対応する Grants クラスのインスタンスを返す`grants`プロパティも提供します。

**Example**  

```
bucket.grants.read(function);
```

```
bucket.grants.read(function);
```

```
bucket.grants.read(function)
```

```
bucket.getGrants().read(function);
```

```
bucket.Grants.Read(function);
```

スタックのデプロイ中にアクセス許可の適用が必要な場合があります。このようなケースの 1 つは、 AWS CloudFormation カスタムリソースに他のリソースへのアクセスを許可する場合です。カスタムリソースはデプロイ時に呼び出されるため、デプロイ時に指定されたアクセス許可が必要です。

もう 1 つのケースは、サービスに渡したロールに適切なポリシーが適用されていることをサービスが検証する例です。(ポリシーの設定を忘れないように、多くの AWS のサービスがこれを行います）。このようなケースでは、アクセス許可の適用が遅すぎる場合、デプロイが失敗する可能性があります。

別のリソースが作成される前に付与されたアクセス許可を強制的に適用するには、こちらに示すように、付与自体に依存関係を追加できます。付与メソッドの戻り値は一般的に破棄されますが、実際にはすべての付与メソッドは `iam.Grant` オブジェクトを返します。

**Example**  

```
const grant = bucket.grants.read(lambda);
const custom = new CustomResource(...);
custom.node.addDependency(grant);
```

```
const grant = bucket.grants.read(lambda);
const custom = new CustomResource(...);
custom.node.addDependency(grant);
```

```
grant = bucket.grants.read(function)
custom = CustomResource(...)
custom.node.add_dependency(grant)
```

```
Grant grant = bucket.getGrants().read(function);
CustomResource custom = new CustomResource(...);
custom.node.addDependency(grant);
```

```
var grant = bucket.Grants.Read(function);
var custom = new CustomResource(...);
custom.node.AddDependency(grant);
```

## ロール
<a name="permissions-roles"></a>

IAM パッケージには、IAM ロールを表す [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html) コンストラクトが含まれています。次のコードは、Amazon EC2 サービスを信頼する新しいロールを作成します。

**Example**  

```
import * as iam from 'aws-cdk-lib/aws-iam';

const role = new iam.Role(this, 'Role', {
  assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),   // required
});
```

```
const iam = require('aws-cdk-lib/aws-iam');

const role = new iam.Role(this, 'Role', {
  assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com')   // required
});
```

```
import aws_cdk.aws_iam as iam

role = iam.Role(self, "Role",
          assumed_by=iam.ServicePrincipal("ec2.amazonaws.com")) # required
```

```
import software.amazon.awscdk.services.iam.Role;
import software.amazon.awscdk.services.iam.ServicePrincipal;

Role role = Role.Builder.create(this, "Role")
        .assumedBy(new ServicePrincipal("ec2.amazonaws.com")).build();
```

```
using Amazon.CDK.AWS.IAM;

var role = new Role(this, "Role", new RoleProps
{
    AssumedBy = new ServicePrincipal("ec2.amazonaws.com"),   // required
});
```

ロールの [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#addwbrtowbrpolicystatement](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#addwbrtowbrpolicystatement) メソッド (Python: `add_to_policy`) を呼び出し、追加するルールを定義する [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html) で渡すことにより、ロールにアクセス許可を追加できます。ステートメントはロールのデフォルトポリシーに追加されます。持っていない場合、1 つ作成されます。

次の例では、承認されたサービスが AWS CodeBuild であることを条件として、 アクションの ロール`ec2:SomeAction`、 リソースの ロール`bucket`、および `otherRole` (Python: `other_role`) `s3:AnotherAction`に`Deny`ポリシーステートメントを追加します。

**Example**  

```
role.addToPolicy(new iam.PolicyStatement({
  effect: iam.Effect.DENY,
  resources: [bucket.bucketArn, otherRole.roleArn],
  actions: ['ec2:SomeAction', 's3:AnotherAction'],
  conditions: {StringEquals: {
    'ec2:AuthorizedService': 'codebuild.amazonaws.com',
}}}));
```

```
role.addToPolicy(new iam.PolicyStatement({
  effect: iam.Effect.DENY,
  resources: [bucket.bucketArn, otherRole.roleArn],
  actions: ['ec2:SomeAction', 's3:AnotherAction'],
  conditions: {StringEquals: {
    'ec2:AuthorizedService': 'codebuild.amazonaws.com'
}}}));
```

```
role.add_to_policy(iam.PolicyStatement(
    effect=iam.Effect.DENY,
    resources=[bucket.bucket_arn, other_role.role_arn],
    actions=["ec2:SomeAction", "s3:AnotherAction"],
    conditions={"StringEquals": {
        "ec2:AuthorizedService": "codebuild.amazonaws.com"}}
))
```

```
role.addToPolicy(PolicyStatement.Builder.create()
        .effect(Effect.DENY)
        .resources(Arrays.asList(bucket.getBucketArn(), otherRole.getRoleArn()))
        .actions(Arrays.asList("ec2:SomeAction", "s3:AnotherAction"))
        .conditions(java.util.Map.of(    // Map.of requires Java 9 or later
            "StringEquals", java.util.Map.of(
                "ec2:AuthorizedService", "codebuild.amazonaws.com")))
        .build());
```

```
role.AddToPolicy(new PolicyStatement(new PolicyStatementProps
{
    Effect = Effect.DENY,
    Resources = new string[] { bucket.BucketArn, otherRole.RoleArn },
    Actions = new string[] { "ec2:SomeAction", "s3:AnotherAction" },
    Conditions = new Dictionary<string, object>
    {
        ["StringEquals"] = new Dictionary<string, string>
        {
            ["ec2:AuthorizedService"] = "codebuild.amazonaws.com"
        }
    }
}));
```

前の例では、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#addwbrtowbrpolicystatement](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#addwbrtowbrpolicystatement) (Python: `add_to_policy`) コールで新しい [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html) インラインを作成しました。既存のポリシーステートメントまたは変更したポリシーステートメントに渡すこともできます。[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html) オブジェクトにはプリンシパル、リソース、条件、アクションを追加する[多数の方法](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html#methods)があります。

ロールが正しく機能する必要があるコンストラクトを使用している場合、次のいずれかを実行できます。
+ コンストラクトオブジェクトをインスタンス化するとき、既存のロールに渡します。
+ 適切なサービスプリンシパルを信頼し、コンストラクトに新しいロールを作成させます。次の例では、CodeBuild プロジェクトというコンストラクトを使用します。

**Example**  

```
import * as codebuild from 'aws-cdk-lib/aws-codebuild';

// imagine roleOrUndefined is a function that might return a Role object
// under some conditions, and undefined under other conditions
const someRole: iam.IRole | undefined = roleOrUndefined();

const project = new codebuild.Project(this, 'Project', {
  // if someRole is undefined, the Project creates a new default role,
  // trusting the codebuild.amazonaws.com service principal
  role: someRole,
});
```

```
const codebuild = require('aws-cdk-lib/aws-codebuild');

// imagine roleOrUndefined is a function that might return a Role object
// under some conditions, and undefined under other conditions
const someRole = roleOrUndefined();

const project = new codebuild.Project(this, 'Project', {
  // if someRole is undefined, the Project creates a new default role,
  // trusting the codebuild.amazonaws.com service principal
  role: someRole
});
```

```
import aws_cdk.aws_codebuild as codebuild

# imagine role_or_none is a function that might return a Role object
# under some conditions, and None under other conditions
some_role = role_or_none();

project = codebuild.Project(self, "Project",
# if role is None, the Project creates a new default role,
# trusting the codebuild.amazonaws.com service principal
role=some_role)
```

```
import software.amazon.awscdk.services.iam.Role;
import software.amazon.awscdk.services.codebuild.Project;

// imagine roleOrNull is a function that might return a Role object
// under some conditions, and null under other conditions
Role someRole = roleOrNull();

// if someRole is null, the Project creates a new default role,
// trusting the codebuild.amazonaws.com service principal
Project project = Project.Builder.create(this, "Project")
        .role(someRole).build();
```

```
using Amazon.CDK.AWS.CodeBuild;

// imagine roleOrNull is a function that might return a Role object
// under some conditions, and null under other conditions
var someRole = roleOrNull();

// if someRole is null, the Project creates a new default role,
// trusting the codebuild.amazonaws.com service principal
var project = new Project(this, "Project", new ProjectProps
{
    Role = someRole
});
```

オブジェクトが作成されたら、ロール (ロールを渡したが、コンストラクトによってデフォルトのものが作成されたかを問わず) がプロパティ `role` として利用できます。ただし、このプロパティは外部リソースでは利用できません。したがって、これらのコンストラクトには `addToRolePolicy` (Python: `add_to_role_policy`) メソッドがあります。

コンストラクトが外部リソースである場合、メソッドは何も行いません。それ以外の場合は `role` プロパティの `addToPolicy` (Python: `add_to_policy`) メソッドを呼び出します。未定義のケースを明示的に処理する手間を省けます。

次の例で示される内容

**Example**  

```
// project is imported into the CDK application
const project = codebuild.Project.fromProjectName(this, 'Project', 'ProjectName');

// project is imported, so project.role is undefined, and this call has no effect
project.addToRolePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,   // ... and so on defining the policy
}));
```

```
// project is imported into the CDK application
const project = codebuild.Project.fromProjectName(this, 'Project', 'ProjectName');

// project is imported, so project.role is undefined, and this call has no effect
project.addToRolePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW   // ... and so on defining the policy
}));
```

```
# project is imported into the CDK application
project = codebuild.Project.from_project_name(self, 'Project', 'ProjectName')

# project is imported, so project.role is undefined, and this call has no effect
project.add_to_role_policy(iam.PolicyStatement(
  effect=iam.Effect.ALLOW,   # ... and so on defining the policy
  )
)
```

```
// project is imported into the CDK application
Project project = Project.fromProjectName(this, "Project", "ProjectName");

// project is imported, so project.getRole() is null, and this call has no effect
project.addToRolePolicy(PolicyStatement.Builder.create()
        .effect(Effect.ALLOW)   // .. and so on defining the policy
        .build();
)
```

```
// project is imported into the CDK application
var project = Project.FromProjectName(this, "Project", "ProjectName");

// project is imported, so project.role is null, and this call has no effect
project.AddToRolePolicy(new PolicyStatement(new PolicyStatementProps
{
    Effect = Effect.ALLOW, // ... and so on defining the policy
}));
```

## リソースポリシー
<a name="permissions-resource-policies"></a>

Amazon S3 バケットや IAM ロールなど AWS、 の一部のリソースにもリソースポリシーがあります。これらのコンストラクトには `addToResourcePolicy` メソッド (Python: `add_to_resource_policy`) があり、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html) を引数として扱います。リソースポリシーに追加されるすべてのポリシーステートメントには、少なくとも 1 つのプリンシパルを指定する必要があります。

次の例では、[Amazon S3 バケット](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html)の `bucket` が、`s3:SomeAction` のアクセス許可を持つロールを自らに付与しています。

**Example**  

```
bucket.addToResourcePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,
  actions: ['s3:SomeAction'],
  resources: [bucket.bucketArn],
  principals: [role]
}));
```

```
bucket.addToResourcePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,
  actions: ['s3:SomeAction'],
  resources: [bucket.bucketArn],
  principals: [role]
}));
```

```
bucket.add_to_resource_policy(iam.PolicyStatement(
    effect=iam.Effect.ALLOW,
    actions=["s3:SomeAction"],
    resources=[bucket.bucket_arn],
    principals=role))
```

```
bucket.addToResourcePolicy(PolicyStatement.Builder.create()
        .effect(Effect.ALLOW)
        .actions(Arrays.asList("s3:SomeAction"))
        .resources(Arrays.asList(bucket.getBucketArn()))
        .principals(Arrays.asList(role))
        .build());
```

```
bucket.AddToResourcePolicy(new PolicyStatement(new PolicyStatementProps
{
    Effect = Effect.ALLOW,
    Actions = new string[] { "s3:SomeAction" },
    Resources = new string[] { bucket.BucketArn },
    Principals = new IPrincipal[] { role }
}));
```

## 外部 IAM オブジェクトの使用
<a name="permissions-existing"></a>

 AWS CDK アプリの外部で IAM ユーザー、プリンシパル、グループ、またはロールを定義している場合は、 AWS CDK アプリでその IAM オブジェクトを使用できます。これを行うには、ARN またはその名前を使用してそのリファレンスを作成します。(ユーザー、グループ、ロールの名前を使用します) その後、返されたリファレンスを使用し、前述のようにアクセス許可を付与したり、ポリシーステートメントを構築したりできます。
+ ユーザーの場合、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html#static-fromwbruserwbrarnscope-id-userarn](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html#static-fromwbruserwbrarnscope-id-userarn) または [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html#static-fromwbruserwbrnamescope-id-username](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html#static-fromwbruserwbrnamescope-id-username) を呼び出します。`User.fromUserAttributes()` も利用できますが、現在は `User.fromUserArn()` と同じ機能を使用できます。
+ プリンシパルの場合、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ArnPrincipal.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ArnPrincipal.html) オブジェクトをインスタンス化します。
+ グループの場合、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html#static-fromwbrgroupwbrarnscope-id-grouparn](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html#static-fromwbrgroupwbrarnscope-id-grouparn) または [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html#static-fromwbrgroupwbrnamescope-id-groupname](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html#static-fromwbrgroupwbrnamescope-id-groupname) を呼び出します。
+ ロールの場合、[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#static-fromwbrrolewbrarnscope-id-rolearn-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#static-fromwbrrolewbrarnscope-id-rolearn-options) または [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#static-fromwbrrolewbrnamescope-id-rolename](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#static-fromwbrrolewbrnamescope-id-rolename) を呼び出します。

ポリシー (マネージドポリシーを含む) は、次の方法を使用して同様に使用できます。これらのオブジェクトへのリファレンスは、IAM ポリシーが必要な場所で使用できます。
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Policy.html#static-fromwbrpolicywbrnamescope-id-policyname](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Policy.html#static-fromwbrpolicywbrnamescope-id-policyname) 
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrmanagedwbrpolicywbrarnscope-id-managedpolicyarn](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrmanagedwbrpolicywbrarnscope-id-managedpolicyarn) 
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrmanagedwbrpolicywbrnamescope-id-managedpolicyname](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrmanagedwbrpolicywbrnamescope-id-managedpolicyname) 
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrawswbrmanagedwbrpolicywbrnamemanagedpolicyname](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrawswbrmanagedwbrpolicywbrnamemanagedpolicyname) 

**注記**  
外部 AWS リソースへのすべての参照と同様に、CDK アプリで外部 IAM オブジェクトを変更することはできません。

# コンテキスト値と AWS CDK
<a name="context"></a>

コンテキスト値は、アプリ、スタック、またはコンストラクトに関連付けることのできるキーと値のペアです。これらは、ファイル (通常はプロジェクトディレクトリ内の `cdk.json` または `cdk.context.json`) またはコマンドラインからアプリに提供できます。

CDK Toolkit は、コンテキストを使用して、合成中に AWS アカウントから取得した値をキャッシュします。値には、アカウントのアベイラビリティーゾーン、または Amazon EC2 インスタンスで現在利用可能な Amazon マシンイメージ (AMI) ID が含まれます。これらの値は AWS アカウントによって提供されるため、CDK アプリケーションの実行間で変更される可能性があります。これにより、意図しない変更が発生する可能性があります。CDK Toolkit のキャッシュ動作は、新しい値を受け入れることを決定するまで、CDK アプリのこれらの値を「凍結」します。

コンテキストキャッシュを無効にした場合の以下のシナリオを想像してください。Amazon EC2 インスタンスの AMI として「最新の Amazon Linux」を指定し、この AMI の新しいバージョンがリリースされたとします。そうすると、次に CDK スタックをデプロイするときには、デプロイ済みのインスタンスが古い (「間違った」) AMI を使用していることになるため、アップグレードが必要になります。アップグレードすると、既存のすべてのインスタンスが新しいインスタンスに置き換えられますが、これはおそらく予期せぬ望ましくない結果でしょう。

そうする代わりに、CDK はアカウントで使用可能な AMI をプロジェクトの `cdk.context.json` ファイルに記録し、今後合成オペレーションに保存された値を使用します。これにより、AMI のリストは潜在的な変更の原因ではなくなります。また、スタックが常に同じ AWS CloudFormation テンプレートに合成されるようにすることもできます。

すべてのコンテキスト値が AWS 環境からキャッシュされるわけではありません。[AWS CDK 機能フラグ](featureflags.md)もまたコンテキスト値です。また、アプリケーションやコンストラクトで使用する独自のコンテキスト値を作成することもできます。

コンテキストキーは文字列です。値は、数値、文字列、配列、オブジェクトなど、JSON でサポートされている任意のタイプにすることができます。

**ヒント**  
コンストラクトが独自のコンテキスト値を作成する場合は、ライブラリのパッケージ名をキーに組み込み、他のパッケージのコンテキスト値と競合しないようにします。

多くのコンテキスト値は特定の AWS 環境に関連付けられており、特定の CDK アプリを複数の環境にデプロイできます。このような値のキーには、異なる環境の値が競合しないように、 AWS アカウントとリージョンが含まれます。

次のコンテキストキーは、アカウントとリージョンを含む AWS CDK で使用される形式を示しています。

```
availability-zones:account=123456789012:region=eu-central-1
```

**重要**  
キャッシュされたコンテキスト値は、書き込み可能なコンストラクトを含め、 AWS CDK とそのコンストラクトによって管理されます。ファイルを手動で編集することで、キャッシュされたコンテキスト値を追加または変更してはなりません。ただし、キャッシュされている値を確認するために時々 `cdk.context.json` を確認することは有用です。キャッシュされた値を表さないコンテキスト値は、`cdk.json` の `context` キーの下に保存する必要があります。これにより、キャッシュ値がクリアされたときでもそれらはクリアされません。

## コンテキスト値のソース
<a name="context-construct"></a>

コンテキスト値は、次の 6 つの異なる方法で AWS CDK アプリに提供できます。
+ 現在の AWS アカウントから自動的に。
+ `cdk` コマンドの `--context` オプションを通して (これらの値は常に文字列です)
+ プロジェクトの `cdk.context.json` ファイル。
+ プロジェクトの `cdk.json` ファイルの `context` キー。
+ `~/.cdk.json` ファイルの `context` キー
+ `construct.node.setContext()` メソッドを使用して AWS CDK アプリで。

プロジェクトファイルは、 AWS CDK が AWS アカウントから取得したコンテキスト値をキャッシュする場所`cdk.context.json`です。この方法により、新しいアベイラビリティーゾーンが導入されるなど、デプロイに予期しない変更が加えられるのを回避できます。 AWS CDK は、リストされている他のファイルにコンテキストデータを書き込みません。

**重要**  
これらはアプリケーションの状態の一部であるため、`cdk.json` と`cdk.context.json` は、アプリのソースコードの残りの部分とともにソース管理にコミットする必要があります。そうしないと、他の環境 (CI パイプラインなど) にデプロイするとき、一貫性のない結果が生じる可能性があります。

コンテキスト値は、それらを作成したコンストラクトにスコープされます。子コンストラクトには表示されますが、親や兄弟には表示されません。 AWS CDK Toolkit ( `cdk` コマンド) によって設定されるコンテキスト値は、ファイルまたは `--context`オプションから自動的に設定できます。これらのソースのコンテキスト値は、`App` コンストラクトに暗黙的に設定されます。したがって、これらはアプリケーション内のすべてのスタックのすべてのコンストラクトに表示されます。

アプリケーションは、`construct.node.tryGetContext` メソッドを使用してコンテキスト値を読み取ることができます。リクエストされたエントリが現在のコンストラクトまたはその親のいずれにも見つからない場合、結果は `undefined` になります。(または、Python の `None` のように、使用言語での同等の値が得られる場合もあります。)

## context メソッド
<a name="context-methods"></a>

 AWS CDK は、 AWS CDK アプリケーションが AWS 環境からコンテキスト情報を取得できるようにするいくつかのコンテキストメソッドをサポートしています。たとえば、 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#availabilityzones](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#availabilityzones)メソッドを使用して、特定の AWS アカウントとリージョンで使用できるアベイラビリティーゾーンのリストを取得できます。

コンテキストメソッドは以下のとおりです。

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_route53.HostedZone.html#static-fromwbrlookupscope-id-query](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_route53.HostedZone.html#static-fromwbrlookupscope-id-query)   
アカウントのホストゾーンを取得します。

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#availabilityzones](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#availabilityzones)   
サポートされているアベイラビリティーゾーンを取得します。

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ssm.StringParameter.html#static-valuewbrfromwbrlookupscope-parametername](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ssm.StringParameter.html#static-valuewbrfromwbrlookupscope-parametername)   
現在のリージョンの Amazon EC2 Systems Manager パラメータストアから値を取得します。

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.Vpc.html#static-fromwbrlookupscope-id-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.Vpc.html#static-fromwbrlookupscope-id-options)   
アカウント内の既存の Amazon Virtual Private Clouds を取得します。

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.LookupMachineImage.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.LookupMachineImage.html)   
Amazon Virtual Private Cloud の NAT インスタンスで使用するマシンイメージを検索します。

必要なコンテキスト値が使用できない場合、 AWS CDK アプリはコンテキスト情報が欠落していることを CDK Toolkit に通知します。次に、CLI は現在の AWS アカウントに情報をクエリし、結果のコンテキスト情報を`cdk.context.json`ファイルに保存します。次に、コンテキスト値を使用して AWS CDK アプリを再度実行します。

## コンテキストの表示と管理
<a name="context-viewing"></a>

`cdk context` コマンドを使用して、`cdk.context.json` ファイル内の情報を表示および管理します。この情報を表示するには、オプションなしで `cdk context` コマンドを使用します。出力は以下のようになります。

```
Context found in cdk.json:

┌───┬─────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────┐
│ # │ Key                                                         │ Value                                                   │
├───┼─────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────┤
│ 1 │ availability-zones:account=123456789012:region=eu-central-1 │ [ "eu-central-1a", "eu-central-1b", "eu-central-1c" ]   │
├───┼─────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────┤
│ 2 │ availability-zones:account=123456789012:region=eu-west-1    │ [ "eu-west-1a", "eu-west-1b", "eu-west-1c" ]            │
└───┴─────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────┘

Run

  cdk context --reset KEY_OR_NUMBER

 to remove a context key. If it is a cached value, it will be refreshed on the next

  cdk synth

.
```

コンテキスト値を削除するには、値に対応するキーまたは数値を指定して `cdk context --reset` を実行します。以下の例では、前の例の 2 番目のキーに対応する値を削除します。この値は、欧州 (アイルランド) リージョンのアベイラビリティーゾーンのリストを表します。

```
cdk context --reset 2
```

```
Context value
availability-zones:account=123456789012:region=eu-west-1
reset. It will be refreshed on the next SDK synthesis run.
```

したがって、Amazon Linux AMI の最新バージョンに更新する場合は、前の例を使用してコンテキスト値の制御された更新を行い、リセットします。次に、アプリを合成して再度デプロイします。

```
$ cdk synth
```

アプリケーションの保存されたコンテキスト値をすべてクリアするには、以下のように `cdk context --clear` を実行します。

```
$ cdk context --clear
```

リセットまたはクリアできるのは、`cdk.context.json` に保存されているコンテキスト値のみです。 AWS CDK は他のコンテキスト値には影響しません。したがって、これらのコマンドを使用してコンテキスト値がリセットされないように保護するために、値を `cdk.json` にコピーできます。

## AWS CDK Toolkit `--context`フラグ
<a name="context-cli"></a>

`--context` (略して `-c`) オプションを使用して、合成またはデプロイ中にランタイムコンテキスト値を CDK アプリケーションに渡します。

```
$ cdk synth --context key=value MyStack
```

複数のコンテキスト値を指定するには、`--context` オプションを何回でも繰り返し、毎回 1 つのキーと値のペアを指定します。

```
$ cdk synth --context key1=value1 --context key2=value2 MyStack
```

複数のスタックを合成すると、指定されたコンテキスト値がすべてのスタックに渡されます。個々のスタックに異なるコンテキスト値を指定するには、値に異なるキーを使用するか、複数の `cdk synth` コマンドまたは `cdk deploy` コマンドを使用します。

コマンドラインから渡されるコンテキスト値は、常に文字列です。通常、値が他のタイプである場合は、コードを変換または解析する準備を整える必要があります。文字列以外のコンテキスト値は、他の方法 (`cdk.context.json` など) で提供される場合があります。この種の値が期待どおりに動作することを確認するには、変換する前に値が文字列であることを確認します。

## 例
<a name="context-example"></a>

 AWS CDK コンテキストを使用して既存の Amazon VPC を使用する例を次に示します。

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';

export class ExistsVpcStack extends cdk.Stack {

  constructor(scope: Construct, id: string, props?: cdk.StackProps) {

    super(scope, id, props);

    const vpcid = this.node.tryGetContext('vpcid');
    const vpc = ec2.Vpc.fromLookup(this, 'VPC', {
      vpcId: vpcid,
    });

    const pubsubnets = vpc.selectSubnets({subnetType: ec2.SubnetType.PUBLIC});

    new cdk.CfnOutput(this, 'publicsubnets', {
      value: pubsubnets.subnetIds.toString(),
    });
  }
}
```

```
const cdk = require('aws-cdk-lib');
const ec2 = require('aws-cdk-lib/aws-ec2');

class ExistsVpcStack extends cdk.Stack {

  constructor(scope, id, props) {

    super(scope, id, props);

    const vpcid = this.node.tryGetContext('vpcid');
    const vpc = ec2.Vpc.fromLookup(this, 'VPC', {
      vpcId: vpcid
    });

    const pubsubnets = vpc.selectSubnets({subnetType: ec2.SubnetType.PUBLIC});

    new cdk.CfnOutput(this, 'publicsubnets', {
      value: pubsubnets.subnetIds.toString()
    });
  }
}

module.exports = { ExistsVpcStack }
```

```
import aws_cdk as cdk
import aws_cdk.aws_ec2 as ec2
from constructs import Construct

class ExistsVpcStack(cdk.Stack):

    def __init__(scope: Construct, id: str, **kwargs):

        super().__init__(scope, id, **kwargs)

        vpcid = self.node.try_get_context("vpcid")
        vpc = ec2.Vpc.from_lookup(self, "VPC", vpc_id=vpcid)

        pubsubnets = vpc.select_subnets(subnetType=ec2.SubnetType.PUBLIC)

        cdk.CfnOutput(self, "publicsubnets",
            value=pubsubnets.subnet_ids.to_string())
```

```
import software.amazon.awscdk.CfnOutput;

import software.amazon.awscdk.services.ec2.Vpc;
import software.amazon.awscdk.services.ec2.VpcLookupOptions;
import software.amazon.awscdk.services.ec2.SelectedSubnets;
import software.amazon.awscdk.services.ec2.SubnetSelection;
import software.amazon.awscdk.services.ec2.SubnetType;
import software.constructs.Construct;

public class ExistsVpcStack extends Stack {
    public ExistsVpcStack(Construct context, String id) {
        this(context, id, null);
    }

    public ExistsVpcStack(Construct context, String id, StackProps props) {
        super(context, id, props);

        String vpcId = (String)this.getNode().tryGetContext("vpcid");
        Vpc vpc = (Vpc)Vpc.fromLookup(this, "VPC", VpcLookupOptions.builder()
                .vpcId(vpcId).build());

        SelectedSubnets pubSubNets = vpc.selectSubnets(SubnetSelection.builder()
                .subnetType(SubnetType.PUBLIC).build());

        CfnOutput.Builder.create(this, "publicsubnets")
                .value(pubSubNets.getSubnetIds().toString()).build();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.EC2;
using Constructs;

class ExistsVpcStack : Stack
{
    public ExistsVpcStack(Construct scope, string id, StackProps props) : base(scope, id, props)
    {
        var vpcId = (string)this.Node.TryGetContext("vpcid");
        var vpc = Vpc.FromLookup(this, "VPC", new VpcLookupOptions
        {
            VpcId = vpcId
        });

        SelectedSubnets pubSubNets = vpc.SelectSubnets([new SubnetSelection
        {
            SubnetType = SubnetType.PUBLIC
        }]);

        new CfnOutput(this, "publicsubnets", new CfnOutputProps {
            Value = pubSubNets.SubnetIds.ToString()
        });
    }
}
```

`cdk diff` を使用して、コマンドラインでコンテキスト値を渡す効果を確認できます。

```
$ cdk diff -c vpcid=vpc-0cb9c31031d0d3e22
```

```
Stack ExistsvpcStack
Outputs
[+] Output publicsubnets publicsubnets: {"Value":"subnet-06e0ea7dd302d3e8f,subnet-01fc0acfb58f3128f"}
```

結果のコンテキスト値は、ここに示すように表示できます。

```
$ cdk context -j
```

```
{
  "vpc-provider:account=123456789012:filter.vpc-id=vpc-0cb9c31031d0d3e22:region=us-east-1": {
    "vpcId": "vpc-0cb9c31031d0d3e22",
    "availabilityZones": [
      "us-east-1a",
      "us-east-1b"
    ],
    "privateSubnetIds": [
      "subnet-03ecfc033225be285",
      "subnet-0cded5da53180ebfa"
    ],
    "privateSubnetNames": [
      "Private"
    ],
    "privateSubnetRouteTableIds": [
      "rtb-0e955393ced0ada04",
      "rtb-05602e7b9f310e5b0"
    ],
    "publicSubnetIds": [
      "subnet-06e0ea7dd302d3e8f",
      "subnet-01fc0acfb58f3128f"
    ],
    "publicSubnetNames": [
      "Public"
    ],
    "publicSubnetRouteTableIds": [
      "rtb-00d1fdfd823c82289",
      "rtb-04bb1969b42969bcb"
    ]
  }
}
```

# AWS CDK 機能フラグ
<a name="featureflags"></a>

AWS CDK は、リリースで潜在的な互換性破壊を伴う動作を有効にするために、*機能フラグ*を使用します。フラグは、[コンテキスト値と AWS CDK 値](context.md)として `cdk.json` (または `~/.cdk.json`) に保存されます。これらは、`cdk context --reset` または `cdk context --clear` コマンドによっては削除されません。

機能フラグはデフォルトでは無効になっています。フラグを指定していない既存のプロジェクトは、後続の AWS CDK のリリースでも以前と同様の動作を続けます。`cdk init` を使用して作成された新しいプロジェクトには、プロジェクトを作成したリリースで利用可能なすべての機能を有効にするフラグが含まれます。以前の動作を希望するフラグについては、`cdk.json` を編集して無効にできます。また、AWS CDK をアップグレードした後で、新しい動作を有効にするためにフラグを追加することもできます。

現在のすべての機能フラグのリストは、AWS CDK GitHub リポジトリの [FEATURE\$1FLAGS.md](https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md) で確認できます。特定のリリースで追加された新しい機能フラグの説明については、そのリリースの 「`CHANGELOG`」を参照してください。

## v1 の動作に戻す
<a name="featureflags-disabling"></a>

CDK v2 では、v1 と比較して、一部の機能フラグのデフォルト値が変更されています。これらの値を `false` に設定すると、特定の AWS CDK v1 の動作に戻すことができます。これらのフラグが必要かどうかを確認するには、`cdk diff` コマンドを使用して、合成されたテンプレートへの変更を調べます。

 `@aws-cdk/core:newStyleStackSynthesis`   
既知の名前を持つブートストラップリソースを前提とする、新しいスタック合成方式を使用します。[最新のブートストラップ](bootstrapping.md)が必要になりますが、その代わりに、[CDK Pipelines](cdk-pipeline.md) を介した CI/CD や、クロスアカウントデプロイをすぐに利用できるようになります。

 `@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId`   
アプリケーションが複数の Amazon API Gateway API キーを使用し、それらを使用プランに関連付けている場合。

 `@aws-cdk/aws-rds:lowercaseDbIdentifier`   
アプリケーションが Amazon RDS データベースインスタンスまたはデータベースクラスターを使用し、それらの識別子を明示的に指定している場合。

 `@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021`   
アプリケーションが Amazon CloudFront ディストリビューションで TLS\$1V1\$12\$12019 セキュリティポリシーを使用している場合。CDK v2 は、デフォルトでセキュリティポリシー TLSv1.2\$12021 を使用します。

 `@aws-cdk/core:stackRelativeExports`   
アプリケーションが複数のスタックを使用し、あるスタックのリソースを別のスタックで参照する場合、AWS CloudFormation エクスポートを構築する際に、絶対パスと相対パスのどちらを使用するかを決定します。

 `@aws-cdk/aws-lambda:recognizeVersionProps`   
`false` に設定すると、CDK は、Lambda 関数の変更の有無を検出する際に、メタデータを検出対象に含めるようになります。メタデータのみが変更された場合、重複するバージョンは許可されないため、デプロイが失敗する可能性があります。アプリケーション内のすべての Lambda 関数に少なくとも 1 つの変更を加えている場合、このフラグを元に戻す必要はありません。

`cdk.json` でこれらのフラグを元に戻すための構文を、以下に示します。

```
{
  "context": {
    "@aws-cdk/core:newStyleStackSynthesis": false,
    "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false,
    "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": false,
    "@aws-cdk/aws-rds:lowercaseDbIdentifier": false,
    "@aws-cdk/core:stackRelativeExports": false,
    "@aws-cdk/aws-lambda:recognizeVersionProps": false
  }
}
```

# 側面と AWS CDK
<a name="aspects"></a>

アスペクトは、特定のスコープ内のすべてのコンストラクトに操作を適用する方法です。このアスペクトでは、タグの追加などによってコンストラクトを変更できます。または、すべてのバケットが暗号化されていることを確認するなど、コンストラクトの状態について何かを検証することもできます。

1 つのコンストラクトおよび同じスコープ内のすべてのコンストラクトにアスペクトを適用するには、以下の例に示すように、新しいアスペクトで ` [Aspects](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Aspects.html#static-ofscope).of(<SCOPE>).add()` を呼び出します。

**Example**  

```
Aspects.of(myConstruct).add(new SomeAspect(...));
```

```
Aspects.of(myConstruct).add(new SomeAspect(...));
```

```
Aspects.of(my_construct).add(SomeAspect(...))
```

```
Aspects.of(myConstruct).add(new SomeAspect(...));
```

```
Aspects.Of(myConstruct).add(new SomeAspect(...));
```

```
awscdk.Aspects_Of(stack).Add(awscdk.NewTag(...))
```

 AWS CDK は側面を使用して[リソースにタグ](tagging.md)を付けますが、フレームワークは他の目的でも使用できます。たとえば、これを使用して、高レベルのコンストラクトで定義されている AWS CloudFormation リソースを検証または変更できます。

## 側面とミクシン
<a name="aspects-vs-mixins"></a>

アスペクトと[ミクシン](mixins.md)はどちらもコンストラクトを変更しますが、いつどのように適用されるかは異なります。


| 機能 | アスペクト | 混合 | 
| --- | --- | --- | 
|   **適用時**   |  合成中、他のすべてのコードが実行された後。  |  `.with()` が呼び出された直後。  | 
|   **スコープ**   |  後で追加されたコンストラクトを含む、特定のスコープ内のすべてのコンストラクト。  |  明示的に適用するコンストラクトのみ。  | 
|   **[Style]** (スタイル)   |  宣言型 — ルールを設定し、CDK が適用します。  |  Imperative — 適用する対象と場所を選択します。  | 
|   **最適な用途**   |  検証、コンプライアンス、タグ付け、広範なポリシー。  |  個々のリソースに特定の機能を追加します。  | 

アプリケーション全体にルールを適用する場合や、コンストラクトが特定の基準を満たしていることを検証する場合は、アスペクトを使用します。特定のコンストラクトに特定の機能を追加する場合は、Mixins を使用します。

アスペクトとミクシンは一緒に使用できます。たとえば、Mixins を使用して個々のリソースとアスペクトを設定し、スタック内のすべてのリソースが組織のセキュリティ要件を満たしていることを検証できます。

## アスペクトの詳細
<a name="aspects-detail"></a>

アスペクトは[訪問者パターン](https://en.wikipedia.org/wiki/Visitor_pattern)を使用します。アスペクトは、以下のインターフェイスを実装するクラスです。

**Example**  

```
interface IAspect {
   visit(node: IConstruct): void;}
```
JavaScript には、言語機能としてのインターフェイスはありません。したがって、アスペクトは、運用されるノードを受け入れる `visit` メソッドを持つクラスのインスタンスです。
Python には言語機能としてのインターフェイスはありません。したがって、アスペクトは、運用されるノードを受け入れる `visit` メソッドを持つクラスのインスタンスです。

```
public interface IAspect {
    public void visit(Construct node);
}
```

```
public interface IAspect
{
    void Visit(IConstruct node);
}
```

```
type IAspect interface {
  Visit(node constructs.IConstruct)
}
```

`Aspects.of(<SCOPE>).add(…​)` を呼び出すと、コンストラクトはアスペクトの内部リストにアスペクトを追加します。`Aspects.of(<SCOPE>)` でリストを取得できます。

[準備フェーズ](deploy.md#deploy-how-synth-app)中、 AWS CDK はコンストラクトとその各子の オブジェクトの `visit`メソッドをトップダウンの順序で呼び出します。

`visit` メソッドは、コンストラクト内の任意の要素を自由に変更できます。強く型付けされた言語では、受信したコンストラクトをより具体的な型にキャストしてから、コンストラクト固有のプロパティやメソッドにアクセスします。

`Stages` は定義後は自己完結型で不変であるため、アスペクトは `Stage` コンストラクトの境界を越えては伝播しません。`Stage` 内のコンストラクトを訪問する場合は、`Stage` コンストラクト自体 (またはそれ以下) にアスペクトを適用します。

## 例
<a name="aspects-example"></a>

以下の例では、スタックで作成されたすべてのバケットでバージョニングが有効になっていることを検証します。このアスペクトは、検証に失敗したコンストラクトにエラー注釈を追加します。これにより、`synth` 操作が失敗し、結果として生成されたクラウドアセンブリのデプロイが防止されます。

**Example**  

```
class BucketVersioningChecker implements IAspect {
  public visit(node: IConstruct): void {
    // See that we're dealing with a CfnBucket
    if (node instanceof s3.CfnBucket) {

      // Check for versioning property, exclude the case where the property
      // can be a token (IResolvable).
      if (!node.versioningConfiguration
        || (!Tokenization.isResolvable(node.versioningConfiguration)
            && node.versioningConfiguration.status !== 'Enabled')) {
        Annotations.of(node).addError('Bucket versioning is not enabled');
      }
    }
  }
}

// Later, apply to the stack
Aspects.of(stack).add(new BucketVersioningChecker());
```

```
class BucketVersioningChecker {
   visit(node) {
    // See that we're dealing with a CfnBucket
    if ( node instanceof s3.CfnBucket) {

      // Check for versioning property, exclude the case where the property
      // can be a token (IResolvable).
      if (!node.versioningConfiguration
        || !Tokenization.isResolvable(node.versioningConfiguration)
            && node.versioningConfiguration.status !== 'Enabled')) {
        Annotations.of(node).addError('Bucket versioning is not enabled');
      }
    }
  }
}

// Later, apply to the stack
Aspects.of(stack).add(new BucketVersioningChecker());
```

```
@jsii.implements(cdk.IAspect)
class BucketVersioningChecker:

  def visit(self, node):
    # See that we're dealing with a CfnBucket
    if isinstance(node, s3.CfnBucket):

      # Check for versioning property, exclude the case where the property
      # can be a token (IResolvable).
      if (not node.versioning_configuration or
              not Tokenization.is_resolvable(node.versioning_configuration)
                  and node.versioning_configuration.status != "Enabled"):
          Annotations.of(node).add_error('Bucket versioning is not enabled')

# Later, apply to the stack
Aspects.of(stack).add(BucketVersioningChecker())
```

```
public class BucketVersioningChecker implements IAspect
{
    @Override
    public void visit(Construct node)
    {
        // See that we're dealing with a CfnBucket
        if (node instanceof CfnBucket)
        {
            CfnBucket bucket = (CfnBucket)node;
            Object versioningConfiguration = bucket.getVersioningConfiguration();
            if (versioningConfiguration == null ||
                    !Tokenization.isResolvable(versioningConfiguration.toString()) &&
                    !versioningConfiguration.toString().contains("Enabled"))
                Annotations.of(bucket.getNode()).addError("Bucket versioning is not enabled");
        }
    }
}

// Later, apply to the stack
Aspects.of(stack).add(new BucketVersioningChecker());
```

```
class BucketVersioningChecker : Amazon.Jsii.Runtime.Deputy.DeputyBase, IAspect
{
    public void Visit(IConstruct node)
    {
        // See that we're dealing with a CfnBucket
        if (node is CfnBucket)
        {
            var bucket = (CfnBucket)node;
            if (bucket.VersioningConfiguration is null ||
                    !Tokenization.IsResolvable(bucket.VersioningConfiguration) &&
                    !bucket.VersioningConfiguration.ToString().Contains("Enabled"))
                Annotations.Of(bucket.Node).AddError("Bucket versioning is not enabled");
        }
    }
}

// Later, apply to the stack
Aspects.Of(stack).add(new BucketVersioningChecker());
```