

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

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

# コンテキスト値と 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"
    ]
  }
}
```