Los recursos y la AWS CDK - AWS Cloud Development Kit (AWS CDK) v2

Esta es la guía para AWS CDK desarrolladores de la versión 2. La CDK versión anterior entró en mantenimiento el 1 de junio de 2022 y finalizó el 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.

Los recursos y la AWS CDK

Los recursos son lo que se configura para usar Servicios de AWS en las aplicaciones. Los recursos son una característica de AWS CloudFormation. Al configurar los recursos y sus propiedades en una AWS CloudFormation plantilla, puede implementarlos AWS CloudFormation para aprovisionar sus recursos. Con él AWS Cloud Development Kit (AWS CDK), puede configurar los recursos mediante componentes fijos. A continuación, debe implementar su CDK aplicación, lo que implica sintetizar una AWS CloudFormation plantilla e implementarla para AWS CloudFormation aprovisionar sus recursos.

Configuración de recursos mediante constructos

Como se describe enConstructos AWS CDK, AWS CDK proporciona una amplia biblioteca de clases de construcciones, denominadas AWS construcciones, que representan todos los recursos. AWS

Para crear una instancia de un recurso utilizando su constructo correspondiente, introduzca el ámbito como primer argumento, el identificador lógico del constructo y un conjunto de propiedades de configuración (props). Por ejemplo, aquí se explica cómo crear una SQS cola de Amazon con AWS KMS cifrado mediante la construcción SQS.Queue de la biblioteca Construct. AWS

TypeScript
import * as sqs from '@aws-cdk/aws-sqs'; new sqs.Queue(this, 'MyQueue', { encryption: sqs.QueueEncryption.KMS_MANAGED });
JavaScript
const sqs = require('@aws-cdk/aws-sqs'); new sqs.Queue(this, 'MyQueue', { encryption: sqs.QueueEncryption.KMS_MANAGED });
Python
import aws_cdk.aws_sqs as sqs sqs.Queue(self, "MyQueue", encryption=sqs.QueueEncryption.KMS_MANAGED)
Java
import software.amazon.awscdk.services.sqs.*; Queue.Builder.create(this, "MyQueue").encryption( QueueEncryption.KMS_MANAGED).build();
C#
using Amazon.CDK.AWS.SQS; new Queue(this, "MyQueue", new QueueProps { Encryption = QueueEncryption.KMS_MANAGED });
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/jsii-runtime-go" sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs" ) sqs.NewQueue(stack, jsii.String("MyQueue"), &sqs.QueueProps{ Encryption: sqs.QueueEncryption_KMS_MANAGED, })

Algunos props de configuración son opcionales y, en muchos casos, tienen valores predeterminados. En algunos casos, todos los props son opcionales y el último argumento se puede omitir por completo.

Atributos de recursos

La mayoría de los recursos de la biblioteca AWS Construct muestran los atributos, que se resuelven en el momento de la implementación mediante. AWS CloudFormation Los atributos se exponen en forma de propiedades en las clases de recursos con el nombre del tipo como prefijo. El siguiente ejemplo muestra cómo obtener una SQS cola URL de Amazon mediante la propiedad queueUrl (Python:queue_url).

TypeScript
import * as sqs from '@aws-cdk/aws-sqs'; const queue = new sqs.Queue(this, 'MyQueue'); const url = queue.queueUrl; // => A string representing a deploy-time value
JavaScript
const sqs = require('@aws-cdk/aws-sqs'); const queue = new sqs.Queue(this, 'MyQueue'); const url = queue.queueUrl; // => A string representing a deploy-time value
Python
import aws_cdk.aws_sqs as sqs queue = sqs.Queue(self, "MyQueue") url = queue.queue_url # => A string representing a deploy-time value
Java
Queue queue = new Queue(this, "MyQueue"); String url = queue.getQueueUrl(); // => A string representing a deploy-time value
C#
var queue = new Queue(this, "MyQueue"); var url = queue.QueueUrl; // => A string representing a deploy-time value
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/jsii-runtime-go" sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs" ) queue := sqs.NewQueue(stack, jsii.String("MyQueue"), &sqs.QueueProps{}) url := queue.QueueUrl() // => A string representing a deploy-time value

Consulte Los tokens y el AWS CDK para obtener información sobre cómo AWS CDK codifica los atributos de tiempo de despliegue como cadenas.

Recursos de referencia

Al configurar los recursos, a menudo tendrá que hacer referencia a las propiedades de otro recurso. A continuación se muestran algunos ejemplos:

  • Un recurso de Amazon Elastic Container Service (AmazonECS) requiere una referencia al clúster en el que se ejecuta.

  • Una CloudFront distribución de Amazon requiere una referencia al bucket de Amazon Simple Storage Service (Amazon S3) que contiene el código fuente.

Puede hacer referencia a recursos en algunas de las siguientes maneras:

  • Al pasar un recurso definido en tu CDK aplicación, ya sea en la misma pila o en una diferente

  • Al pasar un objeto proxy que hace referencia a un recurso definido en tu AWS cuenta, creado a partir de un identificador único del recurso (como unARN)

Si la propiedad de un constructo representa un constructo de otro recurso, su tipo es el del tipo de interfaz del constructo. Por ejemplo, la ECS construcción de Amazon toma una propiedad cluster de tipoecs.ICluster. Otro ejemplo es la construcción CloudFront de distribución que toma una propiedad sourceBucket (Python:source_bucket) de tipos3.IBucket.

Puedes pasar directamente cualquier objeto de recurso del tipo adecuado definido en la misma AWS CDK aplicación. El siguiente ejemplo define un ECS clúster de Amazon y, a continuación, lo usa para definir un ECS servicio de Amazon.

