Constructos do AWS CDK - AWS Cloud Development Kit (AWS CDK) v2

Este é o Guia do Desenvolvedor AWS CDK v2. A CDK v1 mais antiga entrou em manutenção em 1º de junho de 2022 e encerrou o suporte em 1º de junho de 2023.

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Constructos do AWS CDK

Os constructos são os blocos de construção básicos dos aplicativos do AWS Cloud Development Kit (AWS CDK). Um constructo é um componente em seu aplicativo que representa um ou mais recursos do AWS CloudFormation e sua configuração. Você constrói seu aplicativo, parte por parte, importando e configurando constructos.

Importar e usar constructos

Os constructos são classes que você importa para seus aplicativos do CDK da Biblioteca de Constructos da AWS. Você também pode criar e distribuir seus próprios constructos ou usar constructos criados por desenvolvedores terceirizados.

Os constructos fazem parte do Construct Programming Model (CPM – Modelo de programação de constructo). Eles estão disponíveis para uso com outras ferramentas, como CDK para Terraform (CDKtf), CDK para Kubernetes (CDK8s) e Projen.

Vários terceiros também publicaram constructos compatíveis com o AWS CDK. Visite o Construct Hub para explorar o ecossistema do parceiro de constructo do AWS CDK.

Níveis de constructo

Os constructos da Biblioteca de Constructos da AWS são categorizados em três níveis. Cada nível oferece um nível crescente de abstração. Quanto maior a abstração, mais fácil de configurar, exigindo menos experiência. Quanto menor a abstração, mais personalização está disponível, exigindo mais experiência.

Constructos de nível 1 (L1)

Os constructos L1, também conhecidos como recursos do CFN, são os constructos de nível mais baixo e não oferecem abstração. Cada constructo L1 é mapeado diretamente para um único recurso do AWS CloudFormation. Com constructos L1, você importa um constructo que representa um recurso do AWS CloudFormation específico. Em seguida, você define as propriedades do recurso em sua instância de constructo.

Os constructos L1 são ótimos para usar quando você está familiarizado com o AWS CloudFormation e precisa de controle total sobre a definição das propriedades de seus recursos da AWS.

Na Biblioteca de Constructos da AWS, os constructos L1 são nomeados começando com Cfn, seguido por um identificador para o recurso do AWS CloudFormation que eles representam. Por exemplo, o constructo CfnBucket é um constructo L1 que representa um recurso AWS::S3::Bucket do AWS CloudFormation.

Os constructos L1 são gerados a partir da especificação do recurso do AWS CloudFormation. Se um recurso existir no AWS CloudFormation, ele estará disponível no AWS CDK como um constructo L1. Novos recursos ou propriedades podem levar até uma semana para serem disponibilizados na Biblioteca de Constructos da AWS. Para obter mais informações, consulte Referência de tipos de propriedade e recursos da AWS no Guia do usuário do AWS CloudFormation.

Constructos de nível 2 (L2)

Os constructos L2, também conhecidas como constructos curados, são cuidadosamente desenvolvidos pela equipe do CDK e geralmente são o tipo de constructo mais amplamente usado. Os constructos L2 são mapeados diretamente para recursos do AWS CloudFormation individuais, semelhantes aos constructos L1. Em comparação com os constructos L1, os constructos L2 fornecem uma abstração de alto nível por meio de uma API intuitiva baseada em intenção. Os constructos L2 incluem configurações de propriedades padrão sensatas, políticas de segurança de práticas recomendadas e geram muito código clichê e lógica de colagem para você.

Os constructos L2 também fornecem métodos auxiliares para a maioria dos recursos que simplificam e agilizam a definição de propriedades, permissões, interações baseadas em eventos entre recursos e muito mais.

A classe s3.Bucket é um exemplo de um constructo L2 para um recurso de bucket do Amazon Simple Storage Service (Amazon S3).

A Biblioteca de Constructos da AWS contém constructos L2 que são designados como estáveis e prontos para uso em produção. Para constructos L2 em desenvolvimento, eles são designados como experimentais e oferecidos em um módulo separado.

Constructos de nível 3 (L3)

Os constructos L3, também conhecidos como padrões, são o nível mais alto de abstração. Cada constructo L3 pode conter uma coleção de recursos que são configurados para trabalhar juntos para realizar uma tarefa ou serviço específico em seu aplicativo. Os constructos L3 são usados para criar arquiteturas da AWS inteiras para casos de uso específicos em seu aplicativo.

