Ir al contenido

Infraestructura CDK

AWS CDK es un framework para definir infraestructura en la nube mediante código y aprovisionarla a través de AWS CloudFormation.

El generador de infraestructura TypeScript crea una aplicación de infraestructura AWS CDK escrita en TypeScript. La aplicación generada incluye mejores prácticas de seguridad a través de verificaciones de seguridad de Checkov.

Puedes generar un nuevo proyecto de infraestructura de dos maneras:

Terminal window
pnpm nx g @aws/nx-plugin:ts#infra
También puede realizar una ejecución en seco para ver qué archivos se cambiarían
Terminal window
pnpm nx g @aws/nx-plugin:ts#infra --dry-run
ParámetroTipoPredeterminadoDescripción
name Requeridostring-El nombre de la aplicación.
directory stringpackagesEl directorio de la nueva aplicación.
subDirectory string-El subdirectorio en el que se coloca el proyecto. Por defecto, este es el nombre del proyecto.
stageConfig booleanHabilita la configuración centralizada de etapas (credenciales, cuenta, región) para despliegues CDK multi-entorno.
preferInstallDependencies booleantrueSi se prefiere instalar las dependencias después de que se ejecute el generador. Establecer en false para diferir la instalación al ejecutar múltiples generadores en lote (la instalación aún se ejecuta si es necesario para que los generadores subsiguientes puedan calcular el grafo de proyectos de Nx); instalar una vez al final.

El generador creará la siguiente estructura de proyecto en el directorio <directory>/<name>:

  • Directoriosrc
    • main.ts Application entry point instantiating CDK stages to deploy
    • Directoriostages CDK Stage definitions
      • application-stage.ts Defines a collection of stacks to deploy in a stage
    • Directoriostacks 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

Si estableces la opción stageConfig, el generador también crea dos paquetes compartidos para la gestión centralizada de credenciales (si aún no existen):

  • Directoriopackages/common
    • Directorioinfra-config Stage configuration types and credential mappings
      • Directoriosrc
        • 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
    • Directorioscripts Centralized deploy/destroy scripts
      • Directoriosrc
        • infra-deploy.ts Deploy bin script
        • infra-destroy.ts Destroy bin script
        • Directoriostage-credentials/ Shared logic (credential lookup, CDK command building)

Puedes comenzar a escribir tu infraestructura CDK dentro de src/stacks/application-stack.ts, por ejemplo:

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');
}
}

CDK utiliza Stages para agrupar stacks que deben desplegarse juntos en un entorno específico. El src/main.ts generado crea un stage sandbox para tu propio desarrollo y pruebas:

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

La propiedad env le indica a CDK a qué cuenta y región de AWS desplegar. CDK_DEFAULT_ACCOUNT y CDK_DEFAULT_REGION son resueltos automáticamente por el CLI de CDK desde tus credenciales activas de AWS. Consulta la documentación de entornos de CDK para obtener más detalles.

El stage sandbox es el que despliega el target deploy-sandbox.

Si generaste con stageConfig, el main.ts lee la cuenta y región desde un archivo de configuración centralizado, recurriendo a variables de entorno cuando no se establece ninguna configuración:

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,
},
});

Puedes agregar más stages para desplegar en diferentes entornos. Por ejemplo, stages beta y prod dirigidos a cuentas de 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',
},
});

Un Stage agrupa uno o más stacks. Puedes agregar tantos stacks como necesites dentro de un 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,
});
}
}

Cuando tienes múltiples stages dirigidos a diferentes cuentas de AWS, gestionar las credenciales manualmente puede ser propenso a errores, especialmente a medida que crece el número de stages.

La opción stageConfig resuelve esto generando dos paquetes compartidos:

  • packages/common/infra-config — Un único archivo de configuración donde mapeas cada stage a sus credenciales, cuenta y región de AWS. Esto es importable desde cualquier paquete en tu workspace, por lo que tu main.ts de CDK puede leer la cuenta y región desde la misma fuente de verdad.
  • packages/common/scripts — Comandos infra-deploy e infra-destroy que envuelven CDK con resolución automática de credenciales. Cuando ejecutas deploy, el script lee la configuración, establece las variables de entorno de AWS correctas para el proceso hijo de CDK y ejecuta cdk deploy. Tu entorno de shell nunca se modifica.

Edita packages/common/infra-config/src/stages.config.ts para mapear tus stages a las credenciales de 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;

Cuando despliegas, por ejemplo:

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

El script de despliegue:

  1. Extrae el nombre del stage my-app-dev de los argumentos del comando
  2. Busca las credenciales en la configuración: primero bajo projects['packages/infra'], luego bajo shared
  3. Si las encuentra, establece AWS_PROFILE (o asume el rol de IAM) solo para el proceso hijo de CDK
  4. Si no las encuentra, recurre a las credenciales de AWS que estén en tu entorno

Esto significa que los flujos de trabajo existentes sin ninguna configuración continúan funcionando — el script solo aplica credenciales cuando encuentra una entrada coincidente.

Se admiten dos estrategias de credenciales:

  • profile — Utiliza un perfil de AWS CLI nombrado desde ~/.aws/config. El script establece AWS_PROFILE para el proceso de CDK.
  • assumeRole — Llama a STS AssumeRole con el ARN del rol especificado y pasa las credenciales temporales a CDK. Opcionalmente puedes especificar un profile como credenciales de origen para la llamada AssumeRole, un externalId para políticas de confianza entre cuentas y un sessionDuration en segundos.

