Tokens - AWS Cloud Development Kit (AWS CDK) v2

Esta es la guía para AWS CDK desarrolladores de la versión 2. La versión anterior del CDK v1 entró en mantenimiento el 1 de junio de 2022 y dejó de ofrecer soporte el 1 de junio de 2023.

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Tokens

Los tokens representan valores que solo se pueden resolver en un momento posterior del ciclo de vida de la aplicación. Por ejemplo, el nombre de un depósito de Amazon Simple Storage Service (Amazon S3) que defina en su aplicación de CDK solo se asigna cuando se sintetiza AWS CloudFormation la plantilla. Si imprime el bucket.bucketName atributo, que es una cadena, verá que contiene algo parecido a lo siguiente:

${TOKEN[Bucket.Name.1234]}

Así es como AWS CDK codifica un token cuyo valor aún no se conoce en el momento de la construcción, pero que estará disponible más adelante. A estos marcadores de posición los AWS CDK llaman «fichas». En este caso, es un token codificado como una cadena.

Puedes pasar esta cadena como si fuera el nombre del depósito. En el siguiente ejemplo, el nombre del depósito se especifica como una variable de entorno para una AWS Lambda función.

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

Cuando finalmente se sintetiza la AWS CloudFormation plantilla, el token se representa como AWS CloudFormation intrínseco{ "Ref": "MyBucket" }. En el momento de la implementación, AWS CloudFormation reemplaza este elemento intrínseco por el nombre real del depósito que se creó.

Tokens y codificaciones de tokens

Los tokens son objetos que implementan la interfaz IRresolvable, que contiene un único método. resolve Utiliza AWS CDK este método durante la síntesis para obtener el valor final de la plantilla. AWS CloudFormation Los tokens participan en el proceso de síntesis para producir valores arbitrarios de cualquier tipo.

nota

Rara vez trabajarás directamente con la IResolvable interfaz. Lo más probable es que solo veas versiones de los tokens codificadas en cadenas.

Por lo general, otras funciones solo aceptan argumentos de tipos básicos, como string o. number Para usar los tokens en estos casos, puedes codificarlos en uno de los tres tipos mediante métodos estáticos de la clase CDK.Token.

  • Token.asStringpara generar una codificación de cadena (o invocar .toString() el objeto token)

  • Token.asListpara generar una codificación de lista

  • Token.asNumberpara generar una codificación numérica

Estos toman un valor arbitrario, que puede ser unIResolvable, y lo codifican en un valor primitivo del tipo indicado.

importante

Como cualquiera de los tipos anteriores puede ser un token codificado, tenga cuidado al analizar o intentar leer su contenido. Por ejemplo, si intentas analizar una cadena para extraer un valor de ella y la cadena es un token codificado, el análisis no se realizará correctamente. Del mismo modo, si intentas consultar la longitud de una matriz o realizar operaciones matemáticas con un número, primero debes comprobar que no son símbolos codificados.

Para comprobar si un valor contiene un token sin resolver, llama al método Token.isUnresolved (Python:is_unresolved).

El siguiente ejemplo valida que un valor de cadena, que podría ser un token, no supere los 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");

Si el nombre es un token, no se realiza la validación y, aun así, podría producirse un error en una fase posterior del ciclo de vida, por ejemplo, durante la implementación.

nota

Puedes usar codificaciones por token para escapar del sistema de tipos. Por ejemplo, puede codificar en cadena un token que produzca un valor numérico en el momento de la síntesis. Si utilizas estas funciones, es tu responsabilidad asegurarte de que la plantilla se resuelva a un estado utilizable después de la síntesis.

Tokens codificados en cadenas

Los tokens codificados en cadenas tienen el siguiente aspecto.

${TOKEN[Bucket.Name.1234]}

Se pueden transmitir como cadenas normales y se pueden concatenar, como se muestra en el siguiente ejemplo.

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

También puede utilizar la interpolación de cadenas, si su idioma la admite, como se muestra en el siguiente ejemplo.

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 la cadena de otras formas. Por ejemplo, si se toma una subcadena de una cadena, es probable que se rompa el símbolo de la cadena.

Tokens codificados en forma de lista

Los tokens codificados en forma de lista tienen el siguiente aspecto:

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

Lo único seguro que se puede hacer con estas listas es pasarlas directamente a otras construcciones. Los tokens en forma de lista de cadenas no se pueden concatenar ni se puede extraer ningún elemento del token. La única forma segura de manipularlos es mediante el uso de funciones AWS CloudFormation intrínsecas como fn.Select.

Tokens codificados con números

Los símbolos codificados con números son un conjunto de pequeños números negativos de punto flotante que tienen el siguiente aspecto.

-1.8881545897087626e+289

Al igual que ocurre con los símbolos de lista, no se puede modificar el valor numérico, ya que es probable que se rompa el identificador numérico. La única operación permitida es transferir el valor a otra construcción.

Valores perezosos

Además de representar los valores del tiempo de despliegue, como los AWS CloudFormation parámetros, los tokens también se utilizan habitualmente para representar los valores perezosos del tiempo de síntesis. Estos son valores para los que el valor final se determinará antes de que se complete la síntesis, pero no en el punto en el que se construye el valor. Utilice símbolos para pasar un valor numérico o de cadena literal a otra construcción, mientras que el valor real en el momento de la síntesis puede depender de algún cálculo que aún no se haya realizado.

Puedes construir fichas que representen valores perezosos en el tiempo de síntesis utilizando los métodos estáticos de la Lazy clase, como Lazy.String y Lazy.Number. Estos métodos aceptan un objeto cuya produce propiedad es una función que acepta un argumento de contexto y devuelve el valor final cuando se llama.

El siguiente ejemplo crea un grupo de Auto Scaling cuya capacidad se determina después de su creación.

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;

Conversión a JSON

A veces, desea generar una cadena JSON de datos arbitrarios y es posible que no sepa si los datos contienen símbolos. Para codificar correctamente en JSON cualquier estructura de datos, independientemente de si contiene o no tokens, utilice la pila de métodos. toJsonString, como se muestra en el siguiente ejemplo.

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