Pular para o conteúdo

Infraestrutura CDK

AWS CDK é um framework para definir infraestrutura em nuvem em código e provisioná-la através do AWS CloudFormation.

O gerador de infraestrutura TypeScript cria uma aplicação de infraestrutura AWS CDK escrita em TypeScript. A aplicação gerada inclui práticas recomendadas de segurança através de verificações de segurança do Checkov.

Você pode gerar um novo projeto de infraestrutura de duas maneiras:

Terminal window
pnpm nx g @aws/nx-plugin:ts#infra
Você também pode realizar uma execução simulada para ver quais arquivos seriam alterados
Terminal window
pnpm nx g @aws/nx-plugin:ts#infra --dry-run
ParâmetroTipoPadrãoDescrição
name Obrigatóriostring-O nome da aplicação.
directory stringpackagesO diretório da nova aplicação.
subDirectory string-O subdiretório onde o projeto é colocado. Por padrão, este é o nome do projeto.
stageConfig booleanHabilita configuração centralizada de estágio (credenciais, conta, região) para implantações CDK em múltiplos ambientes.
preferInstallDependencies booleantrueSe deve preferir instalar dependências após a execução do gerador. Defina como false para adiar a instalação ao executar múltiplos geradores em lote (uma instalação ainda é executada se necessário para que geradores subsequentes possam calcular o grafo de projetos Nx); instale uma vez no final.

O gerador criará a seguinte estrutura de projeto no diretório <directory>/<name>:

  • Directorysrc
    • main.ts Application entry point instantiating CDK stages to deploy
    • Directorystages CDK Stage definitions
      • application-stage.ts Defines a collection of stacks to deploy in a stage
    • Directorystacks CDK Stack definitions
      • application-stack.ts Main application stack
  • cdk.json CDK configuration
  • package.json Project manifest defining the project’s package name and dependencies
  • project.json Project configuration and build targets
  • checkov.yml Checkov configuration file

Se você definir a opção stageConfig, o gerador também cria dois pacotes compartilhados para gerenciamento centralizado de credenciais (se eles ainda não existirem):

  • Directorypackages/common
    • Directoryinfra-config Stage configuration types and credential mappings
      • Directorysrc
        • stages.types.ts Type definitions for stage credentials and config
        • stages.config.ts Your stage-to-credential mappings (edit this)
        • index.ts Re-exports for importing from other packages
    • Directoryscripts Centralized deploy/destroy scripts
      • Directorysrc
        • infra-deploy.ts Deploy bin script
        • infra-destroy.ts Destroy bin script
        • Directorystage-credentials/ Shared logic (credential lookup, CDK command building)

Você pode começar a escrever sua infraestrutura CDK dentro de src/stacks/application-stack.ts, por exemplo:

src/stacks/application-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import { Bucket } from 'aws-cdk-lib/aws-s3'
import { Construct } from 'constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Declare your infrastructure here
new Bucket(this, 'MyBucket');
}
}

O CDK usa Stages para agrupar stacks que devem ser implantados juntos em um ambiente específico. O src/main.ts gerado cria um stage sandbox para seu próprio desenvolvimento e testes:

src/main.ts
new ApplicationStage(app, 'my-app-sandbox', {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION,
},
});
// Define other instances of stages, such as beta and prod, below

A propriedade env informa ao CDK em qual conta AWS e região implantar. CDK_DEFAULT_ACCOUNT e CDK_DEFAULT_REGION são resolvidos automaticamente pela CLI do CDK a partir de suas credenciais AWS ativas. Consulte a documentação de ambientes do CDK para mais detalhes.

O stage sandbox é aquele que o target deploy-sandbox implanta.

Se você gerou com stageConfig, o main.ts lê a conta e região de um arquivo de configuração centralizado, recorrendo a variáveis de ambiente quando nenhuma configuração está definida:

src/main.ts (with stageConfig)
import { resolveStage } from '@my-scope/common-infra-config';
// Looks up the stage under this project (packages/infra), falling back to
// shared stages. Returns undefined when no config exists for the stage.
const sandboxConfig = resolveStage('packages/infra', 'my-app-sandbox');
new ApplicationStage(app, 'my-app-sandbox', {
env: {
account: sandboxConfig?.account ?? process.env.CDK_DEFAULT_ACCOUNT,
region: sandboxConfig?.region ?? process.env.CDK_DEFAULT_REGION,
},
});

Você pode adicionar mais stages para implantar em diferentes ambientes. Por exemplo, stages beta e prod direcionados a contas AWS separadas:

src/main.ts
new ApplicationStage(app, 'project-beta', {
env: {
account: '123456789012',
region: 'us-west-2',
},
});
new ApplicationStage(app, 'project-prod', {
env: {
account: '098765432109',
region: 'us-west-2',
},
});

Um Stage agrupa um ou mais stacks. Você pode adicionar quantos stacks precisar dentro de um stage:

src/stages/application-stage.ts
import { Stage, StageProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { BackendStack } from '../stacks/backend-stack.js';
import { FrontendStack } from '../stacks/frontend-stack.js';
export class ApplicationStage extends Stage {
constructor(scope: Construct, id: string, props?: StageProps) {
super(scope, id, props);
new BackendStack(this, 'Backend', {
crossRegionReferences: true,
})
new FrontendStack(this, 'Frontend', {
crossRegionReferences: true,
});
}
}

Quando você tem múltiplos stages direcionados a diferentes contas AWS, gerenciar credenciais manualmente pode ser propenso a erros, especialmente à medida que o número de stages cresce.

A opção stageConfig resolve isso gerando dois pacotes compartilhados:

  • packages/common/infra-config — Um único arquivo de configuração onde você mapeia cada stage para suas credenciais AWS, conta e região. Isso é importável de qualquer pacote em seu workspace, então seu main.ts do CDK pode ler conta e região da mesma fonte de verdade.
  • packages/common/scripts — Comandos infra-deploy e infra-destroy que envolvem o CDK com resolução automática de credenciais. Quando você executa deploy, o script lê a configuração, define as variáveis de ambiente AWS corretas para o processo filho do CDK e executa cdk deploy. Seu ambiente de shell nunca é modificado.

Edite packages/common/infra-config/src/stages.config.ts para mapear seus stages para credenciais AWS:

packages/common/infra-config/src/stages.config.ts
import type { StagesConfig } from './stages.types.js';
const config: StagesConfig = {
projects: {
// The key is the project path relative to the workspace root.
// This matches the path in project.json and in deploy commands.
'packages/infra': {
stages: {
// Stage names must match the CDK stage identifiers in main.ts
// (the first argument to `new ApplicationStage(app, 'my-app-dev', ...)`).
'my-app-dev': {
credentials: { type: 'profile', profile: 'dev-account' },
region: 'us-east-1',
},
'my-app-prod': {
credentials: {
type: 'assumeRole',
assumeRole: 'arn:aws:iam::123456789012:role/DeployRole',
},
region: 'us-west-2',
account: '123456789012',
},
},
},
},
shared: {
// Shared stages are available to all infra projects.
// Project-specific entries take priority over shared ones.
stages: {
sandbox: {
credentials: { type: 'profile', profile: 'personal-sandbox' },
region: 'us-east-1',
},
},
},
};
export default config;

Quando você implanta, por exemplo:

Terminal window
pnpm nx deploy infra my-app-dev/*

O script de implantação:

  1. Extrai o nome do stage my-app-dev dos argumentos do comando
  2. Procura credenciais na configuração: primeiro em projects['packages/infra'], depois em shared
  3. Se encontrado, define AWS_PROFILE (ou assume a função IAM) apenas para o processo filho do CDK
  4. Se não encontrado, recorre a quaisquer credenciais AWS que estejam em seu ambiente

Isso significa que fluxos de trabalho existentes sem nenhuma configuração continuam a funcionar — o script só aplica credenciais quando encontra uma entrada correspondente.

Duas estratégias de credenciais são suportadas:

  • profile — Usa um perfil da AWS CLI nomeado de ~/.aws/config. O script define AWS_PROFILE para o processo CDK.
  • assumeRole — Chama STS AssumeRole com o ARN da função especificado e passa as credenciais temporárias para o CDK. Você pode opcionalmente especificar um profile como as credenciais de origem para a chamada AssumeRole, um externalId para políticas de confiança entre contas e um sessionDuration em segundos.

Cada configuração de stage inclui uma region obrigatória e uma account opcional:

  • region (obrigatória) — A região AWS para implantar (por exemplo, us-east-1, eu-west-2).
  • account (opcional) — O ID da conta AWS. Se omitido, o CDK infere das credenciais ativas no momento da implantação. Consulte a documentação de ambientes do CDK para saber como o CDK resolve conta e região.

O main.ts gerado lê esses valores da configuração para que a síntese e implantação do CDK usem as mesmas configurações de ambiente:

src/main.ts
const sandboxConfig = resolveStage('packages/infra', 'my-app-sandbox');
new ApplicationStage(app, 'my-app-sandbox', {
env: {
account: sandboxConfig?.account ?? process.env.CDK_DEFAULT_ACCOUNT,
region: sandboxConfig?.region ?? process.env.CDK_DEFAULT_REGION,
},
});

Stages compartilhados (em shared.stages) se aplicam a qualquer projeto de infraestrutura no workspace. Isso é útil quando múltiplos projetos implantam na mesma conta sandbox — você define as credenciais uma vez em vez de repeti-las para cada projeto.

Stages específicos de projeto (em projects['packages/infra'].stages) se aplicam apenas a esse projeto. Quando ambos existem para o mesmo nome de stage, a entrada específica do projeto tem prioridade.

Se você usou os geradores de API tRPC ou FastAPI para criar APIs, você notará que já tem alguns constructs disponíveis em packages/common/constructs para implantá-los.

Se, por exemplo, você criou uma API tRPC chamada my-api, você pode simplesmente importar e instanciar o construct para adicionar toda a infraestrutura necessária para implantá-la:

src/stacks/application-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { MyApi } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Add infrastructure for your API
new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
});
}
}

Se você usou o gerador de Website React, você notará que já tem um construct em packages/common/constructs para implantá-lo. Por exemplo:

src/stacks/application-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { MyWebsite } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Add infrastructure for your website
new MyWebsite(this, 'MyWebsite');
}
}

Como parte do seu target build, além de executar os targets padrão de compilação, lint e teste, seu projeto de infraestrutura é sintetizado para CloudFormation. Isso também pode ser executado de forma independente, executando o target synth:

Terminal window
pnpm nx synth <my-infra>

Você encontrará seu cloud assembly sintetizado na pasta raiz dist, em dist/packages/<my-infra-project>/cdk.out.

Um target checkov é adicionado ao seu projeto que executa verificações de segurança em sua infraestrutura usando Checkov.

Terminal window
pnpm nx checkov <my-infra>

Você encontrará os resultados dos testes de segurança na pasta raiz dist, em dist/packages/<my-infra-project>/checkov.

Pode haver casos em que você queira suprimir certas regras em recursos. Você pode fazer isso de duas maneiras:

import { suppressRules } from '@my-scope/common-constructs';
// suppresses the CKV_AWS_XXX for the given construct.
suppressRules(construct, ['CKV_AWS_XXX'], 'Reason');
import { suppressRules } from '@my-scope/common-constructs';
// Supresses the CKV_AWS_XXX for the construct or any of its descendants if it is an instance of Bucket
suppressRules(construct, ['CKV_AWS_XXX'], 'Reason', (construct) => construct instanceof Bucket);

Se você está implantando uma aplicação CDK em uma Conta AWS pela primeira vez, ela precisará passar por bootstrap. O bootstrap cria os recursos que o CDK precisa para gerenciar implantações (um bucket S3 para assets, funções IAM, etc.).

Primeiro, certifique-se de que você configurou credenciais para sua conta AWS.

Em seguida, execute o comando bootstrap para cada conta e região que você planeja implantar:

Terminal window
npx cdk bootstrap aws://<account-id>/<region>

Para mais detalhes, consulte a documentação de bootstrap do CDK.

Seu projeto tem três targets de implantação, cada um adequado para uma situação diferente:

TargetUse para
deploy-sandboxImplantar seu próprio stage sandbox durante o desenvolvimento. Nenhum argumento de stage necessário.
deployImplantar qualquer stage, nomeando o stage ou stacks que você deseja.
deploy-ciImplantar a partir de um pipeline CI/CD, usando um cloud assembly pré-sintetizado.

Primeiro, certifique-se de ter credenciais AWS configuradas. Se você gerou com stageConfig e configurou credenciais de stage em packages/common/infra-config/src/stages.config.ts, o comando deploy resolverá e aplicará automaticamente as credenciais corretas para o stage de destino. Caso contrário, certifique-se de que suas credenciais AWS estejam definidas em seu ambiente (por exemplo, via AWS_PROFILE ou variáveis de ambiente). Consulte a documentação de credenciais AWS para as opções disponíveis.

O target deploy-sandbox implanta o stage sandbox que main.ts declara, então você não precisa lembrar seu nome de stage:

Terminal window
pnpm nx deploy-sandbox <my-infra>

Esta é a maneira mais rápida de ter sua própria cópia da aplicação rodando na AWS enquanto você desenvolve.

O target deploy implanta qualquer stage ou stacks que você nomear. Use-o para stages diferentes do seu sandbox, ou para implantar um único stack:

Terminal window
pnpm nx deploy <my-infra> <my-infra>-sandbox/*

Você pode especificar qualquer stage desde que esteja definido em main.ts. Para implantar um stack individual, forneça o nome completo do stack:

Terminal window
pnpm nx deploy <my-infra> <my-infra>-sandbox/Application

Use o target deploy-ci se você está implantando na AWS como parte de um pipeline CI/CD.

Terminal window
pnpm nx deploy-ci <my-infra> my-stage/*

Este target difere ligeiramente do target deploy regular, pois implanta um cloud assembly pré-sintetizado em vez de sintetizar em tempo real. Isso evita potencial não-determinismo de mudanças de versão de pacotes, garantindo que cada estágio do pipeline implante usando o mesmo cloud assembly.

Use o target destroy para desmontar seus recursos:

Terminal window
pnpm nx destroy <my-infra> <my-infra>-sandbox/*

Para mais informações sobre o CDK, consulte o Guia do Desenvolvedor CDK e a Referência da API.