Automatización de Infraestructura con Terraform y Ansible
La industria del hosting y la administración de servidores está experimentando una transformación profunda. Ya no basta con levantar un servidor a mano o ejecutar scripts desorganizados. La demanda de entornos predecibles, escalables y recuperables ha llevado a la adopción masiva de la infraestructura como código (IaC). En este ecosistema, dos herramientas han emergido como el tándem definitivo: Terraform para la orquestación y aprovisionamiento de recursos, y Ansible para la configuración interna y el despliegue de software.
Dominar esta combinación no solo es una habilidad deseable para 2026, sino un requisito indispensable para cualquier profesional que busque ofrecer soluciones de hosting robustas y modernas. Este artículo desglosa cómo integrar Terraform y Ansible en un flujo de trabajo unificado, cubriendo desde conceptos básicos hasta ejemplos prácticos que te permitirán automatizar desde un VPS sencillo hasta un clúster de alta disponibilidad.
¿Por qué Terraform + Ansible? No es una competencia, es una sinergia
Uno de los errores más comunes entre los sysadmins novatos es pensar que Terraform y Ansible son herramientas redundantes. Nada más lejos de la realidad. Cada una está diseñada para una capa específica del stack de automatización.
Terraform: El arquitecto de la infraestructura
Terraform es una herramienta declarativa que se enfoca en el estado final de tu infraestructura. Su dominio es la capa de proveedores de nube y servicios externos. Con Terraform defines qué recursos necesitas: VPCs, subredes, balanceadores de carga, instancias EC2, registros DNS, bases de datos gestionadas, etc.
- Idempotencia y estado: Terraform mantiene un archivo de estado (
terraform.tfstate) que mapea los recursos del mundo real con tu configuración. Esto permite saber exactamente qué se ha creado y cómo. - Ciclo de vida completo: No solo crea, sino que también actualiza y destruye recursos de forma ordenada.
- Lenguaje HCL: Su sintaxis es limpia y legible, diseñada específicamente para infraestructura.
Ansible: El artesano de la configuración
Una vez que Terraform ha creado los servidores vacíos (o con una imagen base), entra Ansible. Ansible es una herramienta imperativa (aunque también soporta declarativo) y sin agente, que se conecta por SSH para configurar el sistema operativo, instalar paquetes, desplegar aplicaciones y gestionar la configuración interna.
- Sin agente: No necesitas instalar nada en los nodos gestionados, solo Python.
- Playbooks YAML: Fáciles de leer y versionar.
- Idempotencia: Ejecutar el mismo playbook varias veces no debería cambiar el estado final del sistema si ya está en el estado deseado.
[INFO] La sinergia perfecta: Terraform se encarga del qué (servidores, redes, DNS) y Ansible del cómo (Apache, Nginx, PHP, configuraciones de seguridad). Juntos cubren el ciclo completo de aprovisionamiento y configuración.
Instalación y configuración inicial del entorno
Antes de escribir código, asegúrate de tener las herramientas instaladas. Para este ejemplo, trabajaremos localmente y contra un proveedor de nube como DigitalOcean o AWS, pero el concepto aplica a cualquier proveedor.
Requisitos previos
- Terraform: Descarga el binario desde terraform.io y colócalo en tu
$PATH. - Ansible: Instálalo mediante pip:
pip install ansible. - Claves SSH: Genera un par de claves para que Ansible pueda conectarse a los servidores.
# Verificar instalaciones
terraform version
ansible --version
Estructura de directorios recomendada
Organizar bien el proyecto es clave para la mantenibilidad.
infra-hosting/
├── terraform/
│ ├── main.tf # Recursos principales
│ ├── variables.tf # Variables de entrada
│ ├── outputs.tf # Salidas (IPs, DNS)
│ └── provider.tf # Configuración del proveedor
├── ansible/
│ ├── playbooks/
│ │ └── setup-web.yml
│ ├── roles/
│ │ └── nginx/
│ └── inventory/
│ └── hosts
└── scripts/
└── deploy.sh # Script que orquesta ambos
Paso 1: Aprovisionar servidores con Terraform
Vamos a crear un ejemplo real: aprovisionar dos servidores Ubuntu para un hosting básico de aplicaciones web.
Configuración del proveedor (provider.tf)
terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.0"
}
}
}
provider "digitalocean" {
token = var.do_token
}
Definición de recursos (main.tf)
Creamos dos droplets (VPS) con una clave SSH específica.
resource "digitalocean_droplet" "web_servers" {
count = 2
image = "ubuntu-22-04-x64"
name = "web-${count.index + 1}"
region = "nyc3"
size = "s-2vcpu-2gb"
ssh_keys = [digitalocean_ssh_key.default.fingerprint]
tags = ["web", "ansible-managed"]
}
resource "digitalocean_ssh_key" "default" {
name = "terraform-ansible-key"
public_key = file("~/.ssh/id_rsa.pub")
}
Variables y outputs (variables.tf y outputs.tf)
# variables.tf
variable "do_token" {
description = "Token de API de DigitalOcean"
type = string
sensitive = true
}
# outputs.tf
output "web_ips" {
value = digitalocean_droplet.web_servers[*].ipv4_address
}
[TIP] Siempre usa variables y outputs. Las IPs de los servidores son dinámicas y necesitamos pasárselas a Ansible de forma automática.
Ejecuta:
cd terraform
terraform init
terraform plan
terraform apply -auto-approve
Paso 2: Configurar el inventario dinámico de Ansible
El gran desafío es conectar Terraform con Ansible. La forma más limpia es generar un inventario dinámico o, en este caso, un archivo de inventario estático a partir de los outputs de Terraform.
Script puente (scripts/deploy.sh)
Este script ejecuta Terraform, extrae las IPs y genera el inventario de Ansible.
#!/bin/bash
set -e
# 1. Aprovisionar infraestructura
cd terraform
terraform apply -auto-approve
# 2. Obtener las IPs de los outputs
IPS=$(terraform output -json web_ips | jq -r '.[]')
# 3. Generar inventario de Ansible
cd ../ansible
echo "[webservers]" > inventory/hosts
for IP in $IPS; do
echo "$IP ansible_user=root ansible_ssh_private_key_file=~/.ssh/id_rsa" >> inventory/hosts
done
# 4. Ejecutar playbook de Ansible
ansible-playbook -i inventory/hosts playbooks/setup-web.yml
[WARNING] Asegúrate de que el usuario SSH (en este caso
root) tenga acceso. En producción, usa un usuario no privilegiado con sudo.
Paso 3: Configurar servidores con Ansible
Ahora que tenemos los servidores, vamos a instalar y configurar Nginx, añadir un sitio web básico y aplicar configuraciones de seguridad.
Playbook principal (ansible/playbooks/setup-web.yml)
---
- name: Configurar servidores web
hosts: webservers
become: yes
vars:
domain: "midominio.com"
app_port: 8080
tasks:
- name: Actualizar cache de apt
apt:
update_cache: yes
cache_valid_time: 3600
- name: Instalar Nginx y herramientas
apt:
name:
- nginx
- python3-pip
- ufw
state: present
- name: Habilitar UFW y permitir SSH y HTTP
ufw:
rule: "{{ item }}"
port: "{{ item.port }}"
proto: tcp
loop:
- { rule: allow, port: '22' }
- { rule: allow, port: '80' }
- { rule: allow, port: '443' }
- name: Crear directorio para el sitio web
file:
path: /var/www/{{ domain }}
state: directory
owner: www-data
group: www-data
mode: '0755'
- name: Copiar archivo index.html básico
copy:
content: |
<html>
<body>
<h1>Hosting automatizado con Terraform y Ansible</h1>
<p>Servidor: {{ ansible_hostname }}</p>
</body>
</html>
dest: /var/www/{{ domain }}/index.html
- name: Configurar sitio Nginx
template:
src: site.conf.j2
dest: /etc/nginx/sites-available/{{ domain }}
notify: reload nginx
- name: Habilitar sitio
file:
src: /etc/nginx/sites-available/{{ domain }}
dest: /etc/nginx/sites-enabled/{{ domain }}
state: link
handlers:
- name: reload nginx
service:
name: nginx
state: reloaded
Template de Nginx (ansible/roles/nginx/templates/site.conf.j2)
server {
listen 80;
server_name {{ domain }};
root /var/www/{{ domain }};
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Ejecuta el script deploy.sh:
chmod +x scripts/deploy.sh
./scripts/deploy.sh
En pocos minutos, tendrás dos servidores Nginx funcionando, listos para servir tráfico.
Buenas prácticas para hosting en 2026
La automatización no es solo cuestión de velocidad, sino de confiabilidad y seguridad. Aquí tienes recomendaciones clave para tu infraestructura como código.
Gestión de secretos
Nunca hardcodees tokens o contraseñas en los archivos de Terraform o Ansible.
- Terraform: Usa variables de entorno (
TF_VAR_do_token) o un vault como HashiCorp Vault. - Ansible: Utiliza Ansible Vault para cifrar variables sensibles.
ansible-vault encrypt vars/secrets.yml
Módulos y roles reutilizables
No reinventes la rueda. Para Terraform, busca módulos en el Terraform Registry. Para Ansible, explora Ansible Galaxy.
# main.tf usando módulo
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "mi-vpc"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b"]
}
Estrategia de estado remoto
Para equipos, el estado de Terraform debe almacenarse de forma remota y bloqueada. Usa S3 + DynamoDB (AWS) o el backend de Terraform Cloud.
terraform {
backend "s3" {
bucket = "mi-estado-terraform"
key = "hosting/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
}
}
Pruebas y validación
Antes de aplicar cambios en producción, ejecuta:
# Terraform
terraform fmt -check
terraform validate
terraform plan
# Ansible
ansible-playbook --syntax-check playbooks/setup-web.yml
ansible-lint playbooks/setup-web.yml
Caso de uso real: Despliegue de un clúster de hosting escalable
Imagina que necesitas un clúster de balanceo de carga para una aplicación SaaS. Con Terraform y Ansible, el proceso es el siguiente:
-
Terraform crea:
- Un balanceador de carga (LB) con IP estática.
- Un grupo de servidores web (auto-scaling group).
- Una base de datos gestionada (RDS).
- Registros DNS apuntando al LB.
-
Ansible configura:
- Cada servidor web con la aplicación, dependencias y certificados SSL.
- Configuración del firewall y monitoreo (Prometheus node exporter).
- Conexión a la base de datos.
-
Automatización del ciclo de vida:
- Cuando se añade un nuevo servidor (por escalado automático), un webhook ejecuta un playbook de Ansible para configurarlo al instante.
- Si un servidor falla, Terraform lo reemplaza y Ansible lo reconfigure automáticamente.
[INFO] Este nivel de automatización no solo acelera el despliegue, sino que garantiza que cada servidor sea una copia exacta del anterior, eliminando la deriva de configuración (configuration drift).
Conclusión: El futuro es declarativo y sin agentes
La combinación de Terraform para orquestar la infraestructura y Ansible para configurarla internamente representa el estándar de oro en la automatización moderna. Para 2026, los entornos de hosting que no estén gestionados bajo infraestructura como código serán considerados obsoletos, difíciles de mantener y propensos a errores humanos.
Al adoptar este flujo de trabajo, no solo ganas velocidad y consistencia, sino que liberas tiempo para centrarte en lo que realmente importa: mejorar la aplicación, la seguridad y la experiencia del usuario. Empieza hoy con un pequeño proyecto, automatiza un solo servidor, y verás cómo no hay vuelta atrás.
# Comando final para recordar: automatiza o muere en la consola
terraform apply && ansible-playbook -i inventory playbooks/setup.yml