TypeScript
const cluster = new ecs.Cluster(this, 'Cluster', { /*...*/ }); const service = new ecs.Ec2Service(this, 'Service', { cluster: cluster });
JavaScript
const cluster = new ecs.Cluster(this, 'Cluster', { /*...*/ }); const service = new ecs.Ec2Service(this, 'Service', { cluster: cluster });
Python
cluster = ecs.Cluster(self, "Cluster") service = ecs.Ec2Service(self, "Service", cluster=cluster)
Java
Cluster cluster = new Cluster(this, "Cluster"); Ec2Service service = new Ec2Service(this, "Service", new Ec2ServiceProps.Builder().cluster(cluster).build());
C#
var cluster = new Cluster(this, "Cluster"); var service = new Ec2Service(this, "Service", new Ec2ServiceProps { Cluster = cluster });
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/jsii-runtime-go" ecs "github.com/aws/aws-cdk-go/awscdk/v2/awsecs" ) cluster := ecs.NewCluster(stack, jsii.String("MyCluster"), &ecs.ClusterProps{}) service := ecs.NewEc2Service(stack, jsii.String("MyService"), &ecs.Ec2ServiceProps{ Cluster: cluster, })

Referencia de recursos en una pila diferente

Puede hacer referencia a los recursos de una pila diferente siempre que estén definidos en la misma aplicación y en el mismo entorno de AWS . Generalmente, se utiliza el siguiente patrón:

  • Guarde una referencia al constructo como atributo de la pila que produce el recurso. (Para obtener una referencia a la pila del constructo actual, utilice Stack.of(this).)

  • Pase esta referencia al constructor de la pila que consume el recurso como parámetro o propiedad. Luego, la pila consumidora la pasa como una propiedad a cualquier constructo que la necesite.

En el ejemplo siguiente se define una pila stack1. Esta pila define un bucket de Amazon S3 y almacena una referencia al constructo del bucket como atributo de la pila. A continuación, la aplicación define una segunda pila, stack2, que acepta un bucket en la instanciación. stack2 podría, por ejemplo, definir una tabla de AWS Glue que utilice el bucket para el almacenamiento de datos.

TypeScript
const prod = { account: '123456789012', region: 'us-east-1' }; const stack1 = new StackThatProvidesABucket(app, 'Stack1', { env: prod }); // stack2 will take a property { bucket: IBucket } const stack2 = new StackThatExpectsABucket(app, 'Stack2', { bucket: stack1.bucket, env: prod });
JavaScript
const prod = { account: '123456789012', region: 'us-east-1' }; const stack1 = new StackThatProvidesABucket(app, 'Stack1', { env: prod }); // stack2 will take a property { bucket: IBucket } const stack2 = new StackThatExpectsABucket(app, 'Stack2', { bucket: stack1.bucket, env: prod });
Python
prod = core.Environment(account="123456789012", region="us-east-1") stack1 = StackThatProvidesABucket(app, "Stack1", env=prod) # stack2 will take a property "bucket" stack2 = StackThatExpectsABucket(app, "Stack2", bucket=stack1.bucket, env=prod)
Java
// Helper method to build an environment static Environment makeEnv(String account, String region) { return Environment.builder().account(account).region(region) .build(); } App app = new App(); Environment prod = makeEnv("123456789012", "us-east-1"); StackThatProvidesABucket stack1 = new StackThatProvidesABucket(app, "Stack1", StackProps.builder().env(prod).build()); // stack2 will take an argument "bucket" StackThatExpectsABucket stack2 = new StackThatExpectsABucket(app, "Stack,", StackProps.builder().env(prod).build(), stack1.bucket);
C#
Amazon.CDK.Environment makeEnv(string account, string region) { return new Amazon.CDK.Environment { Account = account, Region = region }; } var prod = makeEnv(account: "123456789012", region: "us-east-1"); var stack1 = new StackThatProvidesABucket(app, "Stack1", new StackProps { Env = prod }); // stack2 will take a property "bucket" var stack2 = new StackThatExpectsABucket(app, "Stack2", new StackProps { Env = prod, bucket = stack1.Bucket});

Si AWS CDK determina que el recurso se encuentra en el mismo entorno, pero en una pila diferente, sintetiza automáticamente AWS CloudFormation las exportaciones en la pila de producción y un Fn:: ImportValue en la pila consumidora para transferir esa información de una pila a otra.

Resolución de interbloqueos de dependencia

Al hacer referencia a un recurso de una pila en una pila diferente, se crea una dependencia entre las dos pilas. Esto garantiza que se implementen en el orden correcto. Una vez implementadas las pilas, esta dependencia es concreta. Después de eso, eliminar el uso del recurso compartido de la pila que lo consume puede provocar un error de implementación inesperado. Esto ocurre si existe otra dependencia entre las dos pilas que obligue a implementarlas en el mismo orden. También puede ocurrir sin una dependencia si el CDK kit de herramientas simplemente elige la pila de producción para implementarla primero. La AWS CloudFormation exportación se elimina de la pila de producción porque ya no es necesaria, pero el recurso exportado se sigue utilizando en la pila consumidora porque su actualización aún no se ha implementado. Por lo tanto, se produce un error al implementar la pila de productores.

Para salir de este bloqueo, elimine el uso del recurso compartido de la pila que lo consume. (Esto elimina la exportación automática de la pila de producción). A continuación, agregue manualmente la misma exportación a la pila de producción utilizando exactamente el mismo identificador lógico que la exportación generada automáticamente. Elimine el uso del recurso compartido en la pila consumidora e implemente ambas pilas. A continuación, elimine la exportación manual (y el recurso compartido si ya no es necesario) y vuelva a implementar ambas pilas. El método exportValue() de la pila es una forma cómoda de crear la exportación manual para este propósito. (Consulte el ejemplo en la referencia del método vinculado).

Haciendo referencia a los recursos de tu cuenta AWS

Supongamos que quieres usar un recurso que ya está disponible en tu AWS cuenta en tu AWS CDK aplicación. Puede ser un recurso que se definió a través de la consola AWS SDK, directamente con AWS CloudFormation o en una AWS CDK aplicación diferente. Puede convertir el recurso ARN (u otro atributo de identificación o grupo de atributos) en un objeto proxy. El objeto proxy sirve como referencia al recurso al llamar a un método de fábrica estático de la clase del recurso.

