Esta es la guía para desarrolladores de AWS CDK v2. La primera versión del CDK pasó a la etapa de mantenimiento el 1.° de junio de 2022 y no cuenta con soporte desde 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.
Ejemplo: crear una aplicación CDK con varias pilas
Puede crear una aplicación del AWS Cloud Development Kit (AWS CDK) que contenga varias pilas. Al implementar la aplicación AWS CDK, cada pila se convierte en su propia plantilla. AWS CloudFormation También puede sintetizar e implementar cada pila de forma individual mediante el comando AWS CDK cdk deploy
CLI.
En este ejemplo, cubrimos lo siguiente:
-
Cómo extender la clase Stack
para que acepte nuevas propiedades o argumentos.
-
Cómo usar las propiedades para determinar qué recursos contiene la pila y su configuración.
-
Cómo crear instancias de varias pilas de esta clase.
El ejemplo de este tema usa una propiedad booleana llamada encryptBucket
(Python: encrypt_bucket
). Indica si se debe cifrar un bucket de Amazon S3. Si es así, la pila permite el cifrado mediante una clave administrada por el Servicio de administración de AWS claves (AWS KMS). La aplicación crea dos instancias de esta pila, una con cifrado y otra sin él.
Requisitos previos
En este ejemplo se supone que se han completado todos los pasos de introducción.
Crear un proyecto CDK
En primer lugar, creamos un proyecto de CDK mediante la CLI de CDK:
- TypeScript
-
mkdir multistack
cd multistack
cdk init --language=typescript
- JavaScript
-
mkdir multistack
cd multistack
cdk init --language=javascript
- Python
-
mkdir multistack
cd multistack
cdk init --language=python
source .venv/bin/activate # On Windows, run '.\venv\Scripts\activate' instead
pip install -r requirements.txt
- Java
-
mkdir multistack
cd multistack
cdk init --language=java
Puede importar el proyecto Maven resultante a su IDE de Java.
- C#
-
mkdir multistack
cd multistack
cdk init --language=csharp
Puede abrir el archivo src/Pipeline.sln
en Visual Studio.
Agregar un parámetro opcional.
El argumento props
del constructor de Stack
cumple con la interfaz StackProps
. En este ejemplo, queremos que la pila acepte una propiedad adicional que nos indique si debemos cifrar el bucket de Amazon S3. Para ello, creamos una interfaz o clase que incluya la propiedad. Esto permite al compilador asegurarse de que la propiedad tenga un valor booleano y permite completarla automáticamente en su IDE.
Abrimos nuestro archivo de pila en nuestro IDE o editor y añadimos la nueva interfaz, clase o argumento. Las líneas nuevas aparecen resaltadas en negrita:
- TypeScript
-
Archivo: lib/multistack-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
interface MultiStackProps extends cdk.StackProps {
encryptBucket?: boolean;
}
export class MultistackStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: MultiStackProps) {
super(scope, id, props);
// The code that defines our stack goes here
}
}
- JavaScript
-
Archivo: lib/multistack-stack.js
JavaScript no tiene una función de interfaz; no necesitamos añadir ningún código.
const cdk = require('aws-cdk-stack');
class MultistackStack extends cdk.Stack {
constructor(scope, id, props) {
super(scope, id, props);
// The code that defines our stack goes here
}
}
module.exports = { MultistackStack }
- Python
-
Archivo: multistack/multistack_stack.py
Python no tiene una función de interfaz, por lo que ampliaremos nuestra pila para aceptar la nueva propiedad añadiendo un argumento de palabra clave.
import aws_cdk as cdk
from constructs import Construct
class MultistackStack(cdk.Stack):
# The Stack class doesn't know about our encrypt_bucket parameter,
# so accept it separately and pass along any other keyword arguments.
def __init__(self, scope: Construct, id: str, *, encrypt_bucket=False,
**kwargs) -> None:
super().__init__(scope, id, **kwargs)
# The code that defines our stack goes here
- Java
-
Archivo: src/main/java/com/myorg/MultistackStack.java
Ampliar un tipo de accesorios en Java es más complicado de lo que realmente queremos. En su lugar, escribe el constructor de la pila para aceptar un parámetro booleano opcional. Como props
es un argumento opcional, escribiremos un constructor adicional que te permita omitirlo. Estará predeterminado en false
.
package com.myorg;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.constructs.Construct;
import software.amazon.awscdk.services.s3.Bucket;
public class MultistackStack extends Stack {
// additional constructors to allow props and/or encryptBucket to be omitted
public MultistackStack(final Construct scope, final String id, boolean encryptBucket) {
this(scope, id, null, encryptBucket);
}
public MultistackStack(final Construct scope, final String id) {
this(scope, id, null, false);
}
public MultistackStack(final Construct scope, final String id, final StackProps props,
final boolean encryptBucket) {
super(scope, id, props);
// The code that defines our stack goes here
}
}
- C#
-
Archivo: src/Multistack/MultistackStack.cs
using Amazon.CDK;
using constructs;
namespace Multistack
{
public class MultiStackProps : StackProps
{
public bool? EncryptBucket { get; set; }
}
public class MultistackStack : Stack
{
public MultistackStack(Construct scope, string id, MultiStackProps props) : base(scope, id, props)
{
// The code that defines our stack goes here
}
}
}
La nueva propiedad es opcional. Si encryptBucket
(Python: encrypt_bucket
) no está presente, su valor es undefined
, o el equivalente local. De forma predeterminada, el bucket no estará cifrado.
Defina la clase de pila
A continuación, definimos nuestra clase de pila, utilizando nuestra nueva propiedad. El código nuevo aparece resaltado en negrita:
- TypeScript
-
Archivo: lib/multistack-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from constructs;
import * as s3 from 'aws-cdk-lib/aws-s3';
interface MultistackProps extends cdk.StackProps {
encryptBucket?: boolean;
}
export class MultistackStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: MultistackProps) {
super(scope, id, props);
// Add a Boolean property "encryptBucket" to the stack constructor.
// If true, creates an encrypted bucket. Otherwise, the bucket is unencrypted.
// Encrypted bucket uses KMS-managed keys (SSE-KMS).
if (props && props.encryptBucket) {
new s3.Bucket(this, "MyGroovyBucket", {
encryption: s3.BucketEncryption.KMS_MANAGED,
removalPolicy: cdk.RemovalPolicy.DESTROY
});
} else {
new s3.Bucket(this, "MyGroovyBucket", {
removalPolicy: cdk.RemovalPolicy.DESTROY});
}
}
}
- JavaScript
-
Archivo: lib/multistack-stack.js
const cdk = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');
class MultistackStack extends cdk.Stack {
constructor(scope, id, props) {
super(scope, id, props);
// Add a Boolean property "encryptBucket" to the stack constructor.
// If true, creates an encrypted bucket. Otherwise, the bucket is unencrypted.
// Encrypted bucket uses KMS-managed keys (SSE-KMS).
if ( props && props.encryptBucket) {
new s3.Bucket(this, "MyGroovyBucket", {
encryption: s3.BucketEncryption.KMS_MANAGED,
removalPolicy: cdk.RemovalPolicy.DESTROY
});
} else {
new s3.Bucket(this, "MyGroovyBucket", {
removalPolicy: cdk.RemovalPolicy.DESTROY});
}
}
}
module.exports = { MultistackStack }
- Python
-
Archivo: multistack/multistack_stack.py
import aws_cdk as cdk
from constructs import Construct
from aws_cdk import aws_s3 as s3
class MultistackStack(cdk.Stack):
# The Stack class doesn't know about our encrypt_bucket parameter,
# so accept it separately and pass along any other keyword arguments.
def __init__(self, scope: Construct, id: str, *, encrypt_bucket=False,
**kwargs) -> None:
super().__init__(scope, id, **kwargs)
# Add a Boolean property "encryptBucket" to the stack constructor.
# If true, creates an encrypted bucket. Otherwise, the bucket is unencrypted.
# Encrypted bucket uses KMS-managed keys (SSE-KMS).
if encrypt_bucket:
s3.Bucket(self, "MyGroovyBucket",
encryption=s3.BucketEncryption.KMS_MANAGED,
removal_policy=cdk.RemovalPolicy.DESTROY)
else:
s3.Bucket(self, "MyGroovyBucket",
removal_policy=cdk.RemovalPolicy.DESTROY)
- Java
-
Archivo: src/main/java/com/myorg/MultistackStack.java
package com.myorg;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.constructs.Construct;
import software.amazon.awscdk.RemovalPolicy;
import software.amazon.awscdk.services.s3.Bucket;
import software.amazon.awscdk.services.s3.BucketEncryption;
public class MultistackStack extends Stack {
// additional constructors to allow props and/or encryptBucket to be omitted
public MultistackStack(final Construct scope, final String id,
boolean encryptBucket) {
this(scope, id, null, encryptBucket);
}
public MultistackStack(final Construct scope, final String id) {
this(scope, id, null, false);
}
// main constructor
public MultistackStack(final Construct scope, final String id,
final StackProps props, final boolean encryptBucket) {
super(scope, id, props);
// Add a Boolean property "encryptBucket" to the stack constructor.
// If true, creates an encrypted bucket. Otherwise, the bucket is
// unencrypted. Encrypted bucket uses KMS-managed keys (SSE-KMS).
if (encryptBucket) {
Bucket.Builder.create(this, "MyGroovyBucket")
.encryption(BucketEncryption.KMS_MANAGED)
.removalPolicy(RemovalPolicy.DESTROY).build();
} else {
Bucket.Builder.create(this, "MyGroovyBucket")
.removalPolicy(RemovalPolicy.DESTROY).build();
}
}
}
- C#
-
Archivo: src/Multistack/MultistackStack.cs
using Amazon.CDK;
using Amazon.CDK.AWS.S3;
namespace Multistack
{
public class MultiStackProps : StackProps
{
public bool? EncryptBucket { get; set; }
}
public class MultistackStack : Stack
{
public MultistackStack(Construct scope, string id, IMultiStackProps props = null) : base(scope, id, props)
{
// Add a Boolean property "EncryptBucket" to the stack constructor.
// If true, creates an encrypted bucket. Otherwise, the bucket is unencrypted.
// Encrypted bucket uses KMS-managed keys (SSE-KMS).
if (props?.EncryptBucket ?? false)
{
new Bucket(this, "MyGroovyBucket", new BucketProps
{
Encryption = BucketEncryption.KMS_MANAGED,
RemovalPolicy = RemovalPolicy.DESTROY
});
}
else
{
new Bucket(this, "MyGroovyBucket", new BucketProps
{
RemovalPolicy = RemovalPolicy.DESTROY
});
}
}
}
}
Crear dos instancias de pila.
En el archivo de nuestra aplicación, añadimos el código para crear instancias de dos pilas independientes. Eliminamos la definición existente de MultistackStack
y definimos nuestras dos pilas. El código nuevo aparece resaltado en negrita:
- TypeScript
-
Archivo: bin/multistack.ts
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { MultistackStack } from '../lib/multistack-stack';
const app = new cdk.App();
new MultistackStack(app, "MyWestCdkStack", {
env: {region: "us-west-1"},
encryptBucket: false
});
new MultistackStack(app, "MyEastCdkStack", {
env: {region: "us-east-1"},
encryptBucket: true
});
app.synth();
- JavaScript
-
Archivo: bin/multistack.js
#!/usr/bin/env node
const cdk = require('aws-cdk-lib');
const { MultistackStack } = require('../lib/multistack-stack');
const app = new cdk.App();
new MultistackStack(app, "MyWestCdkStack", {
env: {region: "us-west-1"},
encryptBucket: false
});
new MultistackStack(app, "MyEastCdkStack", {
env: {region: "us-east-1"},
encryptBucket: true
});
app.synth();
- Python
-
Archivo: ./app.py
#!/usr/bin/env python3
import aws_cdk as cdk
from multistack.multistack_stack import MultistackStack
app = cdk.App()
MultistackStack(app, "MyWestCdkStack",
env=cdk.Environment(region="us-west-1"),
encrypt_bucket=False)
MultistackStack(app, "MyEastCdkStack",
env=cdk.Environment(region="us-east-1"),
encrypt_bucket=True)
app.synth()
- Java
-
Archivo: src/main/java/com/myorg/MultistackApp.java
package com.myorg;
import software.amazon.awscdk.App;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.StackProps;
public class MultistackApp {
public static void main(final String argv[]) {
App app = new App();
new MultistackStack(app, "MyWestCdkStack", StackProps.builder()
.env(Environment.builder()
.region("us-west-1")
.build())
.build(), false);
new MultistackStack(app, "MyEastCdkStack", StackProps.builder()
.env(Environment.builder()
.region("us-east-1")
.build())
.build(), true);
app.synth();
}
}
- C#
-
Archivo: src/Multistack/Program .cs
using Amazon.CDK;
namespace Multistack
{
class Program
{
static void Main(string[] args)
{
var app = new App();
new MultistackStack(app, "MyWestCdkStack", new MultiStackProps
{
Env = new Environment { Region = "us-west-1" },
EncryptBucket = false
});
new MultistackStack(app, "MyEastCdkStack", new MultiStackProps
{
Env = new Environment { Region = "us-east-1" },
EncryptBucket = true
});
app.Synth();
}
}
}
Este código usa la nueva propiedad encryptBucket
(Python: encrypt_bucket
) de la clase MultistackStack
para crear las siguientes instancias:
Sintetice e implemente la pila
A continuación, podemos implementar pilas desde la aplicación. En primer lugar, sintetizamos una AWS CloudFormation plantilla para. MyEastCdkStack
Esta es la pila que está en us-east-1
con el bucket cifrado de Amazon S3.
$ cdk synth MyEastCdkStack
Para implementar esta pila en nuestro AWS entorno, podemos ejecutar uno de los siguientes comandos. El primer comando usa nuestro AWS perfil predeterminado para obtener las credenciales para implementar la pila. El segundo usa un perfil que especificamos. PorPROFILE_NAME
, podemos sustituirlo por el nombre de un perfil de AWS CLI que contenga las credenciales adecuadas para la implementación en la us-east-1
AWS región.
$ cdk deploy MyEastCdkStack
$ cdk deploy MyEastCdkStack --profile=<PROFILE_NAME>
Limpieza
Para evitar que se cobre por los recursos que hemos implementado, destruimos la pila mediante el siguiente comando:
cdk destroy MyEastCdkStack
La operación de destrucción falla si hay algo almacenado en el depósito de la pila. No debería haberlo, ya que solo hemos creado el depósito. Si pusimos algo en el bucket, debemos eliminar el contenido del bucket antes de destruir la pila. Podemos usar la consola AWS de administración o la AWS CLI para eliminar el contenido del bucket.