Tokens e o AWS CDK - AWS Cloud Development Kit (AWS CDK) v2

Este é o Guia do Desenvolvedor AWS CDK v2. A versão CDK 1 mais antiga entrou em manutenção em 1º de junho de 2022 e encerrou o suporte em 1º de junho de 2023.

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Tokens e o AWS CDK

Os tokens representam valores que só podem ser resolvidos posteriormente no ciclo de vida do aplicativo. Por exemplo, o nome de um bucket do Amazon Simple Storage Service (Amazon S3) que você define no CDK seu aplicativo só é alocado quando AWS CloudFormation o modelo é sintetizado. Se você imprimir o bucket.bucketName atributo, que é uma string, verá que ele contém algo parecido com o seguinte:

${TOKEN[Bucket.Name.1234]}

É assim que ele AWS CDK codifica um token cujo valor ainda não é conhecido no momento da construção, mas estará disponível posteriormente. Eles AWS CDK chamam esses espaços reservados de tokens. Nesse caso, é um token codificado como uma string.

Você pode passar essa string como se fosse o nome do bucket. No exemplo a seguir, o nome do bucket é especificado como uma variável de ambiente para uma AWS Lambda função.

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

Quando o AWS CloudFormation modelo é finalmente sintetizado, o token é renderizado como intrínseco. AWS CloudFormation { "Ref": "MyBucket" } No momento da implantação, AWS CloudFormation substitui esse intrínseco pelo nome real do bucket que foi criado.

Tokens e codificações de tokens

Tokens são objetos que implementam a IResolvableinterface, que contém um único resolve método. O AWS CDK chama esse método durante a síntese para produzir o valor final para o AWS CloudFormation modelo. Os tokens participam do processo de síntese para produzir valores arbitrários de qualquer tipo.

nota

Você raramente trabalhará diretamente com a IResolvable interface. Provavelmente, você verá apenas versões codificadas por string dos tokens.

Outras funções normalmente aceitam apenas argumentos de tipos básicos, como string ounumber. Para usar tokens nesses casos, você pode codificá-los em um dos três tipos usando métodos estáticos na classe cdk.Token.

Eles pegam um valor arbitrário, que pode ser umIResolvable, e os codificam em um valor primitivo do tipo indicado.

Importante

Como qualquer um dos tipos anteriores pode ser potencialmente um token codificado, tenha cuidado ao analisar ou tentar ler seu conteúdo. Por exemplo, se você tentar analisar uma string para extrair um valor dela, e a string for um token codificado, sua análise falhará. Da mesma forma, se você tentar consultar o comprimento de uma matriz ou realizar operações matemáticas com um número, primeiro verifique se eles não são tokens codificados.

Para verificar se um valor tem um token não resolvido, chame o método Token.isUnresolved (Pythonis_unresolved:).

O exemplo a seguir confirma que um valor de string, que pode ser um token, não tem mais do que 10 caracteres.

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 o nome for um token, a validação não será executada e um erro ainda poderá ocorrer em um estágio posterior do ciclo de vida, como durante a implantação.

nota

Você pode usar codificações de token para escapar do sistema de tipos. Por exemplo, você pode codificar em string um token que produz um valor numérico no momento da síntese. Se você usar essas funções, é sua responsabilidade garantir que seu modelo seja resolvido para um estado utilizável após a síntese.

Tokens codificados por string

Os tokens codificados por string têm a seguinte aparência.

${TOKEN[Bucket.Name.1234]}

Eles podem ser transmitidos como cadeias de caracteres regulares e podem ser concatenados, conforme mostrado no exemplo a seguir.

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

Você também pode usar a interpolação de strings, se sua linguagem for compatível, conforme mostrado no exemplo a seguir.

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

Evite manipular a string de outras formas. Por exemplo, pegar uma substring de uma string provavelmente quebrará o token da string.

Tokens codificados em lista

Os tokens codificados em lista têm a seguinte aparência:

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

A única coisa segura a fazer com essas listas é passá-las diretamente para outras construções. Os tokens no formato de lista de strings não podem ser concatenados, nem um elemento pode ser retirado do token. A única maneira segura de manipulá-los é usando funções AWS CloudFormation intrínsecas como fn.Select.

Tokens codificados por números

Os tokens codificados por números são um conjunto de pequenos números negativos de ponto flutuante que se parecem com os seguintes.

-1.8881545897087626e+289

Assim como acontece com os tokens da lista, você não pode modificar o valor do número, pois isso provavelmente quebrará o token numérico. A única operação permitida é passar o valor para outra construção.

Valores preguiçosos

Além de representar valores de tempo de implantação, como AWS CloudFormation parâmetros, os tokens também são comumente usados para representar valores preguiçosos de tempo de síntese. Esses são valores para os quais o valor final será determinado antes da conclusão da síntese, mas não no ponto em que o valor é construído. Use tokens para passar uma string literal ou um valor numérico para outra construção, enquanto o valor real no momento da síntese pode depender de algum cálculo que ainda não foi feito.

Você pode criar tokens representando valores preguiçosos de tempo de sintetização usando métodos estáticos na Lazy classe, como lazy.String e lazy.Number. Esses métodos aceitam um objeto cuja produce propriedade é uma função que aceita um argumento de contexto e retorna o valor final quando chamada.

O exemplo a seguir cria um grupo de Auto Scaling cuja capacidade é determinada após sua criação.

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;

Convertendo para JSON

Às vezes, você deseja produzir uma JSON sequência de dados arbitrários e talvez não saiba se os dados contêm tokens. Para JSON codificar corretamente qualquer estrutura de dados, independentemente de ela conter tokens, use a pilha de métodos. toJsonString, conforme mostrado no exemplo a seguir.

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