Infraestructura como código con Terraform: de la gestión manual a la gestión automatizada de la nube
Las organizaciones que utilizan infraestructura como código (IaC) aprovisionan entornos un 90 % más rápido y experimentan un 60 % menos de interrupciones relacionadas con la configuración que aquellas que administran la infraestructura manualmente. Terraform se ha convertido en la herramienta IaC dominante, con más de 3000 proveedores que respaldan todas las principales plataformas de nube y servicios SaaS.
Esta guía cubre el uso práctico de Terraform para aplicaciones web, sistemas ERP y plataformas de comercio electrónico, desde la primera definición de recursos hasta implementaciones multientorno de nivel de producción.
Conclusiones clave
- Terraform hace que los cambios de infraestructura sean revisables, comprobables y reversibles a través del control de versiones.
- La gestión remota del estado evita conflictos cuando varios ingenieros modifican la infraestructura
- Los módulos encapsulan patrones reutilizables, reduciendo la configuración de cientos de líneas a unos pocos parámetros.
- La integración de Terraform Cloud o CI/CD impone la disciplina de planificar antes de aplicar para cambios seguros
¿Por qué Terraform para las PYMES?
El problema de la infraestructura manual
Sin IaC, su conocimiento de infraestructura reside en:
- Rutas de clic de la consola de AWS que nadie documentó
- Los comandos SSH se ejecutaron hace meses y nadie recuerda
- Archivos de configuración editados directamente en los servidores.
- El modelo mental de un ingeniero sobre "cómo funciona la red"
Con Terraform, su infraestructura vive en Git. Cada cambio es una solicitud de extracción. Cada implementación es reproducible. Cada ingeniero puede entender el panorama completo.
Conceptos básicos
| Concepto | Descripción |
|---|---|
| Proveedor | Complemento que interactúa con una plataforma en la nube (AWS, GCP, Azure, Cloudflare) |
| Recurso | Un único componente de infraestructura (instancia EC2, base de datos RDS, depósito S3) |
| Fuente de datos | Referencia de sólo lectura a la infraestructura existente |
| Variables | Parámetro de entrada para configuración reutilizable |
| Salida | Valor exportado desde una configuración de Terraform |
| Estado | Registro de lo que gestiona Terraform y sus atributos actuales |
| Módulo | Grupo reutilizable de recursos con una interfaz definida |
Primera configuración de Terraform
AWS VPC y EC2 para una aplicación web
# providers.tf
terraform {
required_version = ">= 1.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "ecosire-terraform-state"
key = "production/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
provider "aws" {
region = var.aws_region
}
# variables.tf
variable "aws_region" {
type = string
default = "us-east-1"
}
variable "environment" {
type = string
default = "production"
}
variable "instance_type" {
type = string
default = "t3.large"
}
# main.tf
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${var.environment}-vpc"
Environment = var.environment
ManagedBy = "terraform"
}
}
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 1}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "${var.environment}-public-${count.index + 1}"
}
}
resource "aws_instance" "app" {
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
subnet_id = aws_subnet.public[0].id
vpc_security_group_ids = [aws_security_group.app.id]
key_name = aws_key_pair.deploy.key_name
root_block_device {
volume_size = 50
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "${var.environment}-app"
Environment = var.environment
}
}
resource "aws_db_instance" "postgres" {
identifier = "${var.environment}-db"
engine = "postgres"
engine_version = "17"
instance_class = "db.t3.medium"
allocated_storage = 50
max_allocated_storage = 200
storage_encrypted = true
db_name = "ecosire"
username = "app"
password = var.db_password
vpc_security_group_ids = [aws_security_group.db.id]
db_subnet_group_name = aws_db_subnet_group.main.name
backup_retention_period = 7
backup_window = "03:00-04:00"
maintenance_window = "sun:04:00-sun:05:00"
skip_final_snapshot = false
final_snapshot_identifier = "${var.environment}-db-final"
tags = {
Environment = var.environment
}
}
Módulos para infraestructura reutilizable
Creación de un módulo de aplicación web
# modules/web-app/main.tf
variable "name" {
type = string
}
variable "environment" {
type = string
}
variable "instance_type" {
type = string
default = "t3.medium"
}
variable "vpc_id" {
type = string
}
variable "subnet_ids" {
type = list(string)
}
resource "aws_lb" "app" {
name = "${var.name}-${var.environment}-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = var.subnet_ids
}
resource "aws_lb_target_group" "app" {
name = "${var.name}-${var.environment}-tg"
port = 3000
protocol = "HTTP"
vpc_id = var.vpc_id
health_check {
path = "/health"
healthy_threshold = 2
unhealthy_threshold = 3
interval = 30
}
}
resource "aws_autoscaling_group" "app" {
name = "${var.name}-${var.environment}-asg"
min_size = 2
max_size = 10
desired_capacity = 2
vpc_zone_identifier = var.subnet_ids
target_group_arns = [aws_lb_target_group.app.arn]
launch_template {
id = aws_launch_template.app.id
version = "$Latest"
}
tag {
key = "Name"
value = "${var.name}-${var.environment}"
propagate_at_launch = true
}
}
output "alb_dns_name" {
value = aws_lb.app.dns_name
}
Usando el módulo
# environments/production/main.tf
module "web" {
source = "../../modules/web-app"
name = "ecosire-web"
environment = "production"
instance_type = "t3.large"
vpc_id = module.network.vpc_id
subnet_ids = module.network.public_subnet_ids
}
module "api" {
source = "../../modules/web-app"
name = "ecosire-api"
environment = "production"
instance_type = "t3.large"
vpc_id = module.network.vpc_id
subnet_ids = module.network.public_subnet_ids
}
Gestión del Estado
Estado remoto con S3
# Bootstrap: create the state bucket and DynamoDB table manually or with a separate config
resource "aws_s3_bucket" "terraform_state" {
bucket = "ecosire-terraform-state"
lifecycle {
prevent_destroy = true
}
}
resource "aws_s3_bucket_versioning" "terraform_state" {
bucket = aws_s3_bucket.terraform_state.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_dynamodb_table" "terraform_locks" {
name = "terraform-locks"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}
El bloqueo de estado a través de DynamoDB evita que dos ingenieros ejecuten terraform apply simultáneamente, lo que podría dañar el estado.
Seguridad del archivo de estado
El archivo de estado de Terraform contiene información confidencial, incluidas contraseñas de bases de datos, claves API e ID de recursos. Protégelo:
- Cifrar en reposo: control de versiones del depósito S3 + cifrado del lado del servidor
- Cifrar en tránsito: HTTPS solo para acceso estatal
- Restringir acceso: políticas de IAM que limitan quién puede leer/escribir el estado
- Nunca comprometerse con Git: los archivos de estado nunca deben estar en control de versiones
- Habilitar control de versiones: el control de versiones de S3 permite recuperarse de un estado corrupto
Integración CI/CD
Canalización Terraform de acciones de GitHub
name: Terraform
on:
pull_request:
paths: ['infrastructure/**']
push:
branches: [main]
paths: ['infrastructure/**']
jobs:
plan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- name: Terraform Init
run: terraform init
working-directory: infrastructure/environments/production
- name: Terraform Plan
run: terraform plan -out=tfplan
working-directory: infrastructure/environments/production
- name: Comment PR with plan
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const plan = require('fs').readFileSync('infrastructure/environments/production/tfplan.txt', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## Terraform Plan\n\`\`\`\n${plan}\n\`\`\``
});
apply:
needs: plan
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- name: Terraform Apply
run: terraform apply -auto-approve
working-directory: infrastructure/environments/production
Estrategia multiambiente
| Medio ambiente | Propósito | Tamaños de instancia | Objetivo de costo |
|---|---|---|---|
| Desarrollo | Pruebas de funciones | t3.micro / t3.pequeño | <$100/mes |
| Puesta en escena | Validación de preproducción | Producción de espejos (más pequeños) | ~30% de la producción |
| Producción | Tráfico en vivo | Tamaño adecuado para carga | Optimizado |
Utilice espacios de trabajo de Terraform o directorios separados por entorno:
infrastructure/
modules/
web-app/
database/
network/
environments/
development/
main.tf
terraform.tfvars
staging/
main.tf
terraform.tfvars
production/
main.tf
terraform.tfvars
Preguntas frecuentes
Terraform o Pulumi: ¿cuál deberíamos elegir?
Terraform si su equipo incluye ingenieros de operaciones que prefieren la configuración declarativa. Pulumi si su equipo tiene muchos desarrolladores y prefiere escribir infraestructura en TypeScript o Python. Terraform tiene un ecosistema más grande y más módulos comunitarios. Pulumi tiene una curva de aprendizaje inicial más pronunciada pero es más flexible para lógica compleja.
¿Cómo importamos la infraestructura existente a Terraform?
Utilice terraform import para poner los recursos existentes bajo la gestión de Terraform. Por ejemplo: CÓDIGO1. Después de importar, escriba la configuración correspondiente. Terraform 1.5+ admite bloques de importación en archivos de configuración para importaciones masivas.
¿Cómo manejamos los secretos en Terraform?
Nunca guarde secretos en archivos Terraform. Utilice terraform.tfvars (excluido de Git), variables de entorno (TF_VAR_db_password) o un administrador de secretos (AWS Secrets Manager, HashiCorp Vault). Marque las variables confidenciales con sensitive = true para evitar que aparezcan en la salida del plan.
¿Cuál es el costo de administrar Terraform?
Terraform en sí es gratuito y de código abierto. Terraform Cloud tiene un nivel gratuito para hasta 5 usuarios con estado remoto y planifica/solicita. El costo principal es la curva de aprendizaje (20 a 40 horas para un ingeniero experimentado) y el mantenimiento continuo (2 a 4 horas por mes). Esto se compensa con el tiempo ahorrado en la gestión manual de la infraestructura.
¿Qué viene después?
Terraform proporciona la base para la infraestructura automatizada. Combínelo con canalizaciones de CI/CD para implementación automatizada, monitoreo para visibilidad operativa y recuperación ante desastres para resiliencia.
Comuníquese con ECOSIRE para obtener consultoría sobre automatización de infraestructura, o explore nuestra Guía de DevOps para pequeñas empresas para obtener la hoja de ruta completa.
Publicado por ECOSIRE: ayuda a las empresas a automatizar la infraestructura de la nube.
Escrito por
ECOSIRE Research and Development Team
Construyendo productos digitales de nivel empresarial en ECOSIRE. Compartiendo perspectivas sobre integraciones Odoo, automatización de eCommerce y soluciones empresariales impulsadas por IA.
Artículos relacionados
Automatización de cuentas por pagar: reduzca los costos de procesamiento en un 80 por ciento
Implemente la automatización de cuentas por pagar para reducir los costos de procesamiento de facturas de $15 a $3 por factura con OCR, concordancia tripartita y flujos de trabajo de ERP.
IA en la automatización de la contabilidad y la teneduría de libros: la guía de implementación del CFO
Automatice la contabilidad con IA para el procesamiento de facturas, conciliación bancaria, gestión de gastos e informes financieros. Ciclos de cierre un 85 % más rápidos.
Agentes de IA para la automatización de procesos de negocio: de chatbots a flujos de trabajo autónomos
Cómo los agentes de IA automatizan procesos comerciales complejos en ventas, operaciones, finanzas y servicio al cliente con razonamiento de varios pasos e integración de sistemas.