Para fornecer projetos de sistema completos ou partes substanciais de um sistema maior, os constructos L3 oferecem configurações de propriedades padrão opinativas. Eles são construídos em torno de uma abordagem específica para resolver um problema e fornecer uma solução. Com constructos L3, você pode criar e configurar vários recursos rapidamente, com a menor quantidade de entrada e código.

A classe ecsPatterns.ApplicationLoadBalancedFargateService é um exemplo de um constructo L3 que representa um serviço do AWS Fargate executado em um cluster do Amazon Elastic Container Service (Amazon ECS) e liderado por um Application Load Balancer.

Semelhantes aos constructos L2, os constructos L3 que estão prontos para uso em produção estão incluídos na Biblioteca de Constructos da AWS. Os que estão em desenvolvimento são oferecidos em módulos separados.

Definição de constructos

Composição

A composição é o padrão chave para definir abstrações de alto nível por meio de constructos. Um constructo de alto nível pode ser composto a partir de qualquer número de constructos de nível inferior. De uma perspectiva de baixo para cima, você usa constructos para organizar os recursos individuais da AWS que deseja implantar. Você usa quaisquer abstrações que sejam convenientes para seu propósito, com quantos níveis precisar.

Com a composição, você define componentes reutilizáveis e os compartilha como qualquer outro código. Por exemplo, uma equipe pode definir um constructo que implemente as práticas recomendadas da empresa em uma tabela do Amazon DynamoDB, incluindo backup, replicação global, escalabilidade automática e monitoramento. A equipe pode compartilhar o constructo internamente com outras equipes ou publicamente.

As equipes podem usar constructos como qualquer outro pacote de biblioteca. Quando a biblioteca é atualizada, os desenvolvedores têm acesso às melhorias e correções de erros da nova versão, de forma semelhante a qualquer outra biblioteca de código.

Inicialização

As estruturas são implementadas em classes que estendem a classe base no Construct. Você define um constructo instanciando a classe. Todas as estruturas usam três parâmetros ao serem inicializadas:

  • escopo: o pai ou proprietário do constructo. Pode ser uma pilha ou outro constructo. O escopo determina o lugar do constructo na árvore de constructos. Em geral, é necessário passar this (self no Python), que representa o objeto atual, para o escopo.

  • id: um identificador que deve ser exclusivo dentro desse escopo. O identificador serve como um namespace para tudo o que está definido no constructo. É usado para gerar identificadores exclusivos, como nomes de recursos e IDs lógicos do AWS CloudFormation.

    Os identificadores só precisam ser exclusivos dentro de um escopo. Ele permite que você instancie e reutilize constructos sem se preocupar com os constructos e identificadores que eles possam conter, além de permitir a composição de constructos em abstrações de alto nível. Além disso, os escopos possibilitam a referência a grupos de constructos de uma só vez. Os exemplos incluem a marcação ou a especificação de onde os constructos serão implantados.

  • props: um conjunto de propriedades ou argumentos de palavras-chave, dependendo da linguagem, que definem a configuração inicial do constructo. Constructos de nível superior fornecem mais padrões e, se todos os elementos prop forem opcionais, você poderá omitir completamente o parâmetro props.

Configuração

A maioria dos constructos aceita props como terceiro argumento (ou, em Python, argumentos de palavra-chave), uma coleção de nome/valor que define a configuração do constructo. O exemplo a seguir define um bucket com criptografia do AWS Key Management Service (AWS KMS) e hospedagem estática de sites ativadas. Como não especifica explicitamente uma chave de criptografia, o constructo do Bucket define uma nova kms.Key e a associa ao bucket.

TypeScript
new s3.Bucket(this, 'MyEncryptedBucket', { encryption: s3.BucketEncryption.KMS, websiteIndexDocument: 'index.html' });
JavaScript
new s3.Bucket(this, 'MyEncryptedBucket', { encryption: s3.BucketEncryption.KMS, websiteIndexDocument: 'index.html' });
Python
s3.Bucket(self, "MyEncryptedBucket", encryption=s3.BucketEncryption.KMS, website_index_document="index.html")
Java
Bucket.Builder.create(this, "MyEncryptedBucket") .encryption(BucketEncryption.KMS_MANAGED) .websiteIndexDocument("index.html").build();
C#
new Bucket(this, "MyEncryptedBucket", new BucketProps { Encryption = BucketEncryption.KMS_MANAGED, WebsiteIndexDocument = "index.html" });
Go
awss3.NewBucket(stack, jsii.String("MyEncryptedBucket"), &awss3.BucketProps{ Encryption: awss3.BucketEncryption_KMS, WebsiteIndexDocument: jsii.String("index.html"), })

