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:
# Descargar el binario de https://www.terraform.io/downloads.html
# Descomprimir y colocar el archivo terraform.exe en una carpeta incluida en el PATH
# 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
Archivos escritos en HCL (HashiCorp Configuration Language) que describen la infraestructura deseada.
Plugins que interactúan con APIs de plataformas como AWS, Azure, Google Cloud, etc.
Componentes de infraestructura como instancias EC2, bases de datos, redes VPC, etc.
Archivo que mapea recursos de Terraform con recursos reales en la nube.
Contenedores reutilizables para múltiples recursos que funcionan juntos.
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:
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 |
terraform init
para descargar proveedoresterraform plan
para revisar cambiosterraform apply
para implementar cambiosterraform destroy
cuando ya no se necesiteMejor práctica: Siempre ejecuta terraform plan
antes de apply
para entender qué cambios se realizarán.
Definidas en variables.tf
:
variable "instance_type" {
description = "Tipo de instancia EC2"
type = string
default = "t2.micro"
}
Definidas en outputs.tf
:
output "instance_public_ip" {
description = "IP pública de la instancia"
value = aws_instance.example.public_ip
}
terraform.tfvars
o *.auto.tfvars
:
instance_type = "t3.small"
region = "us-west-2"
El archivo terraform.tfstate
contiene el mapeo entre los recursos en tu configuración y los recursos reales en tu proveedor.
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.
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"]
}
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"
}
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) |
instance_count = var.env == "prod" ? 3 : 1
tags = {
for k, v in var.tags : k => upper(v) if k != "sensitive"
}
Permiten gestionar múltiples entornos (dev, staging, prod) con la misma configuración.
# Listar workspaces
terraform workspace list
# Crear nuevo workspace
terraform workspace new dev
# Seleccionar workspace
terraform workspace select dev
resource "aws_instance" "example" {
count = terraform.workspace == "prod" ? 3 : 1
tags = {
Environment = terraform.workspace
}
}
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.
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
}
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.