Manual Completo de Terraform

1. Introducción a Terraform

Terraform es una herramienta de Infraestructura como Código (IaC) desarrollada por HashiCorp que permite definir, aprovisionar y gestionar infraestructura de manera declarativa mediante archivos de configuración.

Características principales:

2. Instalación de Terraform

Windows

# Descargar el binario de https://www.terraform.io/downloads.html
# Descomprimir y colocar el archivo terraform.exe en una carpeta incluida en el PATH

Linux/macOS

# Descargar e instalar
wget https://releases.hashicorp.com/terraform/1.2.5/terraform_1.2.5_linux_amd64.zip
unzip terraform_1.2.5_linux_amd64.zip
sudo mv terraform /usr/local/bin/

# Verificar instalación
terraform version

3. Conceptos Básicos

Archivos de configuración (.tf)

Archivos escritos en HCL (HashiCorp Configuration Language) que describen la infraestructura deseada.

Proveedores (Providers)

Plugins que interactúan con APIs de plataformas como AWS, Azure, Google Cloud, etc.

Recursos (Resources)

Componentes de infraestructura como instancias EC2, bases de datos, redes VPC, etc.

Estado (State)

Archivo que mapea recursos de Terraform con recursos reales en la nube.

Módulos (Modules)

Contenedores reutilizables para múltiples recursos que funcionan juntos.

4. Estructura Básica de un Proyecto

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  tags = {
    Name = "ExampleInstance"
  }
}

Este ejemplo muestra:

5. Comandos Básicos

Comando Descripción
terraform init Inicializa el proyecto, descarga proveedores
terraform plan Muestra los cambios que se aplicarán
terraform apply Aplica los cambios para alcanzar el estado deseado
terraform destroy Elimina todos los recursos gestionados
terraform validate Valida la sintaxis de los archivos de configuración
terraform fmt Formatea los archivos de configuración
terraform show Muestra el estado actual
terraform output Muestra los valores de salida

6. Flujo de Trabajo Básico

  1. Escribir configuración: Crear archivos .tf con la infraestructura deseada
  2. Inicializar: terraform init para descargar proveedores
  3. Planificar: terraform plan para revisar cambios
  4. Aplicar: terraform apply para implementar cambios
  5. Modificar: Actualizar configuración según necesidades
  6. Destruir: terraform destroy cuando ya no se necesite

Mejor práctica: Siempre ejecuta terraform plan antes de apply para entender qué cambios se realizarán.

7. Variables en Terraform

Variables de entrada

Definidas en variables.tf:

variable "instance_type" {
  description = "Tipo de instancia EC2"
  type        = string
  default     = "t2.micro"
}

Variables de salida

Definidas en outputs.tf:

output "instance_public_ip" {
  description = "IP pública de la instancia"
  value       = aws_instance.example.public_ip
}

Archivos de variables

terraform.tfvars o *.auto.tfvars:

instance_type = "t3.small"
region        = "us-west-2"

8. Manejo del Estado (State)

El archivo terraform.tfstate contiene el mapeo entre los recursos en tu configuración y los recursos reales en tu proveedor.

Backends para almacenar estado

terraform {
  backend "s3" {
    bucket = "my-terraform-state"
    key    = "prod/terraform.tfstate"
    region = "us-east-1"
  }
}

Importante: Nunca edites manualmente el archivo tfstate. Usa comandos como terraform state para modificarlo.

9. Módulos en Terraform

Usar un módulo

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "3.14.0"
  
  name = "my-vpc"
  cidr = "10.0.0.0/16"
  
  azs             = ["us-east-1a", "us-east-1b"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24"]
}

Crear un módulo

Estructura de directorios:

modules/
  └── ec2-instance/
      ├── main.tf
      ├── variables.tf
      └── outputs.tf

Luego puedes llamarlo desde tu configuración principal:

module "web_server" {
  source = "./modules/ec2-instance"
  ami    = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
}

10. Funciones y Expresiones

Funciones comunes

Función Descripción Ejemplo
file() Lee contenido de un archivo file("script.sh")
join() Une elementos con un separador join(", ", ["a", "b", "c"])
split() Divide una cadena en partes split(", ", "a, b, c")
lookup() Busca en un mapa lookup({a=1, b=2}, "a", 0)
element() Obtiene elemento de lista element(["a", "b", "c"], 1)

Expresiones condicionales

instance_count = var.env == "prod" ? 3 : 1

For loops

tags = {
  for k, v in var.tags : k => upper(v) if k != "sensitive"
}

11. Workspaces (Espacios de Trabajo)

Permiten gestionar múltiples entornos (dev, staging, prod) con la misma configuración.

Comandos básicos

# Listar workspaces
terraform workspace list

# Crear nuevo workspace
terraform workspace new dev

# Seleccionar workspace
terraform workspace select dev

Uso en configuración

resource "aws_instance" "example" {
  count = terraform.workspace == "prod" ? 3 : 1
  
  tags = {
    Environment = terraform.workspace
  }
}

12. Provisionadores

Permiten ejecutar scripts en recursos recién creados.

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  provisioner "remote-exec" {
    inline = [
      "sudo apt-get update",
      "sudo apt-get install -y nginx",
      "sudo systemctl start nginx"
    ]
    
    connection {
      type     = "ssh"
      user     = "ubuntu"
      private_key = file("~/.ssh/id_rsa")
      host     = self.public_ip
    }
  }
}

Advertencia: Los provisionadores son una opción de último recurso. Siempre prefiere métodos nativos como user_data en AWS o imágenes personalizadas.

13. Mejores Prácticas

14. Ejemplo Completo: AWS VPC con EC2

terraform {
  required_version = ">= 1.2.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

provider "aws" {
  region = var.region
}

resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true
  
  tags = {
    Name = "MainVPC"
  }
}

resource "aws_subnet" "public" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "${var.region}a"
  
  tags = {
    Name = "PublicSubnet"
  }
}

resource "aws_instance" "web" {
  ami           = var.ami_id
  instance_type = var.instance_type
  subnet_id     = aws_subnet.public.id
  
  user_data = file("init.sh")
  
  tags = {
    Name = "WebServer"
  }
}

output "instance_ip" {
  value = aws_instance.web.public_ip
}

15. Conclusión

Terraform es una herramienta poderosa para gestionar infraestructura de manera consistente y repetible. Este manual cubre los conceptos fundamentales, pero Terraform tiene muchas más capacidades como:

Para aprender más, consulta la documentación oficial y explora los módulos públicos disponibles.