Interagir com constructos

Os constructos são implementados em classes que estendem a classe de constructo de base. Depois de instanciar um constructo, o objeto do constructo expõe um conjunto de métodos e propriedades que permitem que você interaja com o constructo e o transmita como referência para outras partes do sistema.

A estrutura do AWS CDK não impõe nenhuma restrição às APIs dos constructos. Os autores podem definir qualquer API que quiserem. No entanto, os constructos da AWS incluídos na Biblioteca de Constructos da AWS, por exemplo, s3.Bucket, seguem diretrizes e padrões comuns. Isso proporciona uma experiência consistente em todos os recursos da AWS.

A maioria dos constructos da AWS tem um conjunto de métodos de concessão que você pode usar para conceder permissões do AWS Identity and Access Management (IAM) nesse constructo a uma entidade principal. O exemplo a seguir concede a permissão data-science ao grupo do IAM para ler a partir do bucket raw-data do Amazon S3.

TypeScript
const rawData = new s3.Bucket(this, 'raw-data'); const dataScience = new iam.Group(this, 'data-science'); rawData.grantRead(dataScience);
JavaScript
const rawData = new s3.Bucket(this, 'raw-data'); const dataScience = new iam.Group(this, 'data-science'); rawData.grantRead(dataScience);
Python
raw_data = s3.Bucket(self, 'raw-data') data_science = iam.Group(self, 'data-science') raw_data.grant_read(data_science)
Java
Bucket rawData = new Bucket(this, "raw-data"); Group dataScience = new Group(this, "data-science"); rawData.grantRead(dataScience);
C#
var rawData = new Bucket(this, "raw-data"); var dataScience = new Group(this, "data-science"); rawData.GrantRead(dataScience);
Go
rawData := awss3.NewBucket(stack, jsii.String("raw-data"), nil) dataScience := awsiam.NewGroup(stack, jsii.String("data-science"), nil) rawData.GrantRead(dataScience, nil)

Outro padrão comum é que os constructos da AWS definam um dos atributos do recurso a partir de dados fornecidos em outro lugar. Os atributos podem incluir nomes do recurso da Amazon (ARNs), nomes ou URLs.

O código a seguir define uma função do AWS Lambda e a associa a uma fila do Amazon Simple Queue Service (Amazon SQS) que usa o URL da fila em uma variável de ambiente.

TypeScript
const jobsQueue = new sqs.Queue(this, 'jobs'); const createJobLambda = new lambda.Function(this, 'create-job', { runtime: lambda.Runtime.NODEJS_18_X, handler: 'index.handler', code: lambda.Code.fromAsset('./create-job-lambda-code'), environment: { QUEUE_URL: jobsQueue.queueUrl } });
JavaScript
const jobsQueue = new sqs.Queue(this, 'jobs'); const createJobLambda = new lambda.Function(this, 'create-job', { runtime: lambda.Runtime.NODEJS_18_X, handler: 'index.handler', code: lambda.Code.fromAsset('./create-job-lambda-code'), environment: { QUEUE_URL: jobsQueue.queueUrl } });
Python
jobs_queue = sqs.Queue(self, "jobs") create_job_lambda = lambda_.Function(self, "create-job", runtime=lambda_.Runtime.NODEJS_18_X, handler="index.handler", code=lambda_.Code.from_asset("./create-job-lambda-code"), environment=dict( QUEUE_URL=jobs_queue.queue_url ) )
Java
final Queue jobsQueue = new Queue(this, "jobs"); Function createJobLambda = Function.Builder.create(this, "create-job") .handler("index.handler") .code(Code.fromAsset("./create-job-lambda-code")) .environment(java.util.Map.of( // Map.of is Java 9 or later "QUEUE_URL", jobsQueue.getQueueUrl()) .build();
C#
var jobsQueue = new Queue(this, "jobs"); var createJobLambda = new Function(this, "create-job", new FunctionProps { Runtime = Runtime.NODEJS_18_X, Handler = "index.handler", Code = Code.FromAsset(@".\create-job-lambda-code"), Environment = new Dictionary<string, string> { ["QUEUE_URL"] = jobsQueue.QueueUrl } });
Go
createJobLambda := awslambda.NewFunction(stack, jsii.String("create-job"), &awslambda.FunctionProps{ Runtime: awslambda.Runtime_NODEJS_18_X(), Handler: jsii.String("index.handler"), Code: awslambda.Code_FromAsset(jsii.String(".\\create-job-lambda-code"), nil), Environment: &map[string]*string{ "QUEUE_URL": jsii.String(*jobsQueue.QueueUrl()), }, })

Para informações sobre os padrões de API mais comuns na Biblioteca de Constructos da AWS, consulte Recursos e o AWS CDK.

O constructo do aplicativo e da pilha

As classes de App e de Stack da Biblioteca de Constructos da AWS são constructos exclusivos. Em comparação com outros constructos, eles não configuram recursos da AWS sozinhos. Em vez disso, eles usados para fornecer contexto para seus outros constructos. Todos os constructos que representam recursos da AWS devem ser definidos, direta ou indiretamente, dentro do escopo de um constructo da Stack. Os constructos da Stack são definidos dentro do escopo do constructo de um App.

Para saber mais sobre os aplicativos do CDK, consulte Aplicativos do AWS CDK. Para saber mais sobre as pilhas do CDK, consulte Introdução às AWS CDK pilhas.

O exemplo a seguir define um aplicativo com uma única pilha. Dentro da pilha, um constructo L2 é usado para configurar um recurso de bucket do Amazon S3.

TypeScript
import { App, Stack, StackProps } from 'aws-cdk-lib'; import * as s3 from 'aws-cdk-lib/aws-s3'; class HelloCdkStack extends Stack { constructor(scope: App, id: string, props?: StackProps) { super(scope, id, props); new s3.Bucket(this, 'MyFirstBucket', { versioned: true }); } } const app = new App(); new HelloCdkStack(app, "HelloCdkStack");
JavaScript
const { App , Stack } = require('aws-cdk-lib'); const s3 = require('aws-cdk-lib/aws-s3'); class HelloCdkStack extends Stack { constructor(scope, id, props) { super(scope, id, props); new s3.Bucket(this, 'MyFirstBucket', { versioned: true }); } } const app = new App(); new HelloCdkStack(app, "HelloCdkStack");
Python
from aws_cdk import App, Stack import aws_cdk.aws_s3 as s3 from constructs import Construct class HelloCdkStack(Stack): def __init__(self, scope: Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) s3.Bucket(self, "MyFirstBucket", versioned=True) app = App() HelloCdkStack(app, "HelloCdkStack")
Java

Pilha definida no arquivo HelloCdkStack.java:

import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; import software.amazon.awscdk.services.s3.*; public class HelloCdkStack extends Stack { public HelloCdkStack(final Construct scope, final String id) { this(scope, id, null); } public HelloCdkStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); Bucket.Builder.create(this, "MyFirstBucket") .versioned(true).build(); } }

Aplicativo definido no arquivo HelloCdkApp.java:

import software.amazon.awscdk.App; import software.amazon.awscdk.StackProps; public class HelloCdkApp { public static void main(final String[] args) { App app = new App(); new HelloCdkStack(app, "HelloCdkStack", StackProps.builder() .build()); app.synth(); } }
C#
using Amazon.CDK; using Amazon.CDK.AWS.S3; namespace HelloCdkApp { internal static class Program { public static void Main(string[] args) { var app = new App(); new HelloCdkStack(app, "HelloCdkStack"); app.Synth(); } } public class HelloCdkStack : Stack { public HelloCdkStack(Construct scope, string id, IStackProps props=null) : base(scope, id, props) { new Bucket(this, "MyFirstBucket", new BucketProps { Versioned = true }); } } }
Go
func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) awss3.NewBucket(stack, jsii.String("MyFirstBucket"), &awss3.BucketProps{ Versioned: jsii.Bool(true), }) return stack }

Trabalhar com constructos

Trabalhar com constructos L1

