これは 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 つのタイプのいずれかにエンコードできます。
これらは である任意の値を取り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
});