Appearance
Pulumi
Pulumi es una herramienta para Infrastructure as Code (IaC), del mismo modo que Terraform pero diferente en su estilo de implementación. Con Pulumi:
- Usas lenguajes reales (Python, TypeScript, Go, etc.), por lo que puedes incluir bucles, funciones, condiciones, clases…
- Tienes preview antes de deploy, para mostrar exactamente lo que va a cambiar.
- Soporta todos los servicios de AWS (así como otros servicios cloud).
Si te preguntas para qué usar un lenguaje y especificamente Python, ello hace parte de decisiones que tienen que ver con la naturaleza del proyecto, incluso el equipo, pero actualmente con el uso de la IA (Inteligencia Artificial) tienes un motivo para mantener una tecnología. Es decir, si ya estas usando Python en tu proyecto, implica que se tiene ese conocimiento, es probable que sea innecesario agregar otra tencología como Terraform.
Instalación de Pulumi CLI
Prerrequisitos
- Cuenta AWS (usa la de Free Tier)
- AWS CLI instalado (
sudo snap install aws-cli --classicpara Linux ybrew install awsclipara macOS) y luego configurado:bash(ingresa Access Key, Secret Key, regiónaws configureus-east-1, outputjson) - Python 3.8+
- Editor (VS Code o Zed recomendado)
Instalación desde macOS o Linux
bash
curl -fsSL https://get.pulumi.com | shInstalación para Windows (PowerShell como administrador)
bash
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; iex ((New-Object System.Net.WebClient).DownloadString('https://get.pulumi.com/install.ps1'))" && SET "PATH=%PATH%;%USERPROFILE%\.pulumi\bin"Verifcando versión instalada
bash
pulumi version # Debe mostrar ~3.224.x o superiorFlujo de trabajo clásico de Pulumi
En Pulumi se usan Pilas (Stacks) por entorno y se puede conectarse a la nube de Pulumi para ello. Veamos:
bash
pulumi login
pulumi new aws-python --name mi-primer-stack
cd mi-primer-stackEsto crea:
__main__.py(donde escribes tu código)Pulumi.yamlrequirements.txt
Como comandos clave encuentras:
| Comando | Qué hace |
|---|---|
pulumi preview | Muestra exactamente qué se creará/cambiará |
pulumi up | Preview + confirma + deploy |
pulumi stack output | Ver outputs (IPs, URLs, etc.) |
pulumi destroy | Elimina todo |
pulumi stack rm | Borra el stack (después de destroy) |
Ejemplo con Bucket S3 simple
Reemplaza todo el contenido de __main__.py con el siguiente código:
python
import pulumi
import pulumi_aws as aws
# Crear bucket S3 privado
bucket = aws.s3.Bucket("mi-bucket-libros",
bucket="mi-bucket-libros-2026",
tags={
"Environment": "Dev",
"Owner": "Cesar"
},
acl="private"
)
# Exportar datos útiles
pulumi.export("bucket_name", bucket.bucket)
pulumi.export("bucket_arn", bucket.arn)Se importan librerías y se define el recurso en una variable.
Conpulumi.exportse deja a disposición datos útiles para ser usados.
Ejecuta luego:
bash
pulumi preview
pulumi up
pulumi stack outputConfirmas y podrás contar con tu primer recurso en AWS.
Ejemplo de Instancia EC2 con servidor web
Crea un nuevo proyecto o reemplaza __main__.py:
python
import pulumi
import pulumi_aws as aws
size = "t2.micro" # Free Tier
# AMI Amazon Linux 2 (la más reciente)
ami = aws.ec2.get_ami(most_recent=True,
owners=["137112412989"],
filters=[{"name": "name", "values": ["amzn2-ami-hvm-*"]}])
# Security Group (puertos 22 y 80)
group = aws.ec2.SecurityGroup("web-secgrp",
description="Permitir SSH y HTTP",
ingress=[
{"protocol": "tcp", "from_port": 22, "to_port": 22, "cidr_blocks": ["0.0.0.0/0"]},
{"protocol": "tcp", "from_port": 80, "to_port": 80, "cidr_blocks": ["0.0.0.0/0"]},
])
# Script de inicio (servidor web simple)
user_data = """#!/bin/bash
echo "¡Hi from Pulumi + EC2!" > index.html
nohup python3 -m http.server 80 &
"""
server = aws.ec2.Instance("mi-ec2-web",
instance_type=size,
vpc_security_group_ids=[group.id],
ami=ami.id,
user_data=user_data)
pulumi.export("public_ip", server.public_ip)
pulumi.export("public_dns", server.public_dns)bash
pulumi up
pulumi stack output public_dns # Abre esa URL en el navegadorSi abres la url en el navegador, verás el mensaje:
¡Hi from Pulumi + EC2!
Ejemplo de Función Lambda (Serverless)
Crea una carpeta lambda y dentro un archivo lambda_function.py:
python
def handler(event, context):
return {
"statusCode": 200,
"body": "¡Hola desde Lambda con Pulumi!"
}Comprimelo con formato zip:
bash
cd lambda
zip -r ../lambda.zip .
cd ..Ahora en __main__.py (nuevo proyecto o reemplaza):
python
import pulumi
import pulumi_aws as aws
# Rol IAM para Lambda
role = aws.iam.Role("lambda-role",
assume_role_policy="""{
"Version": "2012-10-17",
"Statement": [{
"Action": "sts:AssumeRole",
"Principal": {"Service": "lambda.amazonaws.com"},
"Effect": "Allow"
}]
}""")
aws.iam.RolePolicyAttachment("lambda-basic",
role=role.name,
policy_arn="arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole")
# Función Lambda
lambda_func = aws.lambda_.Function("mi-lambda",
code=pulumi.FileArchive("lambda.zip"),
role=role.arn,
handler="lambda_function.handler",
runtime="python3.12",
timeout=10)
pulumi.export("lambda_name", lambda_func.name)
pulumi.export("lambda_arn", lambda_func.arn)bash
pulumi upPara probar, ve a la consola AWS - Lambda - Test
Resumen del flujo Pulumi
Básicamente, se dispone de los siguientes hitos:
pulumi preview: para ver el planpulumi up: para confirmar y despliegarpulumi destroy: para limpiar todo (si es una prueba)
Pulumi es legible para desarrollaores si usas lenguajes de programación como Python