Constructos L1 mapeiam diretamente para recursos individuais do AWS CloudFormation. Você mesmo deve fornecer a configuração necessária para o recurso.

Neste exemplo, criamos um objeto de bucket usando o constructo L1 CfnBucket:

TypeScript
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", { bucketName: "amzn-s3-demo-bucket" });
JavaScript
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", { bucketName: "amzn-s3-demo-bucket" });
Python
bucket = s3.CfnBucket(self, "amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket")
Java
CfnBucket bucket = new CfnBucket.Builder().bucketName("amzn-s3-demo-bucket").build();
C#
var bucket = new CfnBucket(this, "amzn-s3-demo-bucket", new CfnBucketProps { BucketName= "amzn-s3-demo-bucket" });
Go
awss3.NewCfnBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.CfnBucketProps{ BucketName: jsii.String("amzn-s3-demo-bucket"), })

Propriedades de constructo que não são simples booleanos, strings, números ou contêineres são tratados de forma diferente nas linguagens compatíveis.

TypeScript
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", { bucketName: "amzn-s3-demo-bucket", corsConfiguration: { corsRules: [{ allowedOrigins: ["*"], allowedMethods: ["GET"] }] } });
JavaScript
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", { bucketName: "amzn-s3-demo-bucket", corsConfiguration: { corsRules: [{ allowedOrigins: ["*"], allowedMethods: ["GET"] }] } });
Python

Em Python, essas propriedades são representadas por tipos definidos como classes internas do constructo L1. Por exemplo, a propriedade opcional cors_configuration de um CfnBucket requer um wrapper do tipo CfnBucket.CorsConfigurationProperty. Aqui estamos definindo cors_configuration em uma instância CfnBucket.

bucket = CfnBucket(self, "amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket", cors_configuration=CfnBucket.CorsConfigurationProperty( cors_rules=[CfnBucket.CorsRuleProperty( allowed_origins=["*"], allowed_methods=["GET"] )] ) )
Java

Em Java, essas propriedades são representadas por tipos definidos como classes internas do constructo L1. Por exemplo, a propriedade opcional corsConfiguration de um CfnBucket requer um wrapper do tipo CfnBucket.CorsConfigurationProperty. Aqui estamos definindo corsConfiguration em uma instância CfnBucket.

CfnBucket bucket = CfnBucket.Builder.create(this, "amzn-s3-demo-bucket") .bucketName("amzn-s3-demo-bucket") .corsConfiguration(new CfnBucket.CorsConfigurationProperty.Builder() .corsRules(Arrays.asList(new CfnBucket.CorsRuleProperty.Builder() .allowedOrigins(Arrays.asList("*")) .allowedMethods(Arrays.asList("GET")) .build())) .build()) .build();
C#

Em C#, essas propriedades são representadas por tipos definidos como classes internas do constructo L1. Por exemplo, a propriedade opcional CorsConfiguration de um CfnBucket requer um wrapper do tipo CfnBucket.CorsConfigurationProperty. Aqui estamos definindo CorsConfiguration em uma instância CfnBucket.

var bucket = new CfnBucket(this, "amzn-s3-demo-bucket", new CfnBucketProps { BucketName = "amzn-s3-demo-bucket", CorsConfiguration = new CfnBucket.CorsConfigurationProperty { CorsRules = new object[] { new CfnBucket.CorsRuleProperty { AllowedOrigins = new string[] { "*" }, AllowedMethods = new string[] { "GET" }, } } } });
Go

Em Go, esses tipos são nomeados usando o nome do constructo L1, um sublinhado e o nome da propriedade. Por exemplo, a propriedade opcional CorsConfiguration de um CfnBucket requer um wrapper do tipo CfnBucket_CorsConfigurationProperty. Aqui estamos definindo CorsConfiguration em uma instância CfnBucket.

awss3.NewCfnBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.CfnBucketProps{ BucketName: jsii.String("amzn-s3-demo-bucket"), CorsConfiguration: &awss3.CfnBucket_CorsConfigurationProperty{ CorsRules: []awss3.CorsRule{ awss3.CorsRule{ AllowedOrigins: jsii.Strings("*"), AllowedMethods: &[]awss3.HttpMethods{"GET"}, }, }, }, })
Importante

