Personalizando construções da Construct Library AWS - AWS Cloud Development Kit (AWS CDK) v2

Este é o Guia do Desenvolvedor AWS CDK v2. O CDK v1 antigo 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á.

Personalizando construções da Construct Library AWS

Personalize construções da AWS Construct Library por meio de escotilhas de escape, substituições brutas e recursos personalizados.

Usando escotilhas de escape

A AWS Construct Library fornece construções de vários níveis de abstração.

No nível mais alto, seu AWS CDK aplicativo e as pilhas nele contidas são, em si, abstrações de toda a sua infraestrutura de nuvem ou de partes significativas dela. Eles podem ser parametrizados para implantá-los em diferentes ambientes ou para diferentes necessidades.

As abstrações são ferramentas poderosas para projetar e implementar aplicativos em nuvem. AWS CDK Isso lhe dá o poder não apenas de construir com suas abstrações, mas também de criar novas abstrações. Usando as construções L2 e L3 de código aberto existentes como orientação, você pode criar suas próprias construções L2 e L3 para refletir as melhores práticas e opiniões de sua própria organização.

Nenhuma abstração é perfeita, e mesmo boas abstrações não podem cobrir todos os casos de uso possíveis. Durante o desenvolvimento, você pode encontrar uma construção que quase atenda às suas necessidades, exigindo uma personalização pequena ou grande.

Por esse motivo, AWS CDK fornece maneiras de sair do modelo de construção. Isso inclui mudar para uma abstração de nível inferior ou para um modelo totalmente diferente. As escotilhas de escape permitem que você escape do AWS CDK paradigma e o personalize de forma que atenda às suas necessidades. Em seguida, você pode agrupar suas alterações em uma nova construção para abstrair a complexidade subjacente e fornecer uma API limpa para outros desenvolvedores.

Veja a seguir exemplos de situações em que você pode usar escotilhas de escape:

  • Um recurso AWS de serviço está disponível por meio AWS CloudFormation dele, mas não há construções L2 para ele.

  • Um recurso AWS de serviço está disponível por meio de AWS CloudFormation, e há construções L2 para o serviço, mas elas ainda não expõem o recurso. Como as construções L2 são selecionadas pela equipe do CDK, elas podem não estar imediatamente disponíveis para novos recursos.

  • O recurso ainda não está disponível por meio AWS CloudFormation de nada.

    Para determinar se um recurso está disponível por meio de AWS CloudFormation, consulte Referência de tipos de AWS recursos e propriedades.

Desenvolva escotilhas de escape para construções L1

Se as construções L2 não estiverem disponíveis para o serviço, você poderá usar as construções L1 geradas automaticamente. Esses recursos podem ser reconhecidos pelo nome que começa comCfn, como CfnBucket ouCfnRole. Você os instancia exatamente como usaria o recurso equivalente AWS CloudFormation .

Por exemplo, para instanciar um bucket L1 de baixo nível do Amazon S3 com análises ativadas, você escreveria algo como o seguinte.

