Ceci est le guide du AWS CDK développeur de la version 2. L'ancien CDK v1 est entré 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.
Dans le AWS Cloud Development Kit (AWS CDK), les jetons sont des espaces réservés pour des valeurs inconnues lors de la définition de constructions ou de la synthèse de piles. Ces valeurs seront entièrement résolues lors du déploiement, lorsque votre infrastructure réelle sera créée. Lorsque vous AWS CDK développez des applications, vous utiliserez des jetons pour gérer ces valeurs dans l'ensemble de votre application.
Exemple de jeton
Voici un exemple de pile CDK qui définit une structure pour un bucket Amazon Simple Storage Service (Amazon S3). Le nom de notre bucket n'étant pas encore connu, la valeur de bucketName
est stockée sous forme de jeton :
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
export class CdkDemoAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Define an S3 bucket
const myBucket = new s3.Bucket(this, 'myBucket');
// Store value of the S3 bucket name
const myBucketName = myBucket.bucketName;
// Print the current value for the S3 bucket name at synthesis
console.log("myBucketName: " + bucketName);
}
}
Lorsque nous exécutons cdk synth
la synthèse de notre pile, la valeur de myBucketName
sera affichée au format jeton de${Token[TOKEN.
. Ce format de jeton est le résultat de la façon dont les jetons AWS CDK sont codés. Dans cet exemple, le jeton est codé sous forme de chaîne :1234
]}
$
cdk synth --quiet
myBucketName: ${Token[TOKEN.21
]}
Comme la valeur du nom de notre bucket n'est pas connue lors de la synthèse, le jeton est rendu sous la formemyBucket
. Notre AWS CloudFormation modèle utilise la fonction <unique-hash>
Ref
intrinsèque pour référencer sa valeur, qui sera connue lors du déploiement :
Resources:
myBucket5AF9C99B
:
# ...
Outputs:
bucketNameOutput:
Description: The name of the S3 bucket
Value:
Ref: myBucket5AF9C99B
Pour plus d'informations sur la façon dont le hachage unique est généré, consultezLogique générée IDs dans votre AWS CloudFormation modèle.
Passer des jetons
Les jetons peuvent être transmis comme s'ils étaient la valeur réelle qu'ils représentent. Voici un exemple qui transmet le jeton du nom de notre bucket à la construction d'une AWS Lambda fonction :
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as lambda from 'aws-cdk-lib/aws-lambda';
export class CdkDemoAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Define an S3 bucket
const myBucket = new s3.Bucket(this, 'myBucket');
// ...
// Define a Lambda function
const myFunction = new lambda.Function(this, "myFunction", {
runtime: lambda.Runtime.NODEJS_20_X,
handler: "index.handler",
code: lambda.Code.fromInline(`
exports.handler = async function(event) {
return {
statusCode: 200,
body: JSON.stringify('Hello World!'),
};
};
`),
functionName: myBucketName + "Function", // Pass token for the S3 bucket name
environment: {
BUCKET_NAME: myBucketName, // Pass token for the S3 bucket name
}
});
}
}
Lorsque nous synthétisons notre modèle, les fonctions Fn::Join
intrinsèques Ref
et sont utilisées pour spécifier les valeurs, qui seront connues lors du déploiement :
Resources:
myBucket5AF9C99B
:
Type: AWS::S3::Bucket
# ...
myFunction884E1557
:
Type: AWS::Lambda::Function
Properties:
# ...
Environment:
Variables:
BUCKET_NAME:
Ref: myBucket5AF9C99B
FunctionName:
Fn::Join:
- ""
- - Ref: myBucket5AF9C99B
- Function
# ...
Comment fonctionnent les codages de jetons
Les jetons sont des objets qui implémentent l'IResolvable
interface, qui contient une resolve
méthode unique. Lors de la synthèse, AWS CDK cette méthode est appelée pour produire la valeur finale des jetons dans votre CloudFormation modèle.
Note
Vous travaillerez rarement directement avec l'IResolvable
interface. Vous ne verrez probablement que des versions de jetons codées par chaîne.
Types de codage de jetons
Les jetons participent au processus de synthèse pour produire des valeurs arbitraires de tout type. 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 cdk.Token
classe.
-
Token.asString
pour générer un codage de chaîne (ou appeler.toString()
l'objet jeton). -
Token.asList
pour générer un codage de liste. -
Token.asNumber
pour générer un codage numérique.
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.
Comment vérifier la présence de jetons dans votre application
Pour vérifier si une valeur contient un jeton non résolu, appelez la méthode Token.isUnresolved
(Python :is_unresolved
). Voici un exemple qui vérifie si la valeur de notre nom de compartiment Amazon S3 est un jeton. S'il ne s'agit pas d'un jeton, nous validons ensuite la longueur du nom du bucket :
// ...
export class CdkDemoAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Define an S3 bucket
const myBucket = new s3.Bucket(this, 'myBucket');
// ...
// Check if bucket name is a token. If not, check if length is less than 10 characters
if (cdk.Token.isUnresolved(myBucketName)) {
console.log("Token identified.");
} else if (!cdk.Token.isUnresolved(myBucketName) && myBucketName.length > 10) {
throw new Error('Maximum length for name is 10 characters.');
};
// ...
Lorsque nous exécutonscdk synth
, myBucketName
est identifié comme un jeton :
$
cdk synth --quiet
Token identified.
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.
Utilisation de jetons codés par chaîne
Les jetons codés par chaîne ressemblent à ce qui suit.
${TOKEN[Bucket.Name.1234]}
Elles peuvent être transmises comme des chaînes ordinaires et peuvent être concaténées, comme le montre l'exemple suivant.
const functionName = bucket.bucketName + 'Function';
Vous pouvez également utiliser l'interpolation de chaînes, si votre langue le permet, comme illustré dans l'exemple suivant.
const 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.
Utilisation de 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.
Utilisation de 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.
Voici un exemple de construction contenant un jeton codé sous forme de nombre :
import { Stack, Duration, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as rds from 'aws-cdk-lib/aws-rds';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
export class CdkDemoAppStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Define a new VPC
const vpc = new ec2.Vpc(this, 'MyVpc', {
maxAzs: 3, // Maximum number of availability zones to use
});
// Define an RDS database cluster
const dbCluster = new rds.DatabaseCluster(this, 'MyRDSCluster', {
engine: rds.DatabaseClusterEngine.AURORA,
instanceProps: {
vpc,
},
});
// Get the port token (this is a token encoded as a number)
const portToken = dbCluster.clusterEndpoint.port;
// Print the value for our token at synthesis
console.log("portToken: " + portToken);
}
}
Lorsque nous exécutonscdk synth
, la valeur de portToken
est affichée sous forme de jeton codé par un numéro :
$
cdk synth --quiet
portToken: -1.8881545897087968e+289
Passez des jetons codés
Lorsque vous transmettez des jetons codés par des nombres à d'autres constructions, il peut être judicieux de les convertir d'abord en chaînes. Par exemple, si vous souhaitez utiliser la valeur d'une chaîne codée par un nombre dans le cadre d'une chaîne concaténée, sa conversion améliore la lisibilité.
Dans l'exemple suivant, portToken
il s'agit d'un jeton codé par un nombre que nous voulons transmettre à notre fonction Lambda dans le cadre de : connectionString
import { Stack, Duration, CfnOutput, StackProps } from 'aws-cdk-lib';
// ...
import * as lambda from 'aws-cdk-lib/aws-lambda';
export class CdkDemoAppStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Define a new VPC
// ...
// Define an RDS database cluster
// ...
// Get the port token (this is a token encoded as a number)
const portToken = dbCluster.clusterEndpoint.port;
// ...
// Example connection string with the port token as a number
const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portToken}/mydatabase`;
// Use the connection string as an environment variable in a Lambda function
const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
runtime: lambda.Runtime.NODEJS_20_X,
handler: 'index.handler',
code: lambda.Code.fromInline(`
exports.handler = async function(event) {
return {
statusCode: 200,
body: JSON.stringify('Hello World!'),
};
};
`),
environment: {
DATABASE_CONNECTION_STRING: connectionString, // Using the port token as part of the string
},
});
// Output the value of our connection string at synthesis
console.log("connectionString: " + connectionString);
// Output the connection string
new CfnOutput(this, 'ConnectionString', {
value: connectionString,
});
}
}
Si nous transmettons cette valeur àconnectionString
, la valeur de sortie lors de l'exécution cdk synth
peut être source de confusion en raison de la chaîne codée par des nombres :
$
cdk synth --quiet
connectionString: jdbc:mysql://mydb.cluster.amazonaws.com:-1.888154589708796e+289/mydatabase
Pour convertir un jeton codé par un nombre en chaîne, utilisez. cdk.Tokenization.stringifyNumber(
Dans l'exemple suivant, nous convertissons le jeton codé par un nombre en chaîne avant de définir notre chaîne de connexion :token
)
import { Stack, Duration, Tokenization, CfnOutput, StackProps } from 'aws-cdk-lib';
// ...
export class CdkDemoAppStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Define a new VPC
// ...
// Define an RDS database cluster
// ...
// Get the port token (this is a token encoded as a number)
const portToken = dbCluster.clusterEndpoint.port;
// ...
// Convert the encoded number to an encoded string for use in the connection string
const portAsString = Tokenization.stringifyNumber(portToken);
// Example connection string with the port token as a string
const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portAsString}/mydatabase`;
// Use the connection string as an environment variable in a Lambda function
const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
// ...
environment: {
DATABASE_CONNECTION_STRING: connectionString, // Using the port token as part of the string
},
});
// Output the value of our connection string at synthesis
console.log("connectionString: " + connectionString);
// Output the connection string
new CfnOutput(this, 'ConnectionString', {
value: connectionString,
});
}
}
Lorsque nous exécutonscdk synth
, la valeur de notre chaîne de connexion est représentée dans un format de plus en plus clair :
$
cdk synth --quiet
connectionString: jdbc:mysql://mydb.cluster.amazonaws.com:${Token[TOKEN.242]}/mydatabase
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 paresseuses 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 paresseuses au moment de la synthèse en utilisant des méthodes statiques sur 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.
let actualValue: number;
new AutoScalingGroup(this, 'Group', {
desiredCapacity: Lazy.numberValue({
produce(context) {
return actualValue;
}
})
});
// At some later point
actualValue = 10;
Conversion en JSON
Parfois, vous souhaitez produire une chaîne JSON de données arbitraires, sans savoir si les données contiennent des jetons. Pour encoder correctement en JSON toute structure de données, qu'elle contienne ou non des jetons, utilisez la méthodestack.toJsonString
, comme indiqué dans l'exemple suivant.
const stack = Stack.of(this);
const str = stack.toJsonString({
value: bucket.bucketName
});