Cloud & Infraestrutura

O que Todo Dev Deve Saber sobre AWS CDK Avançado: Constructs, Stacks e Pipelines com CDK Pipelines

6 min de leitura

O que Todo Dev Deve Saber sobre AWS CDK Avançado: Constructs, Stacks e Pipelines com CDK Pipelines

Fundamentos do AWS CDK: Constructs e Stacks O AWS CDK (Cloud Development Kit) é um framework que permite definir infraestrutura como código usando linguagens de programação familiar. Um Construct é o bloco de construção fundamental — representa um componente de nuvem (EC2, S3, Lambda) ou um agrupamento lógico deles. Você combina Constructs para criar aplicações complexas. Uma Stack é um container que agrupa Constructs e mapeia para um CloudFormation template. Cada Stack pode ser deployada independentemente. Vamos ver como estruturar isso: Observe como exportamos o bucket para reutilização em outras Stacks. Isso é essencial para composição. Constructs Avançados e Composição Constructs de alto nível (L3) encapsulam lógica complexa em abstrações reutilizáveis. Em vez de gerenciar IAM, VPC e segurança manualmente, você constrói Constructs customizados que herdam de base. O padrão aqui é aceitar um interface para configurabilidade. Isso permite que sua Stack seja parametrizada e reutilizável em múltiplos contextos. CDK Pipelines: CI/CD Declarativo O CDK Pipelines é o padrão mais

<h2>Fundamentos do AWS CDK: Constructs e Stacks</h2>

<p>O AWS CDK (Cloud Development Kit) é um framework que permite definir infraestrutura como código usando linguagens de programação familiar. Um <strong>Construct</strong> é o bloco de construção fundamental — representa um componente de nuvem (EC2, S3, Lambda) ou um agrupamento lógico deles. Você combina Constructs para criar aplicações complexas.</p>

<p>Uma <strong>Stack</strong> é um container que agrupa Constructs e mapeia para um CloudFormation template. Cada Stack pode ser deployada independentemente. Vamos ver como estruturar isso:</p>

<pre><code class="language-typescript">import * as cdk from &#039;aws-cdk-lib&#039;;

import * as s3 from &#039;aws-cdk-lib/aws-s3&#039;;

import * as lambda from &#039;aws-cdk-lib/aws-lambda&#039;;

export class StorageStack extends cdk.Stack {

public readonly bucket: s3.Bucket;

constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {

super(scope, id, props);

// Criando um S3 bucket customizado

this.bucket = new s3.Bucket(this, &#039;DataBucket&#039;, {

versioned: true,

encryption: s3.BucketEncryption.S3_MANAGED,

blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,

removalPolicy: cdk.RemovalPolicy.RETAIN,

});

// Lambda para processar arquivos

const processor = new lambda.Function(this, &#039;Processor&#039;, {

runtime: lambda.Runtime.NODEJS_18_X,

handler: &#039;index.handler&#039;,

code: lambda.Code.fromAsset(&#039;lambda&#039;),

});

this.bucket.grantReadWrite(processor);

}

}</code></pre>

<p>Observe como exportamos o bucket para reutilização em outras Stacks. Isso é essencial para composição.</p>

<h2>Constructs Avançados e Composição</h2>

<p>Constructs de alto nível (L3) encapsulam lógica complexa em abstrações reutilizáveis. Em vez de gerenciar IAM, VPC e segurança manualmente, você constrói Constructs customizados que herdam de <code>Construct</code> base.</p>

<pre><code class="language-typescript">import * as cdk from &#039;aws-cdk-lib&#039;;

import * as ec2 from &#039;aws-cdk-lib/aws-ec2&#039;;

import * as iam from &#039;aws-cdk-lib/aws-iam&#039;;

interface SecureWebServerProps extends cdk.StackProps {

instanceType: ec2.InstanceType;

machineImage: ec2.IMachineImage;

}

export class SecureWebServer extends cdk.Stack {

constructor(scope: cdk.App, id: string, props: SecureWebServerProps) {

super(scope, id, props);

const vpc = new ec2.Vpc(this, &#039;VPC&#039;, {

maxAzs: 2,

cidrMask: 24,

});

const securityGroup = new ec2.SecurityGroup(this, &#039;SG&#039;, {

vpc,

description: &#039;Security group for web server&#039;,

allowAllOutbound: true,

});

securityGroup.addIngressRule(

ec2.Peer.anyIpv4(),

ec2.Port.tcp(80),

&#039;Allow HTTP&#039;

);

const instance = new ec2.Instance(this, &#039;Instance&#039;, {

vpc,

instanceType: props.instanceType,

machineImage: props.machineImage,

securityGroup,

});

new cdk.CfnOutput(this, &#039;InstanceIP&#039;, {

value: instance.instancePublicIp,

});

}

}</code></pre>

<p>O padrão aqui é aceitar um <code>props</code> interface para configurabilidade. Isso permite que sua Stack seja parametrizada e reutilizável em múltiplos contextos.</p>

<h2>CDK Pipelines: CI/CD Declarativo</h2>

<p>O <strong>CDK Pipelines</strong> é o padrão mais poderoso: você define seu pipeline de deployment como código. O pipeline é autossuficiente — ele se autodeploya e sincroniza com seu repositório.</p>

<pre><code class="language-typescript">import * as cdk from &#039;aws-cdk-lib&#039;;

import * as codepipeline from &#039;aws-cdk-lib/aws-codepipeline&#039;;

import * as codepipeline_actions from &#039;aws-cdk-lib/aws-codepipeline-actions&#039;;

