
AWS CDK con TypeScript: infraestructura como código desde cero
Infraestructura como código con AWS CDK y TypeScript, sin escribir YAML a mano. Comparamos CDK contra CloudFormation y Terraform, y levantas una Lambda real en AWS.
Si alguien te dice "infraestructura como código" y lo primero que se te viene a la mente es un archivo con miles de líneas de código, algo que solo los DevOps pueden hacer, llegaste al artículo correcto. A mí me pasaba lo mismo, y por eso no investigué nada del tema por un buen rato. Fue hasta que conocí AWS CDK que mi percepción cambió, resulta que no es tan complejo como suena.
Por si nunca has escuchado el término, la infraestructura como código (IaC) es justo eso, escribir en un archivo los recursos que quieres en la nube en vez de crearlos a mano en la consola.
En el artículo vamos a ver qué es, por qué existe y por qué escogerías AWS CDK sobre las otras opciones. Y para que no se quede en pura teoría, al final vas a levantar infraestructura real en tu cuenta de AWS con solo unos comandos sencillos de recordar.
Crear infraestructura desde la consola de AWS
Casi todos empezamos igual. Entras a la consola de AWS, buscas el servicio, le picas a los botones, ajustas las opciones al tanteo y en cinco minutos tienes tu infraestructura corriendo. Esta es una forma muy sencilla y visual de crear recursos, pero no es la mejor manera.
El problema llega tres semanas después, cuando tu jefe te dice "necesitamos esto mismo en producción". Y ahí te quedas viendo la pantalla tratando de reconstruir qué hiciste. ¿En qué región lo dejé? ¿Le activé el versionado al bucket? ¿Qué permisos le puse? No hay forma de revisar qué fue lo que hiciste, a menos que hayas escrito el paso a paso en un bloc de notas.
Crear recursos con clicks en la consola es sencillo y te saca del apuro la primera vez, pero no es algo que puedas reproducir. Por eso existe la infraestructura como código.
Qué cambia cuando tu infra vive en un archivo
La idea es sencilla. Ese archivo lo lee una herramienta que traduce lo que escribiste y crea la infraestructura por ti.
Como es un archivo, puedes versionarlo con una herramienta como git, usar el autocompletado de tu editor y, lo más importante, si alguien más quiere replicar la infraestructura en otra cuenta no tiene que preguntarte qué clics hiciste en la consola. El código ya explica todos los recursos que se van a crear.
💡 AWS CloudFormation, Terraform y AWS CDK son tres formas distintas de trabajar con IaC.
CloudFormation, Terraform o AWS CDK, ¿cuál escojo?
AWS CDK no es la única manera de hacer IaC, y ver contra qué compite ayuda a entender por qué vale la pena.
AWS CloudFormation es la forma nativa de escribir infraestructura en AWS. Escribes tu infraestructura en YAML o JSON, la subes a AWS y él crea todo, con rollback automático si algo falla a media instalación. Es una buena herramienta, pero te hace escribir mucho más código para lograr tu objetivo. Un bucket de Amazon S3 con una configuración básica se te va fácil a 40 líneas de YAML, y tienes que aprender cómo se declara cada recurso. Digamos que es el nivel donde tienes control absoluto, pero también la mayor complejidad.
Terraform resuelve un problema distinto. Usa su propio lenguaje, HCL, y no se casa con un solo proveedor: habla con AWS, GCP, Azure y varios más. Si tu equipo vive entre tres nubes al mismo tiempo, es la opción obvia. A cambio te toca aprender HCL y cuidar un state file, un archivo aparte que lleva la cuenta de qué existe y qué no.
| CloudFormation | Terraform | AWS CDK | |
|---|---|---|---|
| Lenguaje | YAML / JSON | HCL | TypeScript (o Python, Java y otros) |
| Alcance | Solo AWS | Multicloud | Solo AWS |
| Curva inicial | Media | Media-alta | Baja si ya sabes TS |
| Lógica de programación | No | Limitada | Completa |
💡 AWS CloudFormation y Terraform son declarativos, describes el resultado final que quieres y la herramienta decide cómo llegar ahí. AWS CDK le da la vuelta, escribes código imperativo (TypeScript normal, con tusifyfor) que por debajo genera esa misma descripción declarativa.
Las tres son opciones válidas, es cuestión de contexto. Pero si ya escribes TypeScript y toda tu infra vive en AWS, hay una que encaja sin pedirte que aprendas un lenguaje nuevo.
¿Por qué AWS CDK?
AWS CDK es una herramienta que abstrae la complejidad de escribir archivos YAML o JSON con configuraciones muy largas. En vez de eso puedes escribir tu infraestructura en distintos lenguajes de programación como Python, TypeScript/JavaScript, C# y más. Lo que me gustó es que con TypeScript tienes tipos, autocompletado en el editor y puedes usar
if, for o cualquier estructura de control igual que en cualquier otro proyecto de Node. No usas un lenguaje distinto al de tu aplicación.Crear un bucket de Amazon S3 con AWS CDK se ve así:
1
2
3
4
const bucket = new s3.Bucket(this, "MiBucket", {
versioned: true,
removalPolicy: cdk.RemovalPolicy.DESTROY,
});Ese
versioned: true le prende el versionado al bucket, y el removalPolicy: DESTROY le avisa a AWS que, cuando destruyas el stack, se lleve el bucket con él.Por debajo, AWS CDK agarra ese código y lo convierte en plantillas de AWS CloudFormation. Así te quedas con lo bueno de la herramienta nativa de AWS, el rollback automático y el manejo de dependencias entre recursos, sin escribir una sola línea de YAML a mano.