Você não pode usar tipos de propriedade L2 com constructos L1 ou vice-versa. Ao trabalhar com constructos L1, sempre use os tipos definidos para o constructo L1 que você está usando. Não use tipos de outros constructos L1 (alguns podem ter o mesmo nome, mas não são do mesmo tipo).

Algumas de nossas referências de API específicas da linguagem atualmente têm erros nos caminhos para os tipos de propriedades L1 ou não documentam essas classes. Esperamos corrigir isso em breve. Enquanto isso, lembre-se de que esses tipos são sempre classes internas do constructo L1 com o qual são usados.

Trabalhar com constructos L2

No exemplo a seguir, definimos um bucket do Amazon S3 criando um objeto a partir do constructo L2 do Bucket:

TypeScript
import * as s3 from 'aws-cdk-lib/aws-s3'; // "this" is HelloCdkStack new s3.Bucket(this, 'MyFirstBucket', { versioned: true });
JavaScript
const s3 = require('aws-cdk-lib/aws-s3'); // "this" is HelloCdkStack new s3.Bucket(this, 'MyFirstBucket', { versioned: true });
Python
import aws_cdk.aws_s3 as s3 # "self" is HelloCdkStack s3.Bucket(self, "MyFirstBucket", versioned=True)
Java
import software.amazon.awscdk.services.s3.*; public class HelloCdkStack extends Stack { public HelloCdkStack(final Construct scope, final String id) { this(scope, id, null); } public HelloCdkStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); Bucket.Builder.create(this, "MyFirstBucket") .versioned(true).build(); } }
C#
using Amazon.CDK.AWS.S3; // "this" is HelloCdkStack new Bucket(this, "MyFirstBucket", new BucketProps { Versioned = true });
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2/awss3" "github.com/aws/jsii-runtime-go" ) // stack is HelloCdkStack awss3.NewBucket(stack, jsii.String("MyFirstBucket"), &awss3.BucketProps{ Versioned: jsii.Bool(true), })>

MyFirstBucket não é o nome do bucket que o AWS CloudFormation cria. É um identificador lógico fornecido ao novo constructo dentro do contexto do seu aplicativo do CDK. O valor physicalName será usado para nomear o recurso do AWS CloudFormation.

Trabalhar com constructos de terceiros

O Construct Hub é um recurso que ajuda você a descobrir constructos adicionais da AWS, de terceiros e da comunidade de código aberto do AWS CDK.

Escrever seus próprios constructos

Além de usar constructos existentes, você também pode escrever seus próprios constructos e permitir que qualquer pessoa os use em seus aplicativos. Todos os constructos são iguais no AWS CDK. Os constructos da Biblioteca de Constructos da AWS são tratados da mesma forma que um constructo de uma biblioteca terceirizada publicada via NPM, Maven ou PyPI. Os constructos publicados no repositório interno de pacotes da sua empresa também são tratados da mesma forma.

Para declarar um novo constructo, crie uma classe que estenda a classe de base do Constructo no pacote constructs e siga o padrão dos argumentos do inicializador.

O exemplo a seguir mostra como declarar um constructo que representa um bucket do Amazon S3. O bucket do S3 envia uma notificação do Amazon Simple Notification Service (Amazon SNS) toda vez que alguém faz upload de um arquivo para ele.