import { CodePipeline, CodePipelineSource, ShellStep } from &#039;aws-cdk-lib/pipelines&#039;;

export class PipelineStack extends cdk.Stack {

constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {

super(scope, id, props);

const pipeline = new CodePipeline(this, &#039;Pipeline&#039;, {

pipelineName: &#039;MyAppPipeline&#039;,

synth: new ShellStep(&#039;Synth&#039;, {

input: CodePipelineSource.gitHub(&#039;seu-user/seu-repo&#039;, &#039;main&#039;, {

authentication: cdk.SecretValue.secretsManager(&#039;github-token&#039;),

}),

commands: [

&#039;npm install&#039;,

&#039;npm run build&#039;,

&#039;npx cdk synth&#039;,

],

}),

});

// Estágio de desenvolvimento

const devStage = pipeline.addStage(

new ApplicationStage(this, &#039;Dev&#039;, {

env: { account: &#039;111111111111&#039;, region: &#039;us-east-1&#039; },

})

);

devStage.addPost(

new ShellStep(&#039;TestDev&#039;, {

commands: [

&#039;npm install&#039;,

&#039;npm test&#039;,

],

})

);

// Estágio de produção com aprovação manual

const prodStage = pipeline.addStage(

new ApplicationStage(this, &#039;Prod&#039;, {

env: { account: &#039;222222222222&#039;, region: &#039;us-east-1&#039; },

})

);

prodStage.addPre(

new codepipeline_actions.ManualApprovalAction({

actionName: &#039;ApproveProduction&#039;,

}) as any

);

}

}

export class ApplicationStage extends cdk.Stage {

constructor(scope: cdk.Construct, id: string, props?: cdk.StageProps) {

super(scope, id, props);

new StorageStack(this, &#039;Storage&#039;);

new SecureWebServer(this, &#039;WebServer&#039;, {

instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),

machineImage: ec2.AmazonLinuxImage.latestAmazonLinux2(),

} as any);

}

}</code></pre>

<p>O pipeline sincroniza automaticamente com seu repositório GitHub. Quando você faz push, o synth executa, gera o CloudFormation e deploya os estágios sequencialmente. Adicione testes, aprovações manuais e validações conforme necessário.</p>

<h2>Boas Práticas e Patterns</h2>

<h3>Separação de Responsabilidades</h3>

<p>Organize seu código em múltiplos arquivos: uma Stack por arquivo, Constructs customizados isolados, configurações centralizadas. Isso torna projetos escaláveis.</p>

<h3>Contexto e Configuração</h3>

<p>Use valores de contexto para parametrizar comportamentos sem hardcode:</p>

<pre><code class="language-typescript">const isDev = this.node.tryGetContext(&#039;env&#039;) === &#039;dev&#039;;

const bucketRetention = isDev ? cdk.RemovalPolicy.DESTROY : cdk.RemovalPolicy.RETAIN;</code></pre>

<h3>Validação em Tempo de Síntese</h3>

<p>Valide Constructs durante a síntese para falhar rápido:</p>

<pre><code class="language-typescript">if (!props.domainName) {

throw new Error(&#039;domainName é obrigatório&#039;);

}</code></pre>

<h2>Conclusão</h2>

<p>Dominar AWS CDK exige entender três pilares: <strong>Constructs</strong> como blocos reutilizáveis com responsabilidades bem definidas, <strong>Stacks</strong> como unidades de deployment lógicas e compostas, e <strong>CDK Pipelines</strong> como a ferramenta que automatiza e torna repetível todo o ciclo de infraestrutura-como-código. Comece com Stacks simples, evolua para Constructs customizados de alto nível, e implemente pipelines quando sua infraestrutura crescer. O poder real vem da composição: Constructs dentro de Stacks dentro de Stages dentro de Pipelines.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://docs.aws.amazon.com/cdk/" target="_blank" rel="noopener noreferrer">AWS CDK Documentation</a></li>

<li><a href="https://docs.aws.amazon.com/cdk/v2/guide/cdk_pipeline.html" target="_blank" rel="noopener noreferrer">AWS CDK Pipelines Guide</a></li>

<li><a href="https://github.com/aws-samples/aws-cdk-examples" target="_blank" rel="noopener noreferrer">CDK Examples Repository</a></li>

<li><a href="https://www.oreilly.com/library/view/infrastructure-as-code/9781491924334/" target="_blank" rel="noopener noreferrer">Infrastructure as Code: Dynamic Systems for the Cloud Age - Kief Morris</a></li>

</ul>

Comentários

Mais em Cloud & Infraestrutura

Dominando Redshift e Athena: Data Warehouse e Query Serverless em S3 em Projetos Reais
Dominando Redshift e Athena: Data Warehouse e Query Serverless em S3 em Projetos Reais

Entendendo Redshift e Athena: Duas Abordagens para Data Warehouse Redshift e...

Amazon Inspector e Trusted Advisor: Vulnerabilidades e Boas Práticas na Prática
Amazon Inspector e Trusted Advisor: Vulnerabilidades e Boas Práticas na Prática

Amazon Inspector: Análise Automatizada de Vulnerabilidades Amazon Inspector é...

Como Usar AWS CLI e AWS SDK: Automação e Scripting de Infraestrutura em Produção
Como Usar AWS CLI e AWS SDK: Automação e Scripting de Infraestrutura em Produção

Diferença Entre AWS CLI e AWS SDK A AWS CLI (Command Line Interface) e o AWS...