Cada recurso que creas es un construct. Vienen en tres niveles: los L1, que mapean uno a uno con CloudFormation; los L2, que ya traen configuraciones recomendadas por defecto y te ahorran decisiones; y los L3, que juntan varios recursos en un patrón ya armado, como una función de AWS Lambda con su Amazon API Gateway lista para recibir tráfico. Al empezar vas a usar casi siempre L2, que son los que más aparecen en la documentación y en los ejemplos.
App, stack y construct
Antes de meterle mano a la terminal, hay que entender tres conceptos importantes que vas a encontrar siempre al usar AWS CDK.
App es tu proyecto de AWS CDK completo, el contenedor donde vive todo lo demás.
Stack es la unidad que se despliega. Todo lo que metes en un mismo stack se crea junto y se destruye junto. Una App puede tener varios stacks, por ejemplo uno para dev y otro para prod, y cada stack termina siendo un stack de CloudFormation del otro lado. También es una forma de limitar responsabilidades.
Construct es cada recurso o grupo de recursos: una función Lambda, una tabla de Amazon DynamoDB, un bucket de S3. Los constructs siempre van dentro de un stack.
Puesto en una línea, la jerarquía es App → Stack → Construct, de lo más grande a lo más chico.

Vamos a levantar tu primer stack
Necesitas tres cosas antes de empezar: Node.js instalado , una cuenta de AWS y tus credenciales configuradas en la terminal (con
aws login ).Instala el CLI de AWS CDK de forma global:
1
npm install -g aws-cdkCrea un proyecto nuevo:
1
2
mkdir mi-primer-cdk && cd mi-primer-cdk
cdk init app --language typescript --generate-onlyAWS CDK te genera esta estructura:
1
2
3
bin/ # El punto de entrada, aquí vive tu App
lib/ # Aquí defines tus Stacks y Constructs
cdk.json # Configuración del proyectoEse
--generate-only hace que se generen los archivos pero no se instalen las dependencias todavía, y lo pongo a propósito. Antes de correr npm install me gusta abrir el package.json, revisar qué trae y pinear cada dependencia a una versión exacta, sin el ^ que las deja subir solas de versión sin que te des cuenta.Si te interesa por qué me pongo tan quisquilloso con esto, escribí un artículo aparte, npm install puede infectar tu máquina , sobre cómo un
npm install a ciegas puede comprometer tu equipo. Para seguir con el ejemplo no lo necesitas, es nomás por si quieres profundizar.Cuando el
package.json te convenza, instala:1
npm installEl archivo
lib/mi-primer-cdk-stack.ts trae el stack vacío, con un comentario donde van tus recursos:1
2
3
4
5
6
7
8
9
10
import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
export class MiPrimerCdkStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Aquí van tus recursos
}
}Metámosle algo que se pueda ver
Un stack vacío no tiene chiste, así que vamos a poner algo real: una función de AWS Lambda que responda en una URL pública de internet.
El código de la función va en su propio archivo, igual que en un proyecto de verdad. Crea una carpeta
lambda y dentro un archivo hola-mundo.ts:1
2
3
4
export const handler = async () => ({
statusCode: 200,
body: "¡Hola desde AWS CDK! Esto salió de tu TypeScript.",
});Ahora, en
lib/mi-primer-cdk-stack.ts, conecta esa función al stack con el construct NodejsFunction:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs";
import * as lambda from "aws-cdk-lib/aws-lambda";
export class MiPrimerCdkStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Apunta al archivo con el código; NodejsFunction lo transpila y empaqueta por ti
const fn = new NodejsFunction(this, "HolaMundo", {
entry: "lambda/hola-mundo.ts",
handler: "handler",
runtime: lambda.Runtime.NODEJS_22_X,
});
// Le pega una URL pública a la función
const fnUrl = fn.addFunctionUrl({
authType: lambda.FunctionUrlAuthType.NONE,
});
// Imprime la URL en la terminal cuando termine el deploy
new cdk.CfnOutput(this, "FunctionUrl", {
value: fnUrl.url,
});
}
}NodejsFunction es el construct que usarías en un proyecto real para funciones en Node. Le pasas el entry, o sea el archivo con tu código, y por debajo usa esbuild para transpilar el TypeScript y empaquetar solo lo que la función necesita. Por eso hay que tener esbuild instalado, así que agrégalo como dependencia de desarrollo, pineado como te gusta:1
npm install --save-dev --save-exact esbuildSi no lo instalas,
NodejsFunction intenta hacer el build dentro de un contenedor de Docker. Funciona, pero es mucho más tardado.Ya con eso, el resto se explica solo:
addFunctionUrl le asigna una URL pública a la función y CfnOutput hace que AWS CDK te imprima esa URL en la terminal cuando termine el deploy.💡 EseauthType: NONEquiere decir que la URL queda abierta, cualquiera que la tenga puede llamarla. Para un experimento de un rato está bien, pero no pongas nada sensible detrás de una URL así, y bórrala cuando termines.
Y estos son los comandos que vas a repetir todo el tiempo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Una sola vez por cuenta y región: prepara tu cuenta para los deploys de AWS CDK
cdk bootstrap
# Genera la plantilla de CloudFormation sin desplegar nada
cdk synth
# Te muestra qué va a cambiar antes de aplicarlo
cdk diff
# Despliega el stack
cdk deploy
# Destruye todo lo que el stack creó
cdk destroyCorre
cdk synth y vas a ver en pantalla la plantilla de AWS CloudFormation que AWS CDK generó a partir de tu TypeScript. Son cientos de líneas de YAML que salieron de tu código de TypeScript. Ahí se ve clarito el trabajo que la herramienta hace por ti.Ojo con un paso que muchos se olvidan. Antes del primer
cdk deploy tienes que correr cdk bootstrap una vez, por cuenta y región. Es lo que prepara los recursos que AWS CDK necesita para desplegar, y si te lo brincas, el deploy truena.Ahora sí,
cdk deploy. Te muestra los permisos que va a crear y te pide confirmar con y. Cuando termina, en la terminal aparece algo así:1
2
Outputs:
MiPrimerCdkStack.FunctionUrl = https://xxxxxxxxxx.lambda-url.us-east-1.on.aws/Copia esa URL, pégala en el navegador y listo. Tu código de TypeScript se convirtió en infraestructura que puedes probar y responde "¡Hola desde AWS CDK!". Y no tuviste que configurar un servidor, subir archivos a ningún lado ni entrar a la consola.
Y para ir cerrando, mi comando favorito:
cdk destroy. Se lleva la función, la URL y todo lo que el stack creó, y te deja la cuenta como estaba, sin nada olvidado por ahí.Qué sigue
Con esto ya tienes el modelo mental completo. Sabes qué es la infraestructura como código y por qué le gana a los clicks, en qué se diferencian AWS CloudFormation, Terraform y AWS CDK, y acabas de levantar una función de AWS Lambda con una URL pública, todo escrito en TypeScript. Justo lo que te prometí al inicio.
De aquí en adelante todo funciona igual. ¿Quieres una base de datos? Instancias un cluster de Aurora DSQL (serverless y compatible con Postgres) dentro del stack. ¿Una API con rutas de verdad? Cambias la Function URL por un Amazon API Gateway. El patrón no cambia. Agregas el construct, corres
cdk deploy y listo.Y si quieres una versión más completa que la de este artículo, en el repo de mi charla sobre AWS CDK dejé una API de notas con Aurora DSQL, Lambda y API Gateway, más ejemplos para comparar constructs L1 contra L2 y un auto-deploy opcional con GitHub Actions. Viene con los pasos exactos para clonarlo y levantarlo en tu cuenta.
Ahora te toca a ti. Clónalo o levanta el tuyo desde cero, agrégale un construct que no vimos aquí y mándalo a
cdk deploy. Y cuando termines de aprender, ya sabes: cdk destroy.Si te sirvió, déjame un like y no te olvides comentar si usarás AWS CDK en tus proyectos,
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article