DevTools

Cheatsheet Terraform

Infraestrutura como código para provisionar cloud e serviços

Volver a los lenguajes
Terraform
34 tarjetas encontradas
Categorías:
Versiones:

CLI


5 cards
Inicializar
terraform init
terraform init -upgrade
terraform init -backend=false

Inicializar el directorio y los providers.

Output e inspección
terraform output
terraform output public_ip
terraform show
terraform state list

Ver los outputs y el estado actual.

Plan y Apply
terraform plan
terraform plan -out=plan.tfplan
terraform apply
terraform apply plan.tfplan
terraform apply -auto-approve

Prever y aplicar cambios.

Destruir
terraform destroy
terraform destroy -target=aws_instance.web
terraform destroy -auto-approve

Eliminar toda la infraestructura.

Formateo y validación
terraform fmt
terraform fmt -check
terraform validate
terraform plan -detailed-exitcode

Formatear y validar código.

HCL e Blocos


4 cards
Estructura de archivos
main.tf       # recursos principales
variables.tf  # variables de input
outputs.tf    # outputs
providers.tf  # configuración de providers
terraform.tfvars # valores
modules/      # módulos reutilizables

Organización del proyecto.

Tipos de datos
string  = "texto"
number  = 42
bool    = true
list    = ["a", "b", "c"]
map     = { key = "value" }
object  = { name = "x", port = 80 }
tuple   = [1, "dos", true]

Tipos disponibles en HCL.

Expresiones
var.name
local.config
resource.type.name.attribute
data.type.name.attribute
module.name.output
terraform.workspace

Referencias a valores.

Bloques dinámicos
dynamic "ingress" {
  for_each = var.ports
  content {
    from_port   = ingress.value
    to_port     = ingress.value
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Generar bloques repetidos.

Resources


5 cards
Definir un recurso
resource "aws_instance" "web" {
  ami           = "ami-12345"
  instance_type = "t3.micro"

  tags = {
    Name = "Web Server"
  }
}

Crear un recurso de infraestructura.

Lifecycle
resource "aws_instance" "web" {
  # ...
  lifecycle {
    create_before_destroy = true
    prevent_destroy       = true
    ignore_changes       = [tags]
  }
}

Controlar el ciclo de vida.

Data sources
data "aws_ami" "ubuntu" {
  most_recent = true
  owners     = ["099720109477"]

  filter {
    name   = "name"
    values = ["ubuntu-*-22.04-*"]
  }
}

Leer datos existentes.

Dependencias
resource "aws_instance" "app" {
  # dependencia implícita
  subnet_id = aws_subnet.main.id

  # dependencia explícita
  depends_on = [aws_iam_role.app]
}

Orden de creación.

for_each y count
resource "aws_instance" "servers" {
  for_each = toset(["web", "api", "db"])
  instance_type = "t3.micro"
  tags = { Name = each.value }
}

resource "aws_subnet" "sub" {
  count = 3
  cidr_block = "10.0.${count.index}.0/24"
}

Crear múltiples instancias.

Variáveis e Outputs


4 cards
Definir variables
variable "instance_type" {
  description = "Tipo de instancia"
  type        = string
  default     = "t3.micro"
}

variable "ports" {
  type = list(number)
  default = [80, 443]
}

Inputs del módulo/proyecto.

Validation
variable "env" {
  type = string
  validation {
    condition = contains(
      ["dev", "staging", "prod"],
      var.env)
    error_message = "Env inválido."
  }
}

Validar inputs.

Outputs
output "public_ip" {
  description = "IP del servidor"
  value       = aws_instance.web.public_ip
}

output "config" {
  value      = aws_instance.web
  sensitive = true
}

Exportar valores.

Locals
locals {
  project_name = "my-app"
  common_tags = {
    Project = local.project_name
    Env     = var.environment
  }
  subnets = [
    for i in range(3) :
    "10.0.${i}.0/24"
  ]
}

Valores calculados internos.

Módulos


4 cards
Usar un módulo
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.0.0"

  name = "my-vpc"
  cidr = "10.0.0.0/16"
  azs  = ["eu-west-1a", "eu-west-1b"]
}

Usar un módulo del registry.

Módulo local
module "app" {
  source = "./modules/app"

  name          = "web"
  instance_type = "t3.small"
  subnet_id     = module.vpc.private_subnets[0]
}

Módulo local personalizado.

Crear un módulo
# modules/app/main.tf
variable "name" { type = string }
variable "instance_type" { type = string }

resource "aws_instance" "this" {
  instance_type = var.instance_type
}

output "id" {
  value = aws_instance.this.id
}

Estructura de un módulo.

Fuentes de módulos
source = "./modules/local"
source = "terraform-aws-modules/vpc/aws"
source = "github.com/user/repo//dir"
source = "s3::https://s3-eu-west-1.amazonaws.com/bucket/module.zip"
source = "git::https://github.com/user/repo.git?ref=v1.0"

Orígenes disponibles.

State


4 cards
Comandos de state
terraform state list
terraform state show aws_instance.web
terraform state mv old new
terraform state rm aws_instance.web
terraform state pull > backup.json

Gestionar el estado.

Backend remoto (S3)
terraform {
  backend "s3" {
    bucket          = "my-tf-state"
    key            = "prod/terraform.tfstate"
    region          = "eu-west-1"
    dynamodb_table  = "tf-locks"
    encrypt         = true
  }
}

Estado compartido con locking.

Importar recursos
terraform import aws_instance.web i-12345

# o con un bloque import (TF 1.5+):
import {
  to = aws_instance.web
  id = "i-12345"
}

Adoptar recursos existentes.

Refresh y taint
terraform refresh
terraform apply -refresh-only
terraform taint aws_instance.web
terraform untaint aws_instance.web

Sincronizar y marcar para recrear.

Providers


4 cards
Configurar un provider
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "eu-west-1"
}

Definir el provider y la versión.

Múltiples providers
provider "aws" {
  region = "eu-west-1"
}

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

resource "aws_instance" "dr" {
  provider = aws.us
}

Usar varias regiones/cuentas.

Versión de Terraform
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    aws    = { version = "~> 5.0" }
    random = { version = "~> 3.5" }
  }
}

Fijar versiones.

Providers comunes
hashicorp/aws
hashicorp/azurerm
hashicorp/google
hashicorp/kubernetes
hashicorp/helm
hashicorp/null   (provisioners)
hashicorp/random

Providers populares.

Avançado


4 cards
Workspaces
terraform workspace list
terraform workspace new staging
terraform workspace select prod
terraform workspace show

# usar en código:
name = "${terraform.workspace}-app"

Entornos aislados.

Funciones útiles
join("-", ["a", "b"])     # "a-b"
lookup(map, key, default)
merge(map1, map2)
length(list)
format("%s-%s", a, b)
try(expr, fallback)
coalesce(a, b, c)

Funciones de manipulación.

Provisioners
resource "aws_instance" "web" {
  # ...
  provisioner "remote-exec" {
    inline = [
      "sudo apt update",
      "sudo apt install -y nginx"
    ]
  }
  connection {
    type        = "ssh"
    user        = "ubuntu"
    private_key = file("~/.ssh/id_rsa")
  }
}

Ejecutar después de la creación.

Buenas prácticas
# • Usar remote state con locking
# • Módulos pequeños y reutilizables
# • Variables con description y type
# • terraform fmt + validate en CI
# • Nunca commitear .tfstate
# • Usar versiones fijas de providers
# • Separar por entorno (workspaces o dirs)

Recomendaciones de uso.