Cada configuración de stage incluye una region requerida y una account opcional:

  • region (requerida) — La región de AWS a la que desplegar (por ejemplo, us-east-1, eu-west-2).
  • account (opcional) — El ID de cuenta de AWS. Si se omite, CDK lo infiere de las credenciales activas en el momento del despliegue. Consulta la documentación de entornos de CDK para ver cómo CDK resuelve la cuenta y región.

El main.ts generado lee estos valores de la configuración para que la síntesis y el despliegue de CDK utilicen la misma configuración de entorno:

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 Compartidos vs Específicos del Proyecto

Sección titulada «Stages Compartidos vs Específicos del Proyecto»

Los stages compartidos (bajo shared.stages) aplican a cualquier proyecto de infraestructura en el workspace. Esto es útil cuando múltiples proyectos se despliegan en la misma cuenta sandbox — defines las credenciales una vez en lugar de repetirlas para cada proyecto.

Los stages específicos del proyecto (bajo projects['packages/infra'].stages) solo aplican a ese proyecto. Cuando ambos existen para el mismo nombre de stage, la entrada específica del proyecto tiene prioridad.

Si has utilizado los generadores de API tRPC o FastAPI para crear APIs, notarás que ya tienes algunos constructos disponibles en packages/common/constructs para desplegarlas.

Si, por ejemplo, creaste una API tRPC llamada my-api, simplemente puedes importar e instanciar el constructo para agregar toda la infraestructura necesaria para desplegarla:

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(),
});
}
}

Si has utilizado el generador de Sitio Web React, notarás que ya tienes un constructo en packages/common/constructs para desplegarlo. Por ejemplo:

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 de tu target build, además de ejecutar los targets predeterminados de compilación, lint y prueba, tu proyecto de infraestructura se sintetiza a CloudFormation. Esto también puede ejecutarse de forma independiente, ejecutando el target synth:

Terminal window
pnpm nx synth <my-infra>

Encontrarás tu ensamblaje en la nube sintetizado en la carpeta raíz dist, bajo dist/packages/<my-infra-project>/cdk.out.

Se agrega un target checkov a tu proyecto que ejecuta verificaciones de seguridad en tu infraestructura usando Checkov.

Terminal window
pnpm nx checkov <my-infra>

Encontrarás los resultados de tus pruebas de seguridad en la carpeta raíz dist, bajo dist/packages/<my-infra-project>/checkov.

Puede haber instancias en las que desees suprimir ciertas reglas en recursos. Puedes hacer esto de dos maneras:

import { suppressRules } from '@my-scope/common-constructs';
// suppresses the CKV_AWS_XXX for the given construct.
suppressRules(construct, ['CKV_AWS_XXX'], 'Reason');

Suprimir una regla en un constructo descendiente

Sección titulada «Suprimir una regla en un constructo descendiente»
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);

Si estás desplegando una aplicación CDK en una Cuenta de AWS por primera vez, necesitará ser inicializada. La inicialización crea los recursos que CDK necesita para gestionar despliegues (un bucket S3 para activos, roles de IAM, etc.).

Primero, asegúrate de haber configurado las credenciales para tu cuenta de AWS.

A continuación, ejecuta el comando bootstrap para cada cuenta y región en la que planeas desplegar:

Ventana de terminal
npx cdk bootstrap aws://<account-id>/<region>

Para obtener más detalles, consulta la documentación de inicialización de CDK.

Tu proyecto tiene tres targets de despliegue, cada uno adecuado para una situación diferente:

TargetÚsalo para
deploy-sandboxDesplegar tu propio stage sandbox durante el desarrollo. No se necesita argumento de stage.
deployDesplegar cualquier stage, nombrando el stage o stacks que deseas.
deploy-ciDesplegar desde un pipeline de CI/CD, usando un ensamblaje en la nube pre-sintetizado.

Primero, asegúrate de tener las credenciales de AWS configuradas. Si generaste con stageConfig y has configurado las credenciales de stage en packages/common/infra-config/src/stages.config.ts, el comando de despliegue resolverá y aplicará automáticamente las credenciales correctas para el stage objetivo. De lo contrario, asegúrate de que tus credenciales de AWS estén establecidas en tu entorno (por ejemplo, a través de AWS_PROFILE o variables de entorno). Consulta la documentación de credenciales de AWS para las opciones disponibles.

El target deploy-sandbox despliega el stage sandbox que declara main.ts, por lo que no necesitas recordar su nombre de stage:

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

Esta es la forma más rápida de tener tu propia copia de la aplicación ejecutándose en AWS mientras desarrollas.

El target deploy despliega el stage o stacks que nombres. Úsalo para stages distintos a tu sandbox, o para desplegar un solo stack:

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

Puedes especificar cualquier stage siempre que esté definido en main.ts. Para desplegar un stack individual, proporciona el nombre completo del stack:

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

Usa el target deploy-ci si estás desplegando en AWS como parte de un pipeline de CI/CD.

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

Este target difiere ligeramente del target deploy regular en que despliega un ensamblaje en la nube pre-sintetizado en lugar de sintetizar sobre la marcha. Esto evita el potencial no determinismo de los cambios de versión de paquetes, asegurando que cada etapa del pipeline despliegue usando el mismo ensamblaje en la nube.

Usa el target destroy para desmantelar tus recursos:

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

Para obtener más información sobre CDK, consulta la Guía del Desarrollador de CDK y la Referencia de API.