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

これは AWS CDK v2 デベロッパーガイドです。古い v1 CDK は 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, 'amzn-s3-demo-bucket'); const fn = new lambda.Function(stack, 'MyLambda', { // ... environment: { BUCKET_NAME: bucket.bucketName, } });
JavaScript
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket'); const fn = new lambda.Function(stack, 'MyLambda', { // ... environment: { BUCKET_NAME: bucket.bucketName } });
Python
bucket = s3.Bucket(self, "amzn-s3-demo-bucket") fn = lambda_.Function(stack, "MyLambda", environment=dict(BUCKET_NAME=bucket.bucket_name))
Java
final Bucket bucket = new Bucket(this, "amzn-s3-demo-bucket"); 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, "amzn-s3-demo-bucket"); var fn = new Function(this, "MyLambda", new FunctionProps { Environment = new Dictionary<string, string> { ["BUCKET_NAME"] = bucket.BucketName } });

AWS CloudFormation テンプレートが最終的に合成されると、トークンは AWS CloudFormation 組み込み としてレンダリングされます{ "Ref": "amzn-s3-demo-bucket" }。デプロイ時に、この組み込みを、作成されたバケットの実際の名前 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 });