Questa è la guida per sviluppatori AWS CDK v2. Il vecchio CDK v1 è entrato 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à.
In AWS Cloud Development Kit (AWS CDK), i token sono segnaposto per valori che non sono noti quando si definiscono costrutti o si sintetizzano pile. Questi valori verranno completamente risolti al momento dell'implementazione, quando verrà creata l'infrastruttura effettiva. Durante lo sviluppo di AWS CDK applicazioni, utilizzerai i token per gestire questi valori in tutta l'applicazione.
Esempio di token
Di seguito è riportato un esempio di stack CDK che definisce un costrutto per un bucket Amazon Simple Storage Service (Amazon S3). Poiché il nome del nostro bucket non è ancora noto, il valore di viene memorizzato come token: bucketName
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);
}
}
Quando eseguiamo cdk synth
la sintesi del nostro stack, il valore di myBucketName
verrà visualizzato nel formato token di. ${Token[TOKEN.
Questo formato di token è il risultato del modo in cui i token codificano AWS CDK . In questo esempio, il token è codificato come stringa:1234
]}
$
cdk synth --quiet
myBucketName: ${Token[TOKEN.21
]}
Poiché il valore del nome del nostro bucket non è noto al momento della sintesi, il token viene reso come. myBucket
Il nostro AWS CloudFormation modello utilizza la funzione <unique-hash>
Ref
intrinseca per fare riferimento al suo valore, che sarà noto al momento dell'implementazione:
Resources:
myBucket5AF9C99B
:
# ...
Outputs:
bucketNameOutput:
Description: The name of the S3 bucket
Value:
Ref: myBucket5AF9C99B
Per ulteriori informazioni su come viene generato l'hash univoco, consulta. Logico generato IDs nel tuo AWS CloudFormation modello
Passare gettoni
I token possono essere trasferiti come se fossero il valore effettivo che rappresentano. Di seguito è riportato un esempio che passa il token per il nome del nostro bucket a un costrutto per una funzione: AWS Lambda
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
}
});
}
}
Quando sintetizziamo il nostro modello, le Ref
funzioni Fn::Join
intrinseche vengono utilizzate per specificare i valori, che saranno noti al momento dell'implementazione:
Resources:
myBucket5AF9C99B
:
Type: AWS::S3::Bucket
# ...
myFunction884E1557
:
Type: AWS::Lambda::Function
Properties:
# ...
Environment:
Variables:
BUCKET_NAME:
Ref: myBucket5AF9C99B
FunctionName:
Fn::Join:
- ""
- - Ref: myBucket5AF9C99B
- Function
# ...
Come funzionano le codifiche dei token
I token sono oggetti che implementano l'IResolvable
interfaccia, che contiene un unico resolve
metodo. Durante la sintesi, AWS CDK chiama questo metodo per produrre il valore finale dei token nel CloudFormation modello.
Nota
Raramente lavorerai direttamente con l'IResolvable
interfaccia. Molto probabilmente vedrai solo versioni di token con codifica a stringa.
Tipi di codifica dei token
I token partecipano al processo di sintesi per produrre valori arbitrari di qualsiasi tipo. Le altre funzioni in genere accettano solo argomenti di tipo base, come string
o. number
Per utilizzare i token in questi casi, potete codificarli in uno dei tre tipi utilizzando metodi statici sulla cdk.Token
classe.
-
Token.asString
per generare una codifica di stringhe (o chiamare l'.toString()
oggetto token). -
Token.asList
per generare una codifica di elenco. -
Token.asNumber
per generare una codifica numerica.
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.
Come verificare la presenza di token nella tua app
Per verificare se un valore contiene un token non risolto, chiamate il metodo Token.isUnresolved
(Pythonis_unresolved
:). Di seguito è riportato un esempio che verifica se il valore per il nome del nostro bucket Amazon S3 è un token. Se non è un token, convalidiamo la lunghezza del nome del 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.');
};
// ...
Quando eseguiamocdk synth
, myBucketName
viene identificato come un token:
$
cdk synth --quiet
Token identified.
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.
Lavorare con 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 illustrato nell'esempio seguente.
const functionName = bucket.bucketName + 'Function';
È inoltre possibile utilizzare l'interpolazione di stringhe, se la lingua in uso la supporta, come illustrato nell'esempio seguente.
const functionName = `${bucket.bucketName}Function`;
Evita di manipolare la stringa in altri modi. Ad esempio, è probabile che l'acquisizione di una sottostringa di una stringa interrompa il token della stringa.
Lavorare con token codificati in elenchi
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.
Lavorare con 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.
Di seguito è riportato un esempio di costrutto che contiene un token codificato come numero:
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);
}
}
Quando eseguiamocdk synth
, il valore di portToken
viene visualizzato come token con codifica numerica:
$
cdk synth --quiet
portToken: -1.8881545897087968e+289
Passa token con codifica numerica
Quando passate token con codifica numerica ad altri costrutti, può essere opportuno convertirli prima in stringhe. Ad esempio, se desiderate utilizzare il valore di una stringa con codifica numerica come parte di una stringa concatenata, la conversione ne facilita la leggibilità.
Nell'esempio seguente, portToken
è un token con codifica numerica che vogliamo passare alla nostra funzione Lambda come parte di: 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,
});
}
}
Se passiamo questo valore aconnectionString
, il valore di output durante l'esecuzione cdk synth
potrebbe creare confusione a causa della stringa con codifica numerica:
$
cdk synth --quiet
connectionString: jdbc:mysql://mydb.cluster.amazonaws.com:-1.888154589708796e+289/mydatabase
Per convertire un token con codifica numerica in una stringa, usa. cdk.Tokenization.stringifyNumber(
Nell'esempio seguente, convertiamo il token con codifica numerica in una stringa prima di definire la nostra stringa di connessione: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,
});
}
}
Quando eseguiamocdk synth
, il valore della nostra stringa di connessione è rappresentato in un formato più pulito e chiaro:
$
cdk synth --quiet
connectionString: jdbc:mysql://mydb.cluster.amazonaws.com:${Token[TOKEN.242]}/mydatabase
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.
È possibile creare token che rappresentano valori lazy in fase di sintetizzazione utilizzando metodi statici sulla classe, come e. Lazy
Lazy.string
Lazy.number
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.
let actualValue: number;
new AutoScalingGroup(this, 'Group', {
desiredCapacity: Lazy.numberValue({
produce(context) {
return actualValue;
}
})
});
// At some later point
actualValue = 10;
Conversione in JSON
A volte vuoi produrre una stringa JSON di dati arbitrari e potresti non sapere se i dati contengono token. Per codificare correttamente in JSON qualsiasi struttura di dati, indipendentemente dal fatto che contenga o meno token, utilizzate il metodostack.toJsonString
, come illustrato nell'esempio seguente.
const stack = Stack.of(this);
const str = stack.toJsonString({
value: bucket.bucketName
});