トークンと AWS CDK - AWS Cloud Development Kit (AWS CDK) v2

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

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

トークンと AWS CDK

トークンは、アプリケーションライフサイクル で後でしか解決できない値を表します。例えば、CDKアプリケーションで定義した Amazon Simple Storage Service (Amazon S3) バケットの名前は、 AWS CloudFormation テンプレートが合成された場合にのみ割り当てられます。文字列である bucket.bucketName 属性を出力すると、次のようなものが含まれていることがわかります。

${TOKEN[Bucket.Name.1234]}

これは、 がトークンを AWS CDK エンコードする方法であり、その値は構築時にはまだ知られていませんが、後で利用可能になります。は、これらのプレースホルダートークンを AWS CDK 呼び出します。 この場合、これは文字列としてエンコードされたトークンです。

この文字列は、バケットの名前であるかのように渡すことができます。次の例では、バケット名は AWS Lambda 関数の環境変数として指定されています。

TypeScript
const bucket = new s3.Bucket(this, 'MyBucket'); const fn = new lambda.Function(stack, 'MyLambda', { // ... environment: { BUCKET_NAME: bucket.bucketName, } });
JavaScript
const bucket = new s3.Bucket(this, 'MyBucket'); const fn = new lambda.Function(stack, 'MyLambda', { // ... environment: { BUCKET_NAME: bucket.bucketName } });
Python
bucket = s3.Bucket(self, "MyBucket") fn = lambda_.Function(stack, "MyLambda", environment=dict(BUCKET_NAME=bucket.bucket_name))
Java
final Bucket bucket = new Bucket(this, "MyBucket"); Function fn = Function.Builder.create(this, "MyLambda") .environment(java.util.Map.of( // Map.of requires Java 9+ "BUCKET_NAME", bucket.getBucketName())) .build();
C#
var bucket = new s3.Bucket(this, "MyBucket"); var fn = new Function(this, "MyLambda", new FunctionProps { Environment = new Dictionary<string, string> { ["BUCKET_NAME"] = bucket.BucketName } });

AWS CloudFormation テンプレートが最後に合成されると、トークンは AWS CloudFormation 組み込み としてレンダリングされます{ "Ref": "MyBucket" }。デプロイ時に、 はこの組み込み を、作成されたバケットの実際の名前 AWS CloudFormation に置き換えます。

トークンとトークンエンコーディング

トークンはIResolvable、インターフェイスを実装するオブジェクトで、単一のresolveメソッドが含まれています。は、合成中にこのメソッドを AWS CDK AWS CloudFormation 呼び出して、テンプレートの最終値を生成します。トークンは合成プロセスに参加し、任意のタイプの値を生成します。

注記

IResolvable インターフェイスを直接操作することはめったにありません。ほとんどの場合、トークンの文字列エンコードされたバージョンのみが表示されます。

他の関数は通常、 stringや などの基本型の引数のみを受け入れますnumber。このような場合にトークンを使用するには、cdk.Token クラスで静的メソッドを使用して、トークンを 3 つのタイプのいずれかにエンコードできます。

  • Token.asString 文字列エンコーディングを生成する (またはトークンオブジェクト.toString()で を呼び出す)

  • Token.asList リストエンコーディングを生成するには

  • Token.asNumber 数値エンコーディングを生成するには

これらは である任意の値を取りIResolvable、指定されたタイプのプリミティブ値にエンコードします。

重要

前述のタイプのいずれかがエンコードされたトークンである可能性があるため、コンテンツを解析または読み込もうとするときは注意が必要です。例えば、文字列を解析してその文字列から値を抽出しようとし、その文字列がエンコードされたトークンである場合、解析は失敗します。同様に、配列の長さをクエリしたり、数値で数学演算を実行したりする場合は、まずそれらがエンコードされたトークンではないことを確認する必要があります。

値に未解決のトークンが含まれているかどうかを確認するには、 Token.isUnresolved (Python: is_unresolved) メソッドを呼び出します。

次の例では、トークンである可能性のある文字列値が 10 文字以下であることを検証します。

TypeScript
if (!Token.isUnresolved(name) && name.length > 10) { throw new Error(`Maximum length for name is 10 characters`); }
JavaScript
if ( !Token.isUnresolved(name) && name.length > 10) { throw ( new Error(`Maximum length for name is 10 characters`)); }
Python
if not Token.is_unresolved(name) and len(name) > 10: raise ValueError("Maximum length for name is 10 characters")
Java
if (!Token.isUnresolved(name) && name.length() > 10) throw new IllegalArgumentException("Maximum length for name is 10 characters");
C#
if (!Token.IsUnresolved(name) && name.Length > 10) throw new ArgumentException("Maximum length for name is 10 characters");

name がトークンの場合、検証は実行されず、デプロイ中など、ライフサイクルの後の段階でエラーが発生する可能性があります。

注記

トークンエンコーディングを使用して、タイプシステムをエスケープできます。例えば、合成時に数値を生成するトークンを文字列エンコードできます。これらの関数を使用する場合は、合成後にテンプレートが使用可能な状態に解決されるようにする責任があります。

文字列エンコードされたトークン

文字列エンコードされたトークンは次のようになります。

${TOKEN[Bucket.Name.1234]}

次の例に示すように、通常の文字列のように渡したり、連結したりできます。

TypeScript
const functionName = bucket.bucketName + 'Function';
JavaScript
const functionName = bucket.bucketName + 'Function';
Python
function_name = bucket.bucket_name + "Function"
Java
String functionName = bucket.getBucketName().concat("Function");
C#
string functionName = bucket.BucketName + "Function";

次の例に示すように、言語が文字列補間をサポートしている場合は、文字列補間を使用することもできます。

TypeScript
const functionName = `${bucket.bucketName}Function`;
JavaScript
const functionName = `${bucket.bucketName}Function`;
Python
function_name = f"{bucket.bucket_name}Function"
Java
String functionName = String.format("%sFunction". bucket.getBucketName());
C#
string functionName = $"${bucket.bucketName}Function";

文字列を他の方法で操作することは避けてください。例えば、文字列の部分文字列を取ると、文字列トークンが破損する可能性があります。

リストエンコードされたトークン

リストエンコードされたトークンは次のようになります。

["#{TOKEN[Stack.NotificationArns.1234]}"]

これらのリストと関係する唯一の安全なことは、それらを他のコンストラクトに直接渡すことです。文字列リスト形式のトークンは連結できず、トークンから要素を取得することもできません。これらを操作する唯一の安全な方法は、Fn.select などの AWS CloudFormation 組み込み関数を使用することです。

数値エンコードされたトークン

数値エンコードされたトークンは、次のような小さな負の浮動小数点数のセットです。

-1.8881545897087626e+289

リストトークンと同様に、数値値は変更できません。変更すると、数値トークンが破損する可能性があります。許可される唯一のオペレーションは、値を別のコンストラクトに渡すことです。

遅延値

トークンは、 AWS CloudFormation パラメータ などのデプロイ時の値を表すだけでなく、合成時の遅延値を表すためにも一般的に使用されます。これらは、合成が完了する前に最終値が決定される値ですが、値が構築される時点では決定されません。トークンを使用してリテラル文字列または数値を別のコンストラクトに渡しますが、合成時の実際の値は、まだ発生していない計算に依存する場合があります。

Lazy.string や Lazy.number などのLazyクラスの静的メソッドを使用して、同期時間の遅延値を表すトークンを作成できます。これらのメソッドは、 produceプロパティがコンテキスト引数を受け入れる関数であるオブジェクトを受け入れ、呼び出されたときに最終値を返します。

次の例では、作成後に容量が決定される Auto Scaling グループを作成します。

TypeScript
let actualValue: number; new AutoScalingGroup(this, 'Group', { desiredCapacity: Lazy.numberValue({ produce(context) { return actualValue; } }) }); // At some later point actualValue = 10;
JavaScript
let actualValue; new AutoScalingGroup(this, 'Group', { desiredCapacity: Lazy.numberValue({ produce(context) { return (actualValue); } }) }); // At some later point actualValue = 10;
Python
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
Java
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;
C#
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

場合によっては、任意のデータのJSON文字列を生成し、データにトークンが含まれているかどうかわからないことがあります。トークンが含まれているかどうかにかかわらず、データ構造を適切にJSONエンコードするには、次の例に示すように、 メソッドスタックtoJsonStringを使用します。

TypeScript
const stack = Stack.of(this); const str = stack.toJsonString({ value: bucket.bucketName });
JavaScript
const stack = Stack.of(this); const str = stack.toJsonString({ value: bucket.bucketName });
Python
stack = Stack.of(self) string = stack.to_json_string(dict(value=bucket.bucket_name))
Java
Stack stack = Stack.of(this); String stringVal = stack.toJsonString(java.util.Map.of( // Map.of requires Java 9+ put("value", bucket.getBucketName())));
C#
var stack = Stack.Of(this); var stringVal = stack.ToJsonString(new Dictionary<string, string> { ["value"] = bucket.BucketName });