El aprovisionamiento de infraestructura ha evolucionado muchísimo. Comenzó con la instalación física de hardware. Después, gracias a la virtualización, se redujo a unos cuantos clics en una interfaz. Más tarde, los proveedores de nube empezaron a ofrecer APIs REST para aprovisionar servicios. Hoy es posible definir de forma declarativa el estado final de un entorno mediante código. Así surgió la infraestructura como código. Algunos ejemplos son Terraform, Cloudformation, plantillas ARM, etc.
El tema con la infraestructura como código
La infraestructura como código es excelente para la reproducibilidad. Reduce los errores humanos y aumenta la inmutabilidad. Como ventaja adicional, también funciona como documentación. Terraform te permite aprovisionar y modificar la infraestructura de forma incremental, y guarda el estado de ejecución después de cada corrida. Pero cuando se usa de manera intensiva en un entorno empresarial, empiezan a notarse sus limitaciones.
Para empezar, incorporar cualquier tipo de lógica con sentencias if resulta complicado. Con el tiempo, el lenguaje HCL de Terraform sumó soporte para sentencias if y bucles for, pero se sienten más como un parche que como elementos de primera clase dentro de HCL. Los frameworks de infraestructura como código no cuentan con capacidades nativas de testing. HCL, Cloudformation y las plantillas de Azure Resource Manager tienen sus propias curvas de aprendizaje. Y, además, te atan a sus respectivos ecosistemas.
Pulumi es un punto medio ideal
En el otro extremo del espectro están los SDKs de nube para muchos lenguajes de programación populares. Todos los grandes proveedores de nube ofrecen estos SDKs llamados CDKs, abreviatura de cloud development kit. Los CDKs son fantásticos porque ofrecen todos los beneficios de un lenguaje de programación; sin embargo, no incluyen un concepto de gestión de estado como sí lo hace Terraform. La gestión de estado vuelve manejables y predecibles los cambios incrementales en la infraestructura.
Aquí es donde entra Pulumi, combinando lo mejor de ambos mundos. Ofrece un lenguaje de programación completo y, a la vez, gestión de estado.
Por ejemplo, en JavaScript puro, el código para varias condiciones if se ve así:
switch (ostype){
case 'linux':
Userdata = userdata
break;
case 'windows':
Userdata = windowsuserdata
break;
}
La misma lógica expresada en el HCL de Terraform se ve así:
Linux = var.ostype == "linux" ? true : false
Windows = var.ostype == "windows" ? true : false
Como puedes ver, la legibilidad mejora bastante con la conocida notación de JavaScript en comparación con el lenguaje HCL de Hashicorp. HCL es un lenguaje de dominio específico que carece de la flexibilidad de un lenguaje de propósito general. Por eso, se puede sumar más lógica a la infraestructura como código usando un lenguaje de propósito general.
Pulumi también aporta otras ventajas del ciclo de vida de desarrollo de software: desarrollo guiado por pruebas, integración continua, versionado de releases, gestión de paquetes, etc.
Ahora el software de aplicación y el software de infraestructura pueden convivir lado a lado. Un mismo repositorio de git puede alojar ambos, escritos en el mismo lenguaje de programación.
Conceptos de Pulumi
Terraform maneja conceptos como provider, módulo, estado, etc. De forma similar, Pulumi reimaginó y simplificó estos conceptos así:
Stacks:
Los Stacks son colecciones de recursos de infraestructura relacionados que comparten las mismas variables de entorno. Se asemejan a los entornos (dev, stage, prod), y cada stack tiene su propio conjunto de variables de entorno. Estas variables se definen exclusivamente en "Pulumi.dev.yaml", "Pulumi.stage.yaml", etc.
Projects:
Un Project es una agrupación lógicamente aislada de recursos de infraestructura que engloba stacks. Los Projects pueden asociarse a equipos, iniciativas o tipos de infraestructura (contenedores, serverless, redes, etc.). Hay margen para definir qué tipo de agrupación le conviene más a cada organización.
Backends:
Los Backends almacenan el estado de ejecución de Pulumi en un sistema de almacenamiento persistente. Pueden ser de varios tipos:
1. Service backends: Pulumi cloud (SAAS) o Pulumi autoalojado. Los Service backends ofrecen la ventaja de generar snapshots de la infraestructura a intervalos regulares. Esto facilita el rollback y la recuperación frente a errores fatales durante el aprovisionamiento.
2. Almacenamiento de objetos autogestionado (AWS S3, GCP GCS, Azure blobs, etc.).
Providers
Pulumi puede aprovisionar infraestructura y servicios en varias plataformas. Actualmente cuenta con providers para AWS, GCP, Azure, Kubernetes, Cloudflare y muchos más.
Apéndice
Tabla comparativa

Próximamente
La segunda parte de este artículo explorará funcionalidades avanzadas de Pulumi que permiten empoderar a los equipos autónomos para que aprovisionen y mantengan su propia infraestructura junto con su aplicación. También recorreremos un codebase capaz de aprovisionar clústeres EKS en AWS: clústeres EKS que van más allá del "hello world" e incorporan algo de hardening y preparación para producción. ¡No te lo pierdas!
Para mantenerte al día, síguenos en el DoiT Engineering Blog, el canal de LinkedIn de DoiT y el canal de Twitter de DoiT. Para conocer oportunidades laborales, visita https://careers.doit-intl.com.
Puede que no haya una gran diferencia técnica en la semántica del lenguaje entre HCL y un lenguaje de propósito general. Y cuando hay que elegir entre un lenguaje de programación de propósito general, maduro y ampliamente conocido, y un lenguaje declarativo de dominio específico, propietario y recién llegado para lograr el mismo resultado, ¿por qué quedarse con el menos conocido? Tanto HCL como un lenguaje de propósito general hacen bien el trabajo. Pero dados los ecosistemas consolidados en torno a los lenguajes de propósito general y el talento disponible en el mercado, tiene mucho sentido optar por un framework como Pulumi en lugar de Terraform.