TypeScript
new s3.CfnBucket(this, 'MyBucket', { analyticsConfigurations: [ { id: 'Config', // ... } ] });
JavaScript
new s3.CfnBucket(this, 'MyBucket', { analyticsConfigurations: [ { id: 'Config' // ... } ] });
Python
s3.CfnBucket(self, "MyBucket", analytics_configurations: [ dict(id="Config", # ... ) ] )
Java
CfnBucket.Builder.create(this, "MyBucket") .analyticsConfigurations(Arrays.asList(java.util.Map.of( // Java 9 or later "id", "Config", // ... ))).build();
C#
new CfnBucket(this, 'MyBucket', new CfnBucketProps { AnalyticsConfigurations = new Dictionary<string, string> { ["id"] = "Config", // ... } });

Pode haver casos raros em que você queira definir um recurso que não tenha uma CfnXxx classe correspondente. Esse pode ser um novo tipo de recurso que ainda não foi publicado na especificação do AWS CloudFormation recurso. Em casos como esse, você pode instanciar o cdk.CfnResource diretamente e especificar o tipo e as propriedades do recurso. Isso é mostrado no exemplo a seguir.

TypeScript
new cdk.CfnResource(this, 'MyBucket', { type: 'AWS::S3::Bucket', properties: { // Note the PascalCase here! These are CloudFormation identifiers. AnalyticsConfigurations: [ { Id: 'Config', // ... } ] } });
JavaScript
new cdk.CfnResource(this, 'MyBucket', { type: 'AWS::S3::Bucket', properties: { // Note the PascalCase here! These are CloudFormation identifiers. AnalyticsConfigurations: [ { Id: 'Config' // ... } ] } });
Python
cdk.CfnResource(self, 'MyBucket', type="AWS::S3::Bucket", properties=dict( # Note the PascalCase here! These are CloudFormation identifiers. "AnalyticsConfigurations": [ { "Id": "Config", # ... } ] } )
Java
CfnResource.Builder.create(this, "MyBucket") .type("AWS::S3::Bucket") .properties(java.util.Map.of( // Map.of requires Java 9 or later // Note the PascalCase here! These are CloudFormation identifiers "AnalyticsConfigurations", Arrays.asList( java.util.Map.of("Id", "Config", // ... )))) .build();
C#
new CfnResource(this, "MyBucket", new CfnResourceProps { Type = "AWS::S3::Bucket", Properties = new Dictionary<string, object> { // Note the PascalCase here! These are CloudFormation identifiers ["AnalyticsConfigurations"] = new Dictionary<string, string>[] { new Dictionary<string, string> { ["Id"] = "Config" } } } });

Desenvolva escotilhas de escape para construções L2

Se uma construção L2 não tiver um recurso ou você estiver tentando contornar um problema, você pode modificar a construção L1 que está encapsulada pela construção L2.

Todas as construções L2 contêm dentro delas a construção L1 correspondente. Por exemplo, a construção de alto nível envolve a Bucket construção de baixo CfnBucket nível. Como CfnBucket corresponde diretamente ao AWS CloudFormation recurso, ele expõe todos os recursos que estão disponíveis por meio AWS CloudFormation de.

A abordagem básica para obter acesso à construção L1 é usar construct.node.defaultChild (Pythondefault_child:), convertê-la para o tipo certo (se necessário) e modificar suas propriedades. Novamente, vamos dar o exemplo de umBucket.

TypeScript
// Get the CloudFormation resource const cfnBucket = bucket.node.defaultChild as s3.CfnBucket; // Change its properties cfnBucket.analyticsConfiguration = [ { id: 'Config', // ... } ];
JavaScript
// Get the CloudFormation resource const cfnBucket = bucket.node.defaultChild; // Change its properties cfnBucket.analyticsConfiguration = [ { id: 'Config' // ... } ];
Python
# Get the CloudFormation resource cfn_bucket = bucket.node.default_child # Change its properties cfn_bucket.analytics_configuration = [ { "id": "Config", # ... } ]
Java
// Get the CloudFormation resource CfnBucket cfnBucket = (CfnBucket)bucket.getNode().getDefaultChild(); cfnBucket.setAnalyticsConfigurations( Arrays.asList(java.util.Map.of( // Java 9 or later "Id", "Config", // ... ));
C#
// Get the CloudFormation resource var cfnBucket = (CfnBucket)bucket.Node.DefaultChild; cfnBucket.AnalyticsConfigurations = new List<object> { new Dictionary<string, string> { ["Id"] = "Config", // ... } };

Você também pode usar esse objeto para alterar AWS CloudFormation opções como Metadata UpdatePolicy e.

TypeScript
cfnBucket.cfnOptions.metadata = { MetadataKey: 'MetadataValue' };
JavaScript
cfnBucket.cfnOptions.metadata = { MetadataKey: 'MetadataValue' };
Python
cfn_bucket.cfn_options.metadata = { "MetadataKey": "MetadataValue" }
Java
cfnBucket.getCfnOptions().setMetadata(java.util.Map.of( // Java 9+ "MetadataKey", "Metadatavalue"));
C#
cfnBucket.CfnOptions.Metadata = new Dictionary<string, object> { ["MetadataKey"] = "Metadatavalue" };

Escotilhas anti-fuga

Isso AWS CDK também fornece a capacidade de subir um nível de abstração, que podemos chamar de escotilha de “saída”. Se você tiver uma construção L1, comoCfnBucket, você pode criar uma nova construção L2 (Bucketnesse caso) para encapsular a construção L1.

Isso é conveniente quando você cria um recurso L1, mas deseja usá-lo com uma construção que requer um recurso L2. Também é útil quando você deseja usar métodos de conveniência como esses .grantXxxxx() que não estão disponíveis na construção L1.

Você passa para o nível de abstração mais alto usando um método estático na classe L2 chamado .fromCfnXxxxx() —por exemplo, para buckets do Amazon Bucket.fromCfnBucket() S3. O recurso L1 é o único parâmetro.

TypeScript
b1 = new s3.CfnBucket(this, "buck09", { ... }); b2 = s3.Bucket.fromCfnBucket(b1);
JavaScript
b1 = new s3.CfnBucket(this, "buck09", { ...} ); b2 = s3.Bucket.fromCfnBucket(b1);
Python
b1 = s3.CfnBucket(self, "buck09", ...) b2 = s3.from_cfn_bucket(b1)
Java
CfnBucket b1 = CfnBucket.Builder.create(this, "buck09") // .... .build(); IBucket b2 = Bucket.fromCfnBucket(b1);
C#
var b1 = new CfnBucket(this, "buck09", new CfnBucketProps { ... }); var v2 = Bucket.FromCfnBucket(b1);

As construções L2 criadas a partir de construções L1 são objetos proxy que se referem ao recurso L1, semelhantes às criadas a partir de nomes de recursos, ARNs ou pesquisas. As modificações nessas construções não afetam o AWS CloudFormation modelo final sintetizado (já que você tem o recurso L1, no entanto, você pode modificá-lo). Para obter mais informações sobre objetos proxy, consulteReferenciando recursos em sua conta AWS.

Para evitar confusão, não crie várias construções L2 que se refiram à mesma construção L1. Por exemplo, se você extrair o CfnBucket de a Bucket usando a técnica da seção anterior, você não deve criar uma segunda Bucket instância chamando Bucket.fromCfnBucket() com issoCfnBucket. Na verdade, funciona conforme o esperado (apenas um AWS::S3::Bucket é sintetizado), mas dificulta a manutenção do código.

Substituições brutas

Se faltarem propriedades na construção L1, você poderá ignorar toda a digitação usando substituições brutas. Isso também possibilita a exclusão de propriedades sintetizadas.

Use um dos addOverride métodos method (Python:add_override), conforme mostrado no exemplo a seguir.

TypeScript
// Get the CloudFormation resource const cfnBucket = bucket.node.defaultChild as s3.CfnBucket; // Use dot notation to address inside the resource template fragment cfnBucket.addOverride('Properties.VersioningConfiguration.Status', 'NewStatus'); cfnBucket.addDeletionOverride('Properties.VersioningConfiguration.Status'); // use index (0 here) to address an element of a list cfnBucket.addOverride('Properties.Tags.0.Value', 'NewValue'); cfnBucket.addDeletionOverride('Properties.Tags.0'); // addPropertyOverride is a convenience function for paths starting with "Properties." cfnBucket.addPropertyOverride('VersioningConfiguration.Status', 'NewStatus'); cfnBucket.addPropertyDeletionOverride('VersioningConfiguration.Status'); cfnBucket.addPropertyOverride('Tags.0.Value', 'NewValue'); cfnBucket.addPropertyDeletionOverride('Tags.0');
JavaScript
// Get the CloudFormation resource const cfnBucket = bucket.node.defaultChild ; // Use dot notation to address inside the resource template fragment cfnBucket.addOverride('Properties.VersioningConfiguration.Status', 'NewStatus'); cfnBucket.addDeletionOverride('Properties.VersioningConfiguration.Status'); // use index (0 here) to address an element of a list cfnBucket.addOverride('Properties.Tags.0.Value', 'NewValue'); cfnBucket.addDeletionOverride('Properties.Tags.0'); // addPropertyOverride is a convenience function for paths starting with "Properties." cfnBucket.addPropertyOverride('VersioningConfiguration.Status', 'NewStatus'); cfnBucket.addPropertyDeletionOverride('VersioningConfiguration.Status'); cfnBucket.addPropertyOverride('Tags.0.Value', 'NewValue'); cfnBucket.addPropertyDeletionOverride('Tags.0');
Python
# Get the CloudFormation resource cfn_bucket = bucket.node.default_child # Use dot notation to address inside the resource template fragment cfn_bucket.add_override("Properties.VersioningConfiguration.Status", "NewStatus") cfn_bucket.add_deletion_override("Properties.VersioningConfiguration.Status") # use index (0 here) to address an element of a list cfn_bucket.add_override("Properties.Tags.0.Value", "NewValue") cfn_bucket.add_deletion_override("Properties.Tags.0") # addPropertyOverride is a convenience function for paths starting with "Properties." cfn_bucket.add_property_override("VersioningConfiguration.Status", "NewStatus") cfn_bucket.add_property_deletion_override("VersioningConfiguration.Status") cfn_bucket.add_property_override("Tags.0.Value", "NewValue") cfn_bucket.add_property_deletion_override("Tags.0")
Java
// Get the CloudFormation resource CfnBucket cfnBucket = (CfnBucket)bucket.getNode().getDefaultChild(); // Use dot notation to address inside the resource template fragment cfnBucket.addOverride("Properties.VersioningConfiguration.Status", "NewStatus"); cfnBucket.addDeletionOverride("Properties.VersioningConfiguration.Status"); // use index (0 here) to address an element of a list cfnBucket.addOverride("Properties.Tags.0.Value", "NewValue"); cfnBucket.addDeletionOverride("Properties.Tags.0"); // addPropertyOverride is a convenience function for paths starting with "Properties." cfnBucket.addPropertyOverride("VersioningConfiguration.Status", "NewStatus"); cfnBucket.addPropertyDeletionOverride("VersioningConfiguration.Status"); cfnBucket.addPropertyOverride("Tags.0.Value", "NewValue"); cfnBucket.addPropertyDeletionOverride("Tags.0");
C#
// Get the CloudFormation resource var cfnBucket = (CfnBucket)bucket.node.defaultChild; // Use dot notation to address inside the resource template fragment cfnBucket.AddOverride("Properties.VersioningConfiguration.Status", "NewStatus"); cfnBucket.AddDeletionOverride("Properties.VersioningConfiguration.Status"); // use index (0 here) to address an element of a list cfnBucket.AddOverride("Properties.Tags.0.Value", "NewValue"); cfnBucket.AddDeletionOverride("Properties.Tags.0"); // addPropertyOverride is a convenience function for paths starting with "Properties." cfnBucket.AddPropertyOverride("VersioningConfiguration.Status", "NewStatus"); cfnBucket.AddPropertyDeletionOverride("VersioningConfiguration.Status"); cfnBucket.AddPropertyOverride("Tags.0.Value", "NewValue"); cfnBucket.AddPropertyDeletionOverride("Tags.0");

Recursos personalizados

Se o recurso não estiver disponível por meio de AWS CloudFormation, mas somente por meio de uma chamada direta de API, você deverá escrever um recurso AWS CloudFormation personalizado para fazer a chamada de API necessária. Você pode usar o AWS CDK para escrever recursos personalizados e agrupá-los em uma interface de construção regular. Do ponto de vista de um consumidor de sua marca, a experiência parecerá nativa.

A criação de um recurso personalizado envolve escrever uma função Lambda que responda aos eventos do ciclo de vida e DELETE do CREATE recurso. UPDATE Se seu recurso personalizado precisar fazer apenas uma única chamada de API, considere usar AwsCustomResourceo. Isso possibilita a realização de chamadas arbitrárias do SDK durante uma AWS CloudFormation implantação. Caso contrário, você deve escrever sua própria função Lambda para realizar o trabalho necessário.

O assunto é muito amplo para ser abordado completamente aqui, mas os links a seguir devem ajudar você a começar: