Conceptos básicos de automatización de infraestructura
10 ejemplos para empezar con la automatización de infraestructura: 7 básicos y 3 intermedios.
Busca en todas las páginas de la documentación
10 ejemplos para empezar con la automatización de infraestructura: 7 básicos y 3 intermedios.
uv venv && source .venv/bin/activate
uv pip install "ansible>=10.0" "pulumi>=3.0" "cdktf>=0.20"AWS_PROFILE o rol de IAM para ejemplos en la nube (opcional para ejecuciones solo locales).La automatización de infraestructura comienza describiendo lo que debería existir, no cómo hacer clic en una consola.
# desired_state.py
from dataclasses import dataclass
@dataclass(frozen=True)
class BucketSpec:
name: str
versioning: bool = True
DESIRED = BucketSpec(name="app-logs-prod", versioning=True)Relacionado: Gestión de configuración - plantillas y entornos
Ejecute el mismo script dos veces y termine en el mismo estado, sin recursos duplicados.
import boto3
def ensure_bucket(s3, name: str) -> None:
buckets = [b["Name"] for b in s3.list_buckets().get("Buckets", [])]
if name not in buckets:
s3.create_bucket(Bucket=name)
s3.put_bucket_versioning(
Bucket=name,
VersioningConfiguration={"Status": "Enabled"},
)
session = boto3.Session()
ensure_bucket(session.client("s3"), "demo-idempotent-bucket")create_bucket sin más fallará en la segunda ejecución.put_bucket_versioning es naturalmente idempotente, seguro de llamar cada vez.created vs updated) para registro y auditorías.Relacionado: Aprovisionamiento de recursos en la nube - aprovisionamiento repetible
Los módulos de Ansible convergen automáticamente hacia el estado declarado.
ansible localhost -m ansible.builtin.file -a "path=/tmp/iac-demo state=directory mode=0755"
ansible localhost -m ansible.builtin.file -a "path=/tmp/iac-demo state=directory mode=0755"ok con changed=0; eso es idempotencia en acción.file, copy, apt) sobre shell crudo a menos que no exista un módulo.-C (modo de verificación) para previsualizar cambios sin aplicarlos.Relacionado: Ansible - playbooks, inventarios y roles
Almacene el código de infraestructura en git con el mismo rigor que el código de aplicación.
git init infra-demo && cd infra-demo
mkdir -p stacks/prod
echo 'name = "prod"' > stacks/prod/Pulumi.yaml
git add . && git commit -m "chore: initial prod stack"infra-v2026.07.09) al promocionar a producción.Relacionado: Pulumi (IaC con Python) - Python real para recursos en la nube
Mantenga las configuraciones de desarrollo, staging y producción distintas pero estructuralmente idénticas.
from dataclasses import dataclass
@dataclass(frozen=True)
class EnvConfig:
name: str
bucket_suffix: str
enable_deletion_protection: bool
ENVS = {
"dev": EnvConfig("dev", "-dev", False),
"prod": EnvConfig("prod", "-prod", True),
}deletion_protection=True) pertenecen a la configuración, no a los comentarios.ENVIRONMENT o un flag de CLI, nunca codifique prod de forma rígida.Relacionado: Gestión de configuración - secretos y plantillas
Previsualice los cambios antes de mutar la infraestructura compartida.
cd stacks/prod
pulumi preview # o: terraform plandelete inesperado en recursos con estado.Relacionado: Pruebas de código de infraestructura - ejecuciones en seco y verificaciones de políticas
Registre qué cambió, quién lo ejecutó y el resultado, no solo éxito/fracaso.
import json
import logging
logging.basicConfig(level=logging.INFO, format="%(message)s")
log = logging.getLogger("iac")
def apply(spec: dict) -> dict:
result = {"resource": spec["name"], "action": "updated", "changed": True}
log.info(json.dumps({"event": "iac_apply", **result}))
return result
apply({"name": "app-logs-prod"})Relacionado: Mejores prácticas de automatización de infraestructura - reglas de infraestructura auditables
Compare el estado en vivo de AWS con su especificación declarada.
import boto3
def detect_versioning_drift(bucket: str, expected: str = "Enabled") -> bool:
s3 = boto3.client("s3")
resp = s3.get_bucket_versioning(Bucket=bucket)
actual = resp.get("Status", "Suspended")
return actual != expected
if detect_versioning_drift("app-logs-prod"):
raise SystemExit("drift detected: versioning mismatch")Relacionado: Aprovisionamiento de recursos en la nube - infraestructura revisable
Genere JSON de Terraform a partir de constructos tipados de Python.
from cdktf import App, TerraformStack
from constructs import Construct
class MiniStack(TerraformStack):
def __init__(self, scope: Construct, ns: str):
super().__init__(scope, ns)
# Agregue proveedores y recursos aquí - cdktf synth escribe JSON de terraform
app = App()
MiniStack(app, "mini")
app.synth()cdktf synth sigue siendo Terraform plano; los equipos de operaciones pueden inspeccionarla.Relacionado: Terraform con Python - CDKTF y envolver Terraform
Rechace planes no conformes en CI antes de que toquen las cuentas en la nube.
def validate_tags(tags: dict) -> list[str]:
required = {"Environment", "Owner", "CostCenter"}
missing = required - set(tags)
return [f"missing tag: {t}" for t in sorted(missing)]
errors = validate_tags({"Environment": "prod"})
assert errors, "policy should fail without Owner and CostCenter"ruff y pytest.Relacionado: Pruebas de código de infraestructura - linting y verificaciones de políticas
Versiones de pila: Esta página se escribió para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+ y uv 0.6+.
Revisado por Chris St. John·Última actualización: 16 jul 2026