Anatomía de templates IaC
La Infraestructura como Código (IaC) ha cambiado la forma en la que gestionamos nuestras infraestructuras en la nube al permitirnos definir nuestros entornos a través de código. En lugar de configurar manualmente servidores, redes y servicios, IaC automatiza el proceso, asegurando consistencia y reduciendo errores humanos.
En este blog veremos las herramientas de IaC más comunes: AWS CloudFormation, Terraform de HashiCorp, Azure Resource Manager (ARM) y Google Cloud Deployment Manager. Pondremos énfasis en el formato de sus archivos de configuración con lo cual podremos armar un diagrama de Venn donde la intersección donde se juntan todas las características de estos archivos nos dará una anatomía de un template IaC genérico.
Un vistazo a la historia
- AWS CloudFormation: Lanzado en 2011, AWS CloudFormation fue una de las primeras herramientas de IaC. Proporcionó a los usuarios de AWS una manera de modelar y gestionar recursos usando plantillas en JSON o YAML. Esta herramienta sentó las bases para definir la infraestructura en la nube de manera declarativa, enfocándose exclusivamente en los recursos de AWS.
- Terraform: Introducido por HashiCorp en 2014, Terraform llevó el concepto de IaC más allá al ser agnóstico a la nube. A diferencia de CloudFormation, no está vinculado a un solo proveedor de nube, lo que lo hace popular para equipos que trabajan en entornos multi-nube. Terraform utiliza el lenguaje HCL (HashiCorp Configuration Language), que es legible para humanos pero también compatible con máquinas.
- Azure Resource Manager (ARM): Las plantillas ARM de Microsoft se introdujeron con el creciente uso de Azure. Las plantillas ARM, escritas en JSON, permiten a los usuarios de Azure definir su infraestructura de manera declarativa. Desde su lanzamiento, ARM se ha convertido en el método estándar para gestionar recursos de Azure de manera eficiente.
- Google Cloud Deployment Manager: La respuesta de Google a IaC vino con Deployment Manager, que permite a los usuarios configurar sus recursos en la nube usando plantillas en YAML, Python o Jinja2. Introducido en 2016, Deployment Manager facilitó la gestión de la infraestructura en Google Cloud Platform (GCP), ofreciendo soporte para scripts personalizados en Python para mayor flexibilidad.
1. AWS CloudFormation
- Lenguaje: JSON o YAML
- Estructura:
- AWSTemplateFormatVersion: Opcional, especifica la versión del template.
- Description: Opcional, para dar una descripción al template.
- Parameters: Parámetros de entrada del template que se pueden establecer durante el despliegue.
- Mappings: Define pares key-value para establecer valores condicionalmente.
- Resources: Sección obligatoria donde se definen recursos AWS (ej., Instancias EC2, buckets S3).
- Outputs: Datos de salida del template que pueden ser importados a otros stacks o usados en un despliegue.
Ejemplo:
Resources:
MyEC2Instance:
Type: "AWS::EC2::Instance"
Properties:
InstanceType: "t2.micro"
ImageId: "ami-0abcdef1234567890"
2. Terraform
- Lenguaje: HCL (HashiCorp Configuration Language) o JSON
- Estructura:
- Providers: Define el cloud provider (e.g., AWS, Azure).
- Resources: Sección obligatoria que define los recursos cloud a ser administrados.
- Variables: Define variables de entrada para personalización.
- Outputs: Define salidas para retornar valores luego de aplicar la configuración.
- Modules: Agrupación y reutilización de configuraciones.
Ejemplo:
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "my_instance" {
ami = "ami-0abcdef1234567890"
instance_type = "t2.micro"
}
3. Azure Resource Manager (ARM)
- Lenguaje: JSON
- Estructura:
- $schema: Link al Json schema que define la estructura del template ARM.
- contentVersion: Versión del template (ej. "1.0.0.0").
- parameters: Parámetros de entrada que permiten personalización del template.
- variables: Valores reutilizables para el template.
- resources: Sección obligatoria que define recursos de Azure (ej., VMs, storage accounts).
- outputs: Datos de salida del deployment.
Ejemplo
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2020-06-01",
"name": "myVM",
"location": "[resourceGroup().location]",
"properties": {
"hardwareProfile": {
"vmSize": "Standard_DS1_v2"
}
}
}
]
}
4. Google Cloud Deployment Manager
- Lenguaje: YAML, Python, or Jinja2
- Estructura:
- imports: Importa otros archivos de configuración o templates.
- resources: Sección obligatoria que define recursos de Google Cloud (ej., compute instances, storage).
- outputs: Datos de salida de la configuración.
Ejemplo:
resources:
- name: my-vm
type: compute.v1.instance
properties:
zone: us-central1-a
machineType: zones/us-central1-a/machineTypes/n1-standard-1
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
sourceImage: projects/debian-cloud/global/images/family/debian-9
Similitudes Entre las Herramientas de IaC
- Enfoque Declarativo: Todas estas herramientas usan un modelo declarativo, donde se especifica el estado final deseado de la infraestructura, y el motor de IaC se encarga de alcanzar ese estado.
- Soporte para Parámetros/Variables: Cada herramienta permite definir parámetros o variables, habilitando la personalización de las plantillas sin necesidad de codificar valores estáticos.
- Definición de Recursos: Todos los sistemas de IaC requieren una sección de “recursos”, donde se declaran los recursos en la nube (como máquinas virtuales o bases de datos).
- Salidas (Outputs): Después de implementar los recursos, estas herramientas pueden devolver información clave, como direcciones IP o detalles de configuración, que pueden ser reutilizados en otras plantillas o entornos.
Principales diferencias
- Lenguaje:
- CloudFormation y ARM se basan en formatos JSON o YAML, que pueden parecer extensos, pero son ampliamente entendidos.
- Terraform utiliza HCL, un lenguaje más conciso y legible que simplifica la gestión de infraestructuras complejas.
- Deployment Manager soporta plantillas en YAML, Python y Jinja2, ofreciendo más flexibilidad para lógica de scripting.
- Modularidad:
- La fortaleza de Terraform radica en su soporte para módulos reutilizables. Puedes agrupar recursos relacionados y reutilizar estos bloques en diferentes configuraciones, lo que simplifica la gestión de infraestructuras grandes.
- CloudFormation tiene stacks anidados, y ARM permite plantillas enlazadas, pero son más rígidos en comparación con los módulos de Terraform.
- Soporte Multi-nube:
- Terraform se destaca por su soporte multi-nube. Permite que el mismo archivo de IaC defina recursos en múltiples plataformas de nube, ofreciendo a los equipos una única herramienta para gestionar entornos diversos.
- CloudFormation, ARM y Deployment Manager están estrechamente integrados con sus respectivas plataformas y carecen de flexibilidad multi-nube.
Usando cualquier leguaje de programación como IaC tool: AWS CDK
Como evolución a los templates declarativos tenemos a AWS CDK el cual nos permite generar un template de Cloudformation a partir de código escrito en lenguajes de programación convencionales como TypeScript, JavaScript, Python, Java, y C#.
En general se tienen los siguientes pasos a la hora de utilizar CDK:
- Instalar la herramienta CDK.
- Inicializar el proyecto eligiendo el lenguaje de programación.
- Preparar dependencias para el proyecto, por ejemplo con un archivo pom.xml para java y npm install para javascript.
- Escribir el código y generar el template con el comando 'cdk synth'.
- Opcionalmente desplegarlo en una cuenta de AWS previamente configurada en el CLI con el comando 'cdk deploy'.
Las ventajas de CDK frente a los templates específicos son:
- No hace falta aprender un lenguaje nuevo, podemos usar el que ya manejamos.
- Se aprovecha todo el poder de los lenguajes de programación permitiendo lógica más compleja y reutilizable.
- Reduce la complejidad de la infraestructura mediante 'Constructs' que permiten agrupar y representar de forma abstracta uno o más recursos cloud como instancias EC2, buckets S3, etc.
Como ejemplo crearemos una instancia EC2 en una cuenta AWS con Python:
- Primero instalamos las dependencias de CDK:
npm install -g aws-cdk
pip install aws-cdk-lib constructs
2. En un directorio inicializamos el proyecto CDK:
cdk init app --language python
3. Instalamos la librería EC2:
pip install aws-cdk-lib.aws_ec2
4. Creamos el script con Python:
from aws_cdk import (
Stack,
aws_ec2 as ec2,
)
from constructs import Construct
class MyEc2CdkStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
# Crea un VPC
vpc = ec2.Vpc(self, "MyVpc", max_azs=2) # Default is all AZs in the region
# Crea una instancia EC2
instance = ec2.Instance(self, "MyInstance",
instance_type=ec2.InstanceType("t2.micro"),
machine_image=ec2.MachineImage.latest_amazon_linux(), # Amazon Linux 2 AMI
vpc=vpc,
vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC) # Place the instance in a public subnet
)
5. Desplegamos el template en AWS:
# Instala dependencias
pip install -r requirements.txt
# Sintetiza el template Cloudformation
cdk synth
# Despliega el stack
cdk deploy
Conclusión
La evolución de la IaC ha transformado dramáticamente el manejo de infraestructuras cloud, ofreciendo consistencia, repetibilidad y reducción de errores. Como pudimos ver todas estas herramientas comparten el enfoque declarativo, el soporte para parámetros/variables, definición de recursos y salida de resultados. Aparte de los templates, tenemos a AWS CDK que permite utilizar cualquier lenguaje de programación como generador de templates Cloudformation, lo que aumenta la versatilidad y facilidad de adopción de IaC.