TypeScript
export interface NotifyingBucketProps { prefix?: string; } export class NotifyingBucket extends Construct { constructor(scope: Construct, id: string, props: NotifyingBucketProps = {}) { super(scope, id); const bucket = new s3.Bucket(this, 'bucket'); const topic = new sns.Topic(this, 'topic'); bucket.addObjectCreatedNotification(new s3notify.SnsDestination(topic), { prefix: props.prefix }); } }
JavaScript
class NotifyingBucket extends Construct { constructor(scope, id, props = {}) { super(scope, id); const bucket = new s3.Bucket(this, 'bucket'); const topic = new sns.Topic(this, 'topic'); bucket.addObjectCreatedNotification(new s3notify.SnsDestination(topic), { prefix: props.prefix }); } } module.exports = { NotifyingBucket }
Python
class NotifyingBucket(Construct): def __init__(self, scope: Construct, id: str, *, prefix=None): super().__init__(scope, id) bucket = s3.Bucket(self, "bucket") topic = sns.Topic(self, "topic") bucket.add_object_created_notification(s3notify.SnsDestination(topic), s3.NotificationKeyFilter(prefix=prefix))
Java
public class NotifyingBucket extends Construct { public NotifyingBucket(final Construct scope, final String id) { this(scope, id, null, null); } public NotifyingBucket(final Construct scope, final String id, final BucketProps props) { this(scope, id, props, null); } public NotifyingBucket(final Construct scope, final String id, final String prefix) { this(scope, id, null, prefix); } public NotifyingBucket(final Construct scope, final String id, final BucketProps props, final String prefix) { super(scope, id); Bucket bucket = new Bucket(this, "bucket"); Topic topic = new Topic(this, "topic"); if (prefix != null) bucket.addObjectCreatedNotification(new SnsDestination(topic), NotificationKeyFilter.builder().prefix(prefix).build()); } }
C#
public class NotifyingBucketProps : BucketProps { public string Prefix { get; set; } } public class NotifyingBucket : Construct { public NotifyingBucket(Construct scope, string id, NotifyingBucketProps props = null) : base(scope, id) { var bucket = new Bucket(this, "bucket"); var topic = new Topic(this, "topic"); bucket.AddObjectCreatedNotification(new SnsDestination(topic), new NotificationKeyFilter { Prefix = props?.Prefix }); } }
Go
type NotifyingBucketProps struct { awss3.BucketProps Prefix *string } func NewNotifyingBucket(scope constructs.Construct, id *string, props *NotifyingBucketProps) awss3.Bucket { var bucket awss3.Bucket if props == nil { bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), nil) } else { bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), &props.BucketProps) } topic := awssns.NewTopic(scope, jsii.String(*id+"Topic"), nil) if props == nil { bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic)) } else { bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic), &awss3.NotificationKeyFilter{ Prefix: props.Prefix, }) } return bucket }
nota

Nosso constructo NotifyingBucket não herda não do Bucket, mas sim do Construct. Estamos usando composição, não herança, para agrupar um bucket do Amazon S3 e um tópico do Amazon SNS. Em geral, a composição tem preferência sobre a herança no desenvolvimento de constructos do AWS CDK.

O construtor NotifyingBucket tem uma assinatura de constructo típica: scope, id e props. O último argumento, props, é opcional (obtém o valor padrão {}) porque todos os props são opcionais. (A classe de base do Construct não aceita um argumento props.) Você pode definir uma instância desse constructo em seu aplicativo sem props, por exemplo:

TypeScript
new NotifyingBucket(this, 'MyNotifyingBucket');
JavaScript
new NotifyingBucket(this, 'MyNotifyingBucket');
Python
NotifyingBucket(self, "MyNotifyingBucket")
Java
new NotifyingBucket(this, "MyNotifyingBucket");
C#
new NotifyingBucket(this, "MyNotifyingBucket");
Go
NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), nil)

Ou você pode usar props (em Java, um parâmetro adicional) para especificar o prefixo do caminho a ser filtrado, por exemplo:

TypeScript
new NotifyingBucket(this, 'MyNotifyingBucket', { prefix: 'images/' });
JavaScript
new NotifyingBucket(this, 'MyNotifyingBucket', { prefix: 'images/' });
Python
NotifyingBucket(self, "MyNotifyingBucket", prefix="images/")
Java
new NotifyingBucket(this, "MyNotifyingBucket", "/images");
C#
new NotifyingBucket(this, "MyNotifyingBucket", new NotifyingBucketProps { Prefix = "/images" });
Go
NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), &NotifyingBucketProps{ Prefix: jsii.String("images/"), })

Normalmente, você também gostaria de expor algumas propriedades ou métodos em seus constructos. Não é muito útil ter um tópico escondido atrás de seu constructo, porque os usuários de seu constructo não conseguem assiná-lo. Adicionar uma propriedade topic permite que os consumidores acessem o tópico interno, conforme mostrado no exemplo a seguir:

