Token e AWS CDK - AWS Cloud Development Kit (AWS CDK) v2

Questa è la guida per sviluppatori AWS CDK v2. La versione precedente della CDK versione 1 è entrata in manutenzione il 1° giugno 2022 e ha terminato il supporto il 1° giugno 2023.

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Token e AWS CDK

I token rappresentano valori che possono essere risolti solo in un secondo momento nel ciclo di vita dell'app. Ad esempio, il nome di un bucket Amazon Simple Storage Service (Amazon S3) definito nell'app viene assegnato solo quando CDK il modello viene sintetizzato. AWS CloudFormation Se stampi l'bucket.bucketNameattributo, che è una stringa, vedrai che contiene qualcosa di simile al seguente:

${TOKEN[Bucket.Name.1234]}

Questo è il modo in cui AWS CDK codifica un token il cui valore non è ancora noto al momento della costruzione, ma sarà disponibile in seguito. AWS CDK Chiama questi segnaposto token. In questo caso, è un token codificato come stringa.

Puoi passare questa stringa come se fosse il nome del bucket. Nell'esempio seguente, il nome del bucket viene specificato come variabile di ambiente di una AWS Lambda funzione.

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

Quando il AWS CloudFormation modello viene finalmente sintetizzato, il token viene reso come intrinseco. AWS CloudFormation { "Ref": "amzn-s3-demo-bucket" } Al momento della distribuzione, AWS CloudFormation sostituisce questo elemento intrinseco con il nome effettivo del bucket che è stato creato.

Token e codifiche dei token

I token sono oggetti che implementano l'IResolvableinterfaccia, che contiene un unico metodo. resolve AWS CDK Chiama questo metodo durante la sintesi per produrre il valore finale per il AWS CloudFormation modello. I token partecipano al processo di sintesi per produrre valori arbitrari di qualsiasi tipo.

Nota

Raramente lavorerai direttamente con l'IResolvableinterfaccia. Molto probabilmente vedrai solo versioni di token con codifica a stringa.

Le altre funzioni in genere accettano solo argomenti di tipo base, come o. string number Per utilizzare i token in questi casi, potete codificarli in uno dei tre tipi utilizzando metodi statici sulla classe CDK.Token.

Questi prendono un valore arbitrario, che può essere unIResolvable, e li codificano in un valore primitivo del tipo indicato.

Importante

Poiché uno qualsiasi dei tipi precedenti può essere potenzialmente un token codificato, fai attenzione quando analizzi o provi a leggerne il contenuto. Ad esempio, se tenti di analizzare una stringa per estrarne un valore e la stringa è un token codificato, l'analisi fallisce. Analogamente, se si tenta di interrogare la lunghezza di un array o di eseguire operazioni matematiche con un numero, è necessario innanzitutto verificare che non si tratti di token codificati.

Per verificare se un valore contiene un token non risolto, chiamate il metodo Token.isUnresolved (Pythonis_unresolved:).

L'esempio seguente verifica che un valore di stringa, che potrebbe essere un token, non sia lungo più di 10 caratteri.

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

Se name è un token, la convalida non viene eseguita e potrebbe comunque verificarsi un errore in una fase successiva del ciclo di vita, ad esempio durante la distribuzione.

Nota

È possibile utilizzare le codifiche dei token per sfuggire al sistema di tipi. Ad esempio, potete codificare tramite stringa un token che produce un valore numerico al momento della sintesi. Se utilizzate queste funzioni, è vostra responsabilità assicurarvi che il modello si risolva in uno stato utilizzabile dopo la sintesi.

Token codificati in stringhe

I token con codifica in stringa hanno il seguente aspetto.

${TOKEN[Bucket.Name.1234]}

Possono essere passati in giro come normali stringhe e possono essere concatenati, come mostrato nell'esempio seguente.

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

È inoltre possibile utilizzare l'interpolazione di stringhe, se la lingua in uso la supporta, come illustrato nell'esempio seguente.

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

Evitate di manipolare la stringa in altri modi. Ad esempio, è probabile che l'acquisizione di una sottostringa di una stringa interrompa il token della stringa.

Token codificati in un elenco

I token con codifica a elenco hanno il seguente aspetto:

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

L'unica cosa sicura da fare con questi elenchi è passarli direttamente ad altri costrutti. I token in forma di elenco di stringhe non possono essere concatenati, né è possibile prelevare un elemento dal token. L'unico modo sicuro per manipolarli è utilizzare AWS CloudFormation funzioni intrinseche come fn.select.

Token con codifica numerica

I token con codifica numerica sono un insieme di minuscoli numeri negativi a virgola mobile che assomigliano ai seguenti.

-1.8881545897087626e+289

Come con i token di lista, non è possibile modificare il valore numerico, poiché così facendo si rischia di rompere il token numerico. L'unica operazione consentita è passare il valore a un altro costrutto.

Valori pigri

Oltre a rappresentare i valori del tempo di implementazione, come i AWS CloudFormation parametri, i token vengono comunemente utilizzati anche per rappresentare valori lazy in fase di sintesi. Si tratta di valori per i quali il valore finale verrà determinato prima del completamento della sintesi, ma non nel punto in cui viene costruito il valore. Utilizzate i token per passare una stringa letterale o un valore numerico a un altro costrutto, mentre il valore effettivo al momento della sintesi potrebbe dipendere da alcuni calcoli che devono ancora essere eseguiti.

Potete costruire token che rappresentano valori lazy in fase di sintetizzazione utilizzando metodi statici sulla classe, come lazy.String e Lazy.Number. Lazy Questi metodi accettano un oggetto la cui produce proprietà è una funzione che accetta un argomento di contesto e restituisce il valore finale quando viene chiamata.

L'esempio seguente crea un gruppo Auto Scaling la cui capacità viene determinata dopo la sua creazione.

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;

Conversione in JSON

A volte si desidera produrre una JSON stringa di dati arbitrari e non si può sapere se i dati contengono token. Per JSON codificare correttamente qualsiasi struttura di dati, indipendentemente dal fatto che contenga token, usa lo stack dei metodi. toJsonString, come illustrato nell'esempio seguente.

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