Al crear un proxy de este tipo, el recurso externo no pasa a formar parte de la AWS CDK aplicación. Por lo tanto, los cambios que realices en el proxy de tu AWS CDK aplicación no afectan al recurso implementado. Sin embargo, el proxy se puede pasar a cualquier AWS CDK método que requiera un recurso de ese tipo.

El siguiente ejemplo muestra cómo hacer referencia a un depósito en función de un depósito existente con el ARN arn:aws:s3: ::amzn-s3-demo-bucket1 y a un Amazon Virtual Private Cloud en función de uno existente que tenga un ID específico. VPC

TypeScript
// Construct a proxy for a bucket by its name (must be same account) s3.Bucket.fromBucketName(this, 'MyBucket', 'amzn-s3-demo-bucket1'); // Construct a proxy for a bucket by its full ARN (can be another account) s3.Bucket.fromBucketArn(this, 'MyBucket', 'arn:aws:s3:::amzn-s3-demo-bucket1'); // Construct a proxy for an existing VPC from its attribute(s) ec2.Vpc.fromVpcAttributes(this, 'MyVpc', { vpcId: 'vpc-1234567890abcde', });
JavaScript
// Construct a proxy for a bucket by its name (must be same account) s3.Bucket.fromBucketName(this, 'MyBucket', 'amzn-s3-demo-bucket1'); // Construct a proxy for a bucket by its full ARN (can be another account) s3.Bucket.fromBucketArn(this, 'MyBucket', 'arn:aws:s3:::amzn-s3-demo-bucket1'); // Construct a proxy for an existing VPC from its attribute(s) ec2.Vpc.fromVpcAttributes(this, 'MyVpc', { vpcId: 'vpc-1234567890abcde' });
Python
# Construct a proxy for a bucket by its name (must be same account) s3.Bucket.from_bucket_name(self, "MyBucket", "amzn-s3-demo-bucket1") # Construct a proxy for a bucket by its full ARN (can be another account) s3.Bucket.from_bucket_arn(self, "MyBucket", "arn:aws:s3:::amzn-s3-demo-bucket1") # Construct a proxy for an existing VPC from its attribute(s) ec2.Vpc.from_vpc_attributes(self, "MyVpc", vpc_id="vpc-1234567890abcdef")
Java
// Construct a proxy for a bucket by its name (must be same account) Bucket.fromBucketName(this, "MyBucket", "amzn-s3-demo-bucket1"); // Construct a proxy for a bucket by its full ARN (can be another account) Bucket.fromBucketArn(this, "MyBucket", "arn:aws:s3:::amzn-s3-demo-bucket1"); // Construct a proxy for an existing VPC from its attribute(s) Vpc.fromVpcAttributes(this, "MyVpc", VpcAttributes.builder() .vpcId("vpc-1234567890abcdef").build());
C#
// Construct a proxy for a bucket by its name (must be same account) Bucket.FromBucketName(this, "MyBucket", "amzn-s3-demo-bucket1"); // Construct a proxy for a bucket by its full ARN (can be another account) Bucket.FromBucketArn(this, "MyBucket", "arn:aws:s3:::amzn-s3-demo-bucket1"); // Construct a proxy for an existing VPC from its attribute(s) Vpc.FromVpcAttributes(this, "MyVpc", new VpcAttributes { VpcId = "vpc-1234567890abcdef" });
Go
// Define a proxy for a bucket by its name (must be same account) s3.Bucket_FromBucketName(stack, jsii.String("MyBucket"), jsii.String("amzn-s3-demo-bucket1")) // Define a proxy for a bucket by its full ARN (can be another account) s3.Bucket_FromBucketArn(stack, jsii.String("MyBucket"), jsii.String("arn:aws:s3:::amzn-s3-demo-bucket1")) // Define a proxy for an existing VPC from its attributes ec2.Vpc_FromVpcAttributes(stack, jsii.String("MyVpc"), &ec2.VpcAttributes{ VpcId: jsii.String("vpc-1234567890abcde"), })

Echemos un vistazo más de cerca al método Vpc.fromLookup(). Debido a que la ec2.Vpc construcción es compleja, puede que desee seleccionarla de varias maneras para usarla con su aplicación. VPC CDK Para solucionar este problema, la VPC construcción tiene un método fromLookup estático (Python:from_lookup) que te permite buscar el Amazon deseado VPC consultando tu AWS cuenta en el momento de la síntesis.

Para usarloVpc.fromLookup(), el sistema que sintetiza la pila debe tener acceso a la cuenta propietaria de AmazonVPC. Esto se debe a que el CDK kit de herramientas consulta la cuenta para encontrar el Amazon correcto VPC en el momento de la síntesis.

Además, Vpc.fromLookup() solo funciona en pilas definidas con una cuenta y una región explícitas (consulte Entornos para AWS CDK). Si AWS CDK intenta buscar un Amazon VPC desde una pila independiente del entorno, el CDK kit de herramientas no sabe en qué entorno consultar para encontrar el. VPC

Debes proporcionar Vpc.fromLookup() atributos suficientes para identificar de forma exclusiva a en tu cuenta. VPC AWS Por ejemplo, solo puede haber un valor predeterminadoVPC, por lo que basta con especificarlo VPC como predeterminado.

TypeScript
ec2.Vpc.fromLookup(this, 'DefaultVpc', { isDefault: true });
JavaScript
ec2.Vpc.fromLookup(this, 'DefaultVpc', { isDefault: true });
Python
ec2.Vpc.from_lookup(self, "DefaultVpc", is_default=True)
Java
Vpc.fromLookup(this, "DefaultVpc", VpcLookupOptions.builder() .isDefault(true).build());
C#
Vpc.FromLookup(this, id = "DefaultVpc", new VpcLookupOptions { IsDefault = true });
Go
ec2.Vpc_FromLookup(this, jsii.String("DefaultVpc"), &ec2.VpcLookupOptions{ IsDefault: jsii.Bool(true), })

También puedes usar la tags propiedad para realizar consultas VPCs por etiqueta. Puedes añadir etiquetas a Amazon VPC en el momento de su creación utilizando AWS CloudFormation o el AWS CDK. Puedes editar las etiquetas en cualquier momento después de su creación utilizando el AWS Management Console AWS CLI, el o un AWS SDK. Además de las etiquetas que añada usted mismo, añade AWS CDK automáticamente las siguientes etiquetas a todo VPCs lo que cree.

  • Nombre: el nombre delVPC.

  • aws-cdk:subnet-name: nombre de la subred.

  • aws-cdk:subnet-type: tipo de subred: pública, privada o aislada.

TypeScript
ec2.Vpc.fromLookup(this, 'PublicVpc', {tags: {'aws-cdk:subnet-type': "Public"}});
JavaScript
ec2.Vpc.fromLookup(this, 'PublicVpc', {tags: {'aws-cdk:subnet-type': "Public"}});
Python
ec2.Vpc.from_lookup(self, "PublicVpc", tags={"aws-cdk:subnet-type": "Public"})
Java
Vpc.fromLookup(this, "PublicVpc", VpcLookupOptions.builder() .tags(java.util.Map.of("aws-cdk:subnet-type", "Public")) // Java 9 or later .build());
C#
Vpc.FromLookup(this, id = "PublicVpc", new VpcLookupOptions { Tags = new Dictionary<string, string> { ["aws-cdk:subnet-type"] = "Public" });
Go
ec2.Vpc_FromLookup(this, jsii.String("DefaultVpc"), &ec2.VpcLookupOptions{ Tags: &map[string]*string{"aws-cdk:subnet-type": jsii.String("Public")}, })

Los resultados de Vpc.fromLookup() se almacenan en caché en el archivo cdk.context.json del proyecto. (Consulte Los valores de contexto y el AWS CDK). Confirma este archivo al control de versiones para que tu aplicación siga haciendo referencia al mismo AmazonVPC. Esto funciona incluso si luego cambias tus atributos de una VPCs manera que dé como resultado que VPC se seleccione otro diferente. Esto es especialmente importante si vas a implementar la pila en un entorno que no tiene acceso a la AWS cuenta que la defineVPC, como CDKPipelines.

Aunque puedes usar un recurso externo en cualquier lugar en el que utilices un recurso similar definido en tu AWS CDK aplicación, no puedes modificarlo. Por ejemplo, llamar a addToResourcePolicy (Python: add_to_resource_policy) en un s3.Bucket externo no hace nada.

Nombres físicos de los recursos

Los nombres lógicos de los recursos AWS CloudFormation son diferentes de los nombres de los recursos que aparecen AWS Management Console después de su implementación AWS CloudFormation. A estos nombres finales los AWS CDK llama nombres físicos.

Por ejemplo, AWS CloudFormation podría crear el bucket de Amazon S3 con el ID lógico Stack2MyBucket4DD88B4F del ejemplo anterior con el nombre físicostack2MyBucket4dd88b4f-iuv1rbv9z3to.

Puede especificar un nombre físico al crear construcciones que representen recursos mediante el <resourceType> nombre de la propiedad. En el siguiente ejemplo se crea un bucket de Amazon S3 con el nombre físico MyBucket.

TypeScript
const bucket = new s3.Bucket(this, 'MyBucket', { bucketName: 'amzn-s3-demo-bucket', });
JavaScript
const bucket = new s3.Bucket(this, 'MyBucket', { bucketName: 'amzn-s3-demo-bucket' });
Python
bucket = s3.Bucket(self, "MyBucket", bucket_name="amzn-s3-demo-bucket")
Java
Bucket bucket = Bucket.Builder.create(this, "MyBucket") .bucketName("amzn-s3-demo-bucket").build();
C#
var bucket = new Bucket(this, "MyBucket", new BucketProps { BucketName = "amzn-s3-demo-bucket" });
Go
bucket := s3.NewBucket(this, jsii.String("MyBucket"), &s3.BucketProps{ BucketName: jsii.String("amzn-s3-demo-bucket"), })

La asignación de nombres físicos a los recursos presenta algunas desventajas. AWS CloudFormation Y lo que es más importante, cualquier cambio en los recursos implementados que requiera la sustitución de un recurso, como los cambios en las propiedades de un recurso que sean inmutables tras su creación, fallará si a un recurso se le ha asignado un nombre físico. Si terminas en ese estado, la única solución es eliminar la AWS CloudFormation pila y volver a implementar la AWS CDK aplicación. Consulte la documentación de AWS CloudFormation para obtener más detalles.

En algunos casos, como cuando se crea una AWS CDK aplicación con referencias a varios entornos, se requieren nombres físicos para AWS CDK que funcione correctamente. En esos casos, si no quieres molestarte en crear un nombre físico tú mismo, puedes dejar que se lo AWS CDK ponga por ti. Para ello, use el valor especial PhysicalName.GENERATE_IF_NEEDED, de la siguiente manera.

TypeScript
const bucket = new s3.Bucket(this, 'MyBucket', { bucketName: core.PhysicalName.GENERATE_IF_NEEDED, });
JavaScript
const bucket = new s3.Bucket(this, 'MyBucket', { bucketName: core.PhysicalName.GENERATE_IF_NEEDED });
Python
bucket = s3.Bucket(self, "MyBucket", bucket_name=core.PhysicalName.GENERATE_IF_NEEDED)
Java
Bucket bucket = Bucket.Builder.create(this, "MyBucket") .bucketName(PhysicalName.GENERATE_IF_NEEDED).build();
C#
var bucket = new Bucket(this, "MyBucket", new BucketProps { BucketName = PhysicalName.GENERATE_IF_NEEDED });
Go
bucket := s3.NewBucket(this, jsii.String("MyBucket"), &s3.BucketProps{ BucketName: awscdk.PhysicalName_GENERATE_IF_NEEDED(), })

Pasar identificadores de recursos únicos

Siempre que sea posible, debe pasar recursos por referencia, como se describe en la sección anterior. Sin embargo, hay casos en los que no tiene otra opción que hacer referencia a un recurso por uno de sus atributos. Algunos ejemplos de casos de uso incluyen lo siguiente:

  • Cuando utilice AWS CloudFormation recursos de bajo nivel.

  • Cuando necesita exponer los recursos a los componentes de tiempo de ejecución de una AWS CDK aplicación, como cuando se hace referencia a las funciones de Lambda a través de variables de entorno.

Estos identificadores están disponibles como atributos en los recursos, como los siguientes.

TypeScript
bucket.bucketName lambdaFunc.functionArn securityGroup.groupArn
JavaScript
bucket.bucketName lambdaFunc.functionArn securityGroup.groupArn
Python
bucket.bucket_name lambda_func.function_arn security_group_arn
Java

El AWS CDK enlace de Java utiliza métodos de captación para los atributos.

bucket.getBucketName() lambdaFunc.getFunctionArn() securityGroup.getGroupArn()
C#
bucket.BucketName lambdaFunc.FunctionArn securityGroup.GroupArn
Go
bucket.BucketName() fn.FunctionArn()

En el siguiente ejemplo, se muestra cómo pasar el nombre de un bucket generado a una AWS Lambda función.

TypeScript
const bucket = new s3.Bucket(this, 'Bucket'); new lambda.Function(this, 'MyLambda', { // ... environment: { BUCKET_NAME: bucket.bucketName, }, });
JavaScript
const bucket = new s3.Bucket(this, 'Bucket'); new lambda.Function(this, 'MyLambda', { // ... environment: { BUCKET_NAME: bucket.bucketName } });
Python
bucket = s3.Bucket(self, "Bucket") lambda.Function(self, "MyLambda", environment=dict(BUCKET_NAME=bucket.bucket_name))
Java
final Bucket bucket = new Bucket(this, "Bucket"); Function.Builder.create(this, "MyLambda") .environment(java.util.Map.of( // Java 9 or later "BUCKET_NAME", bucket.getBucketName())) .build();
C#
var bucket = new Bucket(this, "Bucket"); new Function(this, "MyLambda", new FunctionProps { Environment = new Dictionary<string, string> { ["BUCKET_NAME"] = bucket.BucketName } });
Go
bucket := s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{}) lambda.NewFunction(this, jsii.String("MyLambda"), &lambda.FunctionProps{ Environment: &map[string]*string{"BUCKET_NAME": bucket.BucketName()}, })

Otorgar permisos entre recursos

Las construcciones de nivel superior permiten obtener permisos con privilegios mínimos al ofrecer requisitos de permiso expresos simples y basados en la intención. APIs Por ejemplo, muchas construcciones de nivel 2 ofrecen métodos de concesión que se pueden utilizar para conceder a una entidad (como un IAM rol o un usuario) permiso para trabajar con el recurso, sin tener que crear manualmente las declaraciones de permiso. IAM

El siguiente ejemplo crea los permisos para permitir que el rol de ejecución de una función de Lambda lea y escriba objetos en un bucket de Amazon S3 concreto. Si el bucket de Amazon S3 está cifrado con una AWS KMS clave, este método también concede permisos a la función de ejecución de la función Lambda para descifrar con la clave.

TypeScript
if (bucket.grantReadWrite(func).success) { // ... }
JavaScript
if ( bucket.grantReadWrite(func).success) { // ... }
Python
if bucket.grant_read_write(func).success: # ...
Java
if (bucket.grantReadWrite(func).getSuccess()) { // ... }
C#
if (bucket.GrantReadWrite(func).Success) { // ... }
Go
if *bucket.GrantReadWrite(function, nil).Success() { // ... }

Los métodos de concesión devuelven un objeto iam.Grant. Utilice el atributo success del objeto Grant para determinar si la subvención se aplicó de manera efectiva (por ejemplo, es posible que no se haya aplicado a recursos externos). También puede usar el método assertSuccess (Python: assert_success) del objeto Grant para garantizar que la concesión se haya aplicado correctamente.

Si un método de concesión específico no está disponible para un caso de uso concreto, puede usar un método de concesión genérico para definir una nueva concesión con una lista de acciones específica.

En el siguiente ejemplo se muestra cómo conceder acceso a una función de Lambda al CreateBackup de Amazon DynamoDB.

TypeScript
table.grant(func, 'dynamodb:CreateBackup');
JavaScript
table.grant(func, 'dynamodb:CreateBackup');
Python
table.grant(func, "dynamodb:CreateBackup")
Java
table.grant(func, "dynamodb:CreateBackup");
C#
table.Grant(func, "dynamodb:CreateBackup");
Go
table := dynamodb.NewTable(this, jsii.String("MyTable"), &dynamodb.TableProps{}) table.Grant(function, jsii.String("dynamodb:CreateBackup"))

Muchos recursos, como las funciones de Lambda, requieren que se asuma un rol al ejecutar el código. Una propiedad de configuración le permite especificar un iam.IRole. Si no se especifica ningún rol, la función crea automáticamente un rol específico para este uso. A continuación, puede utilizar métodos de concesión en los recursos para agregar declaraciones al rol.

Los métodos de concesión se diseñan utilizando un nivel inferior APIs para gestionar las políticas. IAM Las políticas se modelan como PolicyDocumentobjetos. Agregue instrucciones directamente a los roles (o al rol adjunto de un constructo) mediante el método addToRolePolicy (Python: add_to_role_policy) o a la política de un recurso (como una política Bucket) mediante el método addToResourcePolicy (Python: add_to_resource_policy).

Métricas de recursos y alarmas

Muchos recursos emiten CloudWatch métricas que se pueden utilizar para configurar paneles de control y alarmas. Los constructos de nivel superior tienen métodos métricos que permiten acceder a las métricas sin tener que buscar el nombre correcto que se va a utilizar.

El siguiente ejemplo muestra cómo definir una alarma cuando la SQS cola ApproximateNumberOfMessagesNotVisible de Amazon supera los 100.

TypeScript
import * as cw from '@aws-cdk/aws-cloudwatch'; import * as sqs from '@aws-cdk/aws-sqs'; import { Duration } from '@aws-cdk/core'; const queue = new sqs.Queue(this, 'MyQueue'); const metric = queue.metricApproximateNumberOfMessagesNotVisible({ label: 'Messages Visible (Approx)', period: Duration.minutes(5), // ... }); metric.createAlarm(this, 'TooManyMessagesAlarm', { comparisonOperator: cw.ComparisonOperator.GREATER_THAN_THRESHOLD, threshold: 100, // ... });
JavaScript
const cw = require('@aws-cdk/aws-cloudwatch'); const sqs = require('@aws-cdk/aws-sqs'); const { Duration } = require('@aws-cdk/core'); const queue = new sqs.Queue(this, 'MyQueue'); const metric = queue.metricApproximateNumberOfMessagesNotVisible({ label: 'Messages Visible (Approx)', period: Duration.minutes(5) // ... }); metric.createAlarm(this, 'TooManyMessagesAlarm', { comparisonOperator: cw.ComparisonOperator.GREATER_THAN_THRESHOLD, threshold: 100 // ... });
Python
import aws_cdk.aws_cloudwatch as cw import aws_cdk.aws_sqs as sqs from aws_cdk.core import Duration queue = sqs.Queue(self, "MyQueue") metric = queue.metric_approximate_number_of_messages_not_visible( label="Messages Visible (Approx)", period=Duration.minutes(5), # ... ) metric.create_alarm(self, "TooManyMessagesAlarm", comparison_operator=cw.ComparisonOperator.GREATER_THAN_THRESHOLD, threshold=100, # ... )
Java
import software.amazon.awscdk.core.Duration; import software.amazon.awscdk.services.sqs.Queue; import software.amazon.awscdk.services.cloudwatch.Metric; import software.amazon.awscdk.services.cloudwatch.MetricOptions; import software.amazon.awscdk.services.cloudwatch.CreateAlarmOptions; import software.amazon.awscdk.services.cloudwatch.ComparisonOperator; Queue queue = new Queue(this, "MyQueue"); Metric metric = queue .metricApproximateNumberOfMessagesNotVisible(MetricOptions.builder() .label("Messages Visible (Approx)") .period(Duration.minutes(5)).build()); metric.createAlarm(this, "TooManyMessagesAlarm", CreateAlarmOptions.builder() .comparisonOperator(ComparisonOperator.GREATER_THAN_THRESHOLD) .threshold(100) // ... .build());
C#
using cdk = Amazon.CDK; using cw = Amazon.CDK.AWS.CloudWatch; using sqs = Amazon.CDK.AWS.SQS; var queue = new sqs.Queue(this, "MyQueue"); var metric = queue.MetricApproximateNumberOfMessagesNotVisible(new cw.MetricOptions { Label = "Messages Visible (Approx)", Period = cdk.Duration.Minutes(5), // ... }); metric.CreateAlarm(this, "TooManyMessagesAlarm", new cw.CreateAlarmOptions { ComparisonOperator = cw.ComparisonOperator.GREATER_THAN_THRESHOLD, Threshold = 100, // .. });
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/jsii-runtime-go" cw "github.com/aws/aws-cdk-go/awscdk/v2/awscloudwatch" sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs" ) queue := sqs.NewQueue(this, jsii.String("MyQueue"), &sqs.QueueProps{}) metric := queue.MetricApproximateNumberOfMessagesNotVisible(&cw.MetricOptions{ Label: jsii.String("Messages Visible (Approx)"), Period: awscdk.Duration_Minutes(jsii.Number(5)), }) metric.CreateAlarm(this, jsii.String("TooManyMessagesAlarm"), &cw.CreateAlarmOptions{ ComparisonOperator: cw.ComparisonOperator_GREATER_THAN_THRESHOLD, Threshold: jsii.Number(100), })

Si no hay ningún método para una métrica en particular, puede utilizar el método de métrica general para especificar el nombre de la métrica manualmente.

Las métricas también se pueden añadir a los CloudWatch paneles. Consulte CloudWatch.

Tráfico de red

En muchos casos, debe habilitar los permisos en una red para que una aplicación funcione, por ejemplo, cuando la infraestructura informática necesita acceder a la capa de persistencia. Los recursos que establecen o detectan las conexiones exponen los métodos que permiten los flujos de tráfico, incluida la configuración de las reglas de los grupos de seguridad o la redACLs.

IConnectablelos recursos tienen una connections propiedad que es la puerta de entrada a la configuración de las reglas de tráfico de la red.

Para permitir que los datos fluyan en una ruta de red determinada, se utilizan métodos allow. El siguiente ejemplo habilita HTTPS las conexiones a la web y las conexiones entrantes desde el grupo Amazon EC2 Auto Scalingfleet2.

TypeScript
import * as asg from '@aws-cdk/aws-autoscaling'; import * as ec2 from '@aws-cdk/aws-ec2'; const fleet1: asg.AutoScalingGroup = asg.AutoScalingGroup(/*...*/); // Allow surfing the (secure) web fleet1.connections.allowTo(new ec2.Peer.anyIpv4(), new ec2.Port({ fromPort: 443, toPort: 443 })); const fleet2: asg.AutoScalingGroup = asg.AutoScalingGroup(/*...*/); fleet1.connections.allowFrom(fleet2, ec2.Port.AllTraffic());
JavaScript
const asg = require('@aws-cdk/aws-autoscaling'); const ec2 = require('@aws-cdk/aws-ec2'); const fleet1 = asg.AutoScalingGroup(); // Allow surfing the (secure) web fleet1.connections.allowTo(new ec2.Peer.anyIpv4(), new ec2.Port({ fromPort: 443, toPort: 443 })); const fleet2 = asg.AutoScalingGroup(); fleet1.connections.allowFrom(fleet2, ec2.Port.AllTraffic());
Python
import aws_cdk.aws_autoscaling as asg import aws_cdk.aws_ec2 as ec2 fleet1 = asg.AutoScalingGroup( ... ) # Allow surfing the (secure) web fleet1.connections.allow_to(ec2.Peer.any_ipv4(), ec2.Port(PortProps(from_port=443, to_port=443))) fleet2 = asg.AutoScalingGroup( ... ) fleet1.connections.allow_from(fleet2, ec2.Port.all_traffic())
Java
import software.amazon.awscdk.services.autoscaling.AutoScalingGroup; import software.amazon.awscdk.services.ec2.Peer; import software.amazon.awscdk.services.ec2.Port; AutoScalingGroup fleet1 = AutoScalingGroup.Builder.create(this, "MyFleet") /* ... */.build(); // Allow surfing the (secure) Web fleet1.getConnections().allowTo(Peer.anyIpv4(), Port.Builder.create().fromPort(443).toPort(443).build()); AutoScalingGroup fleet2 = AutoScalingGroup.Builder.create(this, "MyFleet2") /* ... */.build(); fleet1.getConnections().allowFrom(fleet2, Port.allTraffic());
C#
using cdk = Amazon.CDK; using asg = Amazon.CDK.AWS.AutoScaling; using ec2 = Amazon.CDK.AWS.EC2; // Allow surfing the (secure) Web var fleet1 = new asg.AutoScalingGroup(this, "MyFleet", new asg.AutoScalingGroupProps { /* ... */ }); fleet1.Connections.AllowTo(ec2.Peer.AnyIpv4(), new ec2.Port(new ec2.PortProps { FromPort = 443, ToPort = 443 }); var fleet2 = new asg.AutoScalingGroup(this, "MyFleet2", new asg.AutoScalingGroupProps { /* ... */ }); fleet1.Connections.AllowFrom(fleet2, ec2.Port.AllTraffic());
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/jsii-runtime-go" autoscaling "github.com/aws/aws-cdk-go/awscdk/v2/awsautoscaling" ec2 "github.com/aws/aws-cdk-go/awscdk/v2/awsec2" ) fleet1 := autoscaling.NewAutoScalingGroup(this, jsii.String("MyFleet1"), &autoscaling.AutoScalingGroupProps{}) fleet1.Connections().AllowTo(ec2.Peer_AnyIpv4(),ec2.NewPort(&ec2.PortProps{ FromPort: jsii.Number(443), ToPort: jsii.Number(443) }),jsii.String("secure web")) fleet2 := autoscaling.NewAutoScalingGroup(this, jsii.String("MyFleet2"), &autoscaling.AutoScalingGroupProps{}) fleet1.Connections().AllowFrom(fleet2, ec2.Port_AllTraffic(),jsii.String("all traffic"))

Algunos recursos tienen puertos predeterminados asociados. Los ejemplos incluyen el receptor de un balanceador de carga en el puerto público y los puertos en los que el motor de base de datos acepta conexiones para instancias de una base de datos de AmazonRDS. En estos casos, puede imponer un control estricto de la red sin tener que especificar el puerto manualmente. Para hacerlo, utilice los métodos allowDefaultPortFrom y allowToDefaultPort (Python: allow_default_port_from, allow_to_default_port).

El siguiente ejemplo muestra cómo habilitar las conexiones desde cualquier IPV4 dirección y una conexión desde un grupo de Auto Scaling para acceder a una base de datos.

TypeScript
listener.connections.allowDefaultPortFromAnyIpv4('Allow public access'); fleet.connections.allowToDefaultPort(rdsDatabase, 'Fleet can access database');
JavaScript
listener.connections.allowDefaultPortFromAnyIpv4('Allow public access'); fleet.connections.allowToDefaultPort(rdsDatabase, 'Fleet can access database');
Python
listener.connections.allow_default_port_from_any_ipv4("Allow public access") fleet.connections.allow_to_default_port(rds_database, "Fleet can access database")
Java
listener.getConnections().allowDefaultPortFromAnyIpv4("Allow public access"); fleet.getConnections().AllowToDefaultPort(rdsDatabase, "Fleet can access database");
C#
listener.Connections.AllowDefaultPortFromAnyIpv4("Allow public access"); fleet.Connections.AllowToDefaultPort(rdsDatabase, "Fleet can access database");
Go
listener.Connections().AllowDefaultPortFromAnyIpv4(jsii.String("Allow public Access")) fleet.Connections().AllowToDefaultPort(rdsDatabase, jsii.String("Fleet can access database"))

Control de eventos

Algunos recursos pueden actuar como fuentes de eventos. Utilice el método addEventNotification (Python: add_event_notification) para registrar un objetivo de evento en un tipo de evento concreto emitido por el recurso. Además, los métodos addXxxNotification ofrecen una forma sencilla de registrar un controlador para los tipos de eventos más comunes.

En el siguiente ejemplo se muestra cómo activar una función de Lambda cuando se agrega un objeto a un bucket de Amazon S3.

TypeScript
import * as s3nots from '@aws-cdk/aws-s3-notifications'; const handler = new lambda.Function(this, 'Handler', { /*…*/ }); const bucket = new s3.Bucket(this, 'Bucket'); bucket.addObjectCreatedNotification(new s3nots.LambdaDestination(handler));
JavaScript
const s3nots = require('@aws-cdk/aws-s3-notifications'); const handler = new lambda.Function(this, 'Handler', { /*…*/ }); const bucket = new s3.Bucket(this, 'Bucket'); bucket.addObjectCreatedNotification(new s3nots.LambdaDestination(handler));
Python
import aws_cdk.aws_s3_notifications as s3_nots handler = lambda_.Function(self, "Handler", ...) bucket = s3.Bucket(self, "Bucket") bucket.add_object_created_notification(s3_nots.LambdaDestination(handler))
Java
import software.amazon.awscdk.services.s3.Bucket; import software.amazon.awscdk.services.lambda.Function; import software.amazon.awscdk.services.s3.notifications.LambdaDestination; Function handler = Function.Builder.create(this, "Handler")/* ... */.build(); Bucket bucket = new Bucket(this, "Bucket"); bucket.addObjectCreatedNotification(new LambdaDestination(handler));
C#
using lambda = Amazon.CDK.AWS.Lambda; using s3 = Amazon.CDK.AWS.S3; using s3Nots = Amazon.CDK.AWS.S3.Notifications; var handler = new lambda.Function(this, "Handler", new lambda.FunctionProps { .. }); var bucket = new s3.Bucket(this, "Bucket"); bucket.AddObjectCreatedNotification(new s3Nots.LambdaDestination(handler));
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/jsii-runtime-go" s3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3" s3nots "github.com/aws/aws-cdk-go/awscdk/v2/awss3notifications" ) handler := lambda.NewFunction(this, jsii.String("MyFunction"), &lambda.FunctionProps{}) bucket := s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{}) bucket.AddObjectCreatedNotification(s3nots.NewLambdaDestination(handler), nil)

Políticas de eliminación

Los recursos que mantienen datos persistentes, como las bases de datos, los depósitos de Amazon S3 y los ECR registros de Amazon, tienen una política de eliminación. La política de eliminación indica si se deben eliminar los objetos persistentes cuando se destruya la pila de AWS CDK que los contiene. Los valores que especifican la política de retirada están disponibles en la RemovalPolicy enumeración del módulo. AWS CDK core

nota

Los recursos, además de los que almacenan datos de forma persistente, también pueden tener una removalPolicy que se utilice para un propósito diferente. Por ejemplo, una versión de una función de Lambda usa un atributo removalPolicy para determinar si una versión determinada se conserva cuando se implementa una nueva versión. Tienen significados y valores predeterminados diferentes en comparación con la política de eliminación de un bucket de Amazon S3 o tabla de DynamoDB.

Valor Significado

RemovalPolicy.RETAIN

Conserve el contenido del recurso al destruir la pila (opción predeterminada). El recurso queda huérfano de la pila y se debe eliminar manualmente. Si intenta volver a implementar la pila mientras el recurso aún existe, recibirá un mensaje de error debido a un conflicto de nombres.

RemovalPolicy.DESTROY

El recurso se destruirá junto con la pila.

AWS CloudFormation no elimina los buckets de Amazon S3 que contienen archivos, incluso si su política de eliminación está establecida en. DESTROY Intentar hacerlo es un AWS CloudFormation error. Para AWS CDK eliminar todos los archivos del depósito antes de destruirlo, defina la autoDeleteObjects propiedad del depósito entrue.

A continuación, se muestra un ejemplo de cómo crear un bucket de Amazon S3 con la RemovalPolicy de DESTROY y autoDeleteOjbects establecido en true.

TypeScript
import * as cdk from '@aws-cdk/core'; import * as s3 from '@aws-cdk/aws-s3'; export class CdkTestStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const bucket = new s3.Bucket(this, 'Bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY, autoDeleteObjects: true }); } }
JavaScript
const cdk = require('@aws-cdk/core'); const s3 = require('@aws-cdk/aws-s3'); class CdkTestStack extends cdk.Stack { constructor(scope, id, props) { super(scope, id, props); const bucket = new s3.Bucket(this, 'Bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY, autoDeleteObjects: true }); } } module.exports = { CdkTestStack }
Python
import aws_cdk.core as cdk import aws_cdk.aws_s3 as s3 class CdkTestStack(cdk.stack): def __init__(self, scope: cdk.Construct, id: str, **kwargs): super().__init__(scope, id, **kwargs) bucket = s3.Bucket(self, "Bucket", removal_policy=cdk.RemovalPolicy.DESTROY, auto_delete_objects=True)
Java
software.amazon.awscdk.core.*; import software.amazon.awscdk.services.s3.*; public class CdkTestStack extends Stack { public CdkTestStack(final Construct scope, final String id) { this(scope, id, null); } public CdkTestStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); Bucket.Builder.create(this, "Bucket") .removalPolicy(RemovalPolicy.DESTROY) .autoDeleteObjects(true).build(); } }
C#
using Amazon.CDK; using Amazon.CDK.AWS.S3; public CdkTestStack(Construct scope, string id, IStackProps props) : base(scope, id, props) { new Bucket(this, "Bucket", new BucketProps { RemovalPolicy = RemovalPolicy.DESTROY, AutoDeleteObjects = true }); }
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/jsii-runtime-go" s3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3" ) s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{ RemovalPolicy: awscdk.RemovalPolicy_DESTROY, AutoDeleteObjects: jsii.Bool(true), })

También puedes aplicar una política de retirada directamente al AWS CloudFormation recurso subyacente mediante applyRemovalPolicy() este método. Este método está disponible en algunos recursos con estado que no tienen una propiedad removalPolicy en los props de sus recursos de nivel 2. Algunos ejemplos son los siguientes:

  • AWS CloudFormation pilas

  • Grupos de usuarios de Amazon Cognito

  • Instancias de base de datos de Amazon DocumentDB

  • EC2Volúmenes de Amazon

  • Dominios OpenSearch de Amazon Service

  • Sistemas de FSx archivos de Amazon

  • Colas de SQS Amazon

TypeScript
const resource = bucket.node.findChild('Resource') as cdk.CfnResource; resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
JavaScript
const resource = bucket.node.findChild('Resource'); resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
Python
resource = bucket.node.find_child('Resource') resource.apply_removal_policy(cdk.RemovalPolicy.DESTROY);
Java
CfnResource resource = (CfnResource)bucket.node.findChild("Resource"); resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
C#
var resource = (CfnResource)bucket.node.findChild('Resource'); resource.ApplyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
nota

La AWS CDK«sRemovalPolicy» se traduce como «s» AWS CloudFormation. DeletionPolicy Sin embargo, la entrada predeterminada AWS CDK es conservar los datos, que es lo contrario de lo AWS CloudFormation predeterminado.