Les jetons et le AWS CDK - AWS Cloud Development Kit (AWS CDK) v2

Ceci est le guide du AWS CDK développeur de la version 2. L'ancienne CDK version 1 est entrée en maintenance le 1er juin 2022 et a pris fin le 1er juin 2023.

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Les jetons et le AWS CDK

Les jetons représentent des valeurs qui ne peuvent être résolues que plus tard dans le cycle de vie de l'application. Par exemple, le nom d'un bucket Amazon Simple Storage Service (Amazon S3) que vous définissez dans CDK votre application n'est attribué que lorsque AWS CloudFormation le modèle est synthétisé. Si vous imprimez l'bucket.bucketNameattribut, qui est une chaîne, vous verrez qu'il contient quelque chose comme ceci :

${TOKEN[Bucket.Name.1234]}

C'est ainsi que l'on AWS CDK code un jeton dont la valeur n'est pas encore connue au moment de la construction, mais qui sera disponible ultérieurement. Ils AWS CDK appellent ces placeholders des jetons. Dans ce cas, il s'agit d'un jeton codé sous forme de chaîne.

Vous pouvez transmettre cette chaîne comme s'il s'agissait du nom du bucket. Dans l'exemple suivant, le nom du compartiment est spécifié en tant que variable d'environnement pour une AWS Lambda fonction.

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

Lorsque le AWS CloudFormation modèle est finalement synthétisé, le jeton est rendu en tant qu' AWS CloudFormation intrinsèque{ "Ref": "MyBucket" }. Au moment du déploiement, AWS CloudFormation remplace ce nom intrinsèque par le nom réel du bucket créé.

Jetons et encodages de jetons

Les jetons sont des objets qui implémentent l'IResolvableinterface, qui contient une resolve méthode unique. Il AWS CDK appelle cette méthode pendant la synthèse pour produire la valeur finale du AWS CloudFormation modèle. Les jetons participent au processus de synthèse pour produire des valeurs arbitraires de tout type.

Note

Il est rare que vous travailliez directement avec l'IResolvableinterface. Vous ne verrez probablement que des versions de jetons codées par chaîne.

Les autres fonctions n'acceptent généralement que des arguments de type basique, tels que string ounumber. Pour utiliser des jetons dans ces cas, vous pouvez les encoder dans l'un des trois types suivants en utilisant des méthodes statiques sur la classe CDK.Token.

Ils prennent une valeur arbitraire, qui peut être unIResolvable, et les encodent en une valeur primitive du type indiqué.

Important

Étant donné que l'un des types précédents peut potentiellement être un jeton codé, soyez prudent lorsque vous analysez ou essayez de lire leur contenu. Par exemple, si vous essayez d'analyser une chaîne pour en extraire une valeur et que la chaîne est un jeton codé, votre analyse échoue. De même, si vous essayez d'interroger la longueur d'un tableau ou d'effectuer des opérations mathématiques avec un nombre, vous devez d'abord vérifier qu'il ne s'agit pas de jetons codés.

Pour vérifier si une valeur contient un jeton non résolu, appelez la méthode Token.isUnresolved (Python :is_unresolved).

L'exemple suivant confirme qu'une valeur de chaîne, qui peut être un jeton, ne comporte pas plus de 10 caractères.

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 le nom est un jeton, la validation n'est pas effectuée et une erreur peut encore se produire à un stade ultérieur du cycle de vie, par exemple lors du déploiement.

Note

Vous pouvez utiliser des codages de jetons pour échapper au système de types. Par exemple, vous pouvez coder en chaîne un jeton qui produit une valeur numérique au moment de la synthèse. Si vous utilisez ces fonctions, il est de votre responsabilité de vous assurer que votre modèle passe à un état utilisable après la synthèse.

Jetons codés par chaîne

Les jetons codés par chaîne ressemblent à ce qui suit.

${TOKEN[Bucket.Name.1234]}

Ils peuvent être transmis comme des chaînes ordinaires et peuvent être concaténés, comme le montre l'exemple suivant.

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

Vous pouvez également utiliser l'interpolation de chaînes, si votre langue le permet, comme indiqué dans l'exemple suivant.

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

Évitez de manipuler la chaîne d'une autre manière. Par exemple, la prise d'une sous-chaîne d'une chaîne risque de casser le jeton de chaîne.

Jetons codés sous forme de liste

Les jetons codés sous forme de liste ressemblent à ce qui suit :

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

La seule chose sûre à faire avec ces listes est de les transmettre directement à d'autres constructions. Les jetons sous forme de liste de chaînes ne peuvent pas être concaténés, et aucun élément ne peut être extrait du jeton. Le seul moyen sûr de les manipuler est d'utiliser des fonctions AWS CloudFormation intrinsèques telles que FN.select.

Jetons numérotés

Les jetons codés par des nombres sont un ensemble de minuscules nombres négatifs à virgule flottante qui ressemblent à ce qui suit.

-1.8881545897087626e+289

Comme pour les jetons de liste, vous ne pouvez pas modifier la valeur numérique, car cela risque de casser le jeton numérique. La seule opération autorisée est de transmettre la valeur à une autre construction.

Valeurs paresseuses

En plus de représenter les valeurs de temps de déploiement, telles que les AWS CloudFormation paramètres, les jetons sont également couramment utilisés pour représenter les valeurs latentes au moment de la synthèse. Il s'agit de valeurs pour lesquelles la valeur finale sera déterminée avant la fin de la synthèse, mais pas au moment où la valeur est construite. Utilisez des jetons pour transmettre une chaîne littérale ou une valeur numérique à une autre construction, tandis que la valeur réelle au moment de la synthèse peut dépendre d'un calcul qui n'a pas encore été effectué.

Vous pouvez créer des jetons représentant des valeurs latentes au moment de la synthèse à l'aide de méthodes statiques appliquées à la Lazy classe, telles que Lazy.String et Lazy.Number. Ces méthodes acceptent un objet dont la produce propriété est une fonction qui accepte un argument de contexte et renvoie la valeur finale lorsqu'elle est appelée.

L'exemple suivant crée un groupe Auto Scaling dont la capacité est déterminée après sa création.

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;

Conversion en JSON

Parfois, vous souhaitez produire une JSON chaîne de données arbitraires, sans savoir si les données contiennent des jetons. Pour encoder correctement JSON n'importe quelle structure de données, qu'elle contienne ou non des jetons, utilisez la pile de méthodes. toJsonString, comme le montre l'exemple suivant.

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