TypeScript
export class NotifyingBucket extends Construct { public readonly topic: sns.Topic; constructor(scope: Construct, id: string, props: NotifyingBucketProps) { super(scope, id); const bucket = new s3.Bucket(this, 'bucket'); this.topic = new sns.Topic(this, 'topic'); bucket.addObjectCreatedNotification(new s3notify.SnsDestination(this.topic), { prefix: props.prefix }); } }
JavaScript
class NotifyingBucket extends Construct { constructor(scope, id, props) { super(scope, id); const bucket = new s3.Bucket(this, 'bucket'); this.topic = new sns.Topic(this, 'topic'); bucket.addObjectCreatedNotification(new s3notify.SnsDestination(this.topic), { prefix: props.prefix }); } } module.exports = { NotifyingBucket };
Python
class NotifyingBucket(Construct): def __init__(self, scope: Construct, id: str, *, prefix=None, **kwargs): super().__init__(scope, id) bucket = s3.Bucket(self, "bucket") self.topic = sns.Topic(self, "topic") bucket.add_object_created_notification(s3notify.SnsDestination(self.topic), s3.NotificationKeyFilter(prefix=prefix))
Java
public class NotifyingBucket extends Construct { public Topic topic = null; public NotifyingBucket(final Construct scope, final String id) { this(scope, id, null, null); } public NotifyingBucket(final Construct scope, final String id, final BucketProps props) { this(scope, id, props, null); } public NotifyingBucket(final Construct scope, final String id, final String prefix) { this(scope, id, null, prefix); } public NotifyingBucket(final Construct scope, final String id, final BucketProps props, final String prefix) { super(scope, id); Bucket bucket = new Bucket(this, "bucket"); topic = new Topic(this, "topic"); if (prefix != null) bucket.addObjectCreatedNotification(new SnsDestination(topic), NotificationKeyFilter.builder().prefix(prefix).build()); } }
C#
public class NotifyingBucket : Construct { public readonly Topic topic; public NotifyingBucket(Construct scope, string id, NotifyingBucketProps props = null) : base(scope, id) { var bucket = new Bucket(this, "bucket"); topic = new Topic(this, "topic"); bucket.AddObjectCreatedNotification(new SnsDestination(topic), new NotificationKeyFilter { Prefix = props?.Prefix }); } }
Go

Para fazer isso em Go, precisaremos de um pouco mais de encanamento. Nossa função original NewNotifyingBucket retornou um awss3.Bucket. Precisaremos estender o Bucket para incluir um membro do topic criando uma estrutura NotifyingBucket. Nossa função então retornará esse tipo.

type NotifyingBucket struct { awss3.Bucket topic awssns.Topic } func NewNotifyingBucket(scope constructs.Construct, id *string, props *NotifyingBucketProps) NotifyingBucket { var bucket awss3.Bucket if props == nil { bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), nil) } else { bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), &props.BucketProps) } topic := awssns.NewTopic(scope, jsii.String(*id+"Topic"), nil) if props == nil { bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic)) } else { bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic), &awss3.NotificationKeyFilter{ Prefix: props.Prefix, }) } var nbucket NotifyingBucket nbucket.Bucket = bucket nbucket.topic = topic return nbucket }

Agora, os consumidores podem assinar o tópico, por exemplo:

TypeScript
const queue = new sqs.Queue(this, 'NewImagesQueue'); const images = new NotifyingBucket(this, '/images'); images.topic.addSubscription(new sns_sub.SqsSubscription(queue));
JavaScript
const queue = new sqs.Queue(this, 'NewImagesQueue'); const images = new NotifyingBucket(this, '/images'); images.topic.addSubscription(new sns_sub.SqsSubscription(queue));
Python
queue = sqs.Queue(self, "NewImagesQueue") images = NotifyingBucket(self, prefix="Images") images.topic.add_subscription(sns_sub.SqsSubscription(queue))
Java
NotifyingBucket images = new NotifyingBucket(this, "MyNotifyingBucket", "/images"); images.topic.addSubscription(new SqsSubscription(queue));
C#
var queue = new Queue(this, "NewImagesQueue"); var images = new NotifyingBucket(this, "MyNotifyingBucket", new NotifyingBucketProps { Prefix = "/images" }); images.topic.AddSubscription(new SqsSubscription(queue));
Go
queue := awssqs.NewQueue(stack, jsii.String("NewImagesQueue"), nil) images := NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), &NotifyingBucketProps{ Prefix: jsii.String("/images"), }) images.topic.AddSubscription(awssnssubscriptions.NewSqsSubscription(queue, nil))

Saiba mais

O vídeo a seguir fornece uma visão geral abrangente dos constructos do CDK e explica como você pode usá-los em seus aplicativos do CDK.