Hasta ahora hemos definido valores fijos. Pero la verdadera potencia de Terraform viene de conectar cosas entre sí y transformar valores. Para eso usamos expresiones, referencias y funciones. Con ellas, tu infraestructura deja de ser una lista estática y se vuelve dinámica e inteligente.

Referencias: conectar recursos entre sí

Una referencia es la forma de usar el valor de un recurso (o variable) en otro sitio. Es lo que permite que los recursos se conecten.

La sintaxis general para referirte a un atributo de un recurso es:

tipo_recurso.nombre.atributo

Ejemplo: Tienes una VPC y quieres crear una subred dentro de ella. La subred necesita saber el ID de la VPC. En lugar de copiar el ID a mano, lo referencias:

resource "aws_vpc" "principal" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "publica" {
  vpc_id     = aws_vpc.principal.id   # ← referencia al ID de la VPC
  cidr_block = "10.0.1.0/24"
}

Aquí aws_vpc.principal.id significa: «el atributo id del recurso aws_vpc que llamé principal».

Por qué esto es genial: No necesitas saber el ID de la VPC de antemano (lo asigna AWS al crearla). Terraform lo resuelve automáticamente. Y aquí ocurre algo muy importante...

Las dependencias implícitas

Cuando un recurso referencia a otro, Terraform entiende automáticamente que hay una dependencia: «la subred necesita la VPC, así que crearé la VPC primero».

Esto es la magia del enfoque declarativo (subcapítulo 9.2): tú no indicas el orden; Terraform lo deduce de las referencias y construye un grafo de dependencias para crear todo en el orden correcto.

Recuerda la analogía del taxi: tú declaras qué quieres y cómo se conectan las cosas; Terraform calcula el orden de creación. Las referencias son las que le dicen «esto depende de esto».

Las distintas referencias que ya conoces:

  • var.nombre → una variable (subcapítulo 10.1).
  • local.nombre → un local.
  • aws_vpc.principal.id → un atributo de un recurso.

Expresiones: combinar y calcular valores

Una expresión es cualquier cosa que produce un valor: un valor literal, una referencia, una operación, o una combinación.

Interpolación de strings

Puedes insertar valores dentro de un texto usando ${ }:

resource "aws_instance" "web" {
  # ...
  tags = {
    Name = "servidor-${var.entorno}-web"
  }
}

Si var.entorno vale "prod", el nombre resultante será "servidor-prod-web". Esto se llama interpolación: meter el valor de una variable dentro de un texto.

Operaciones

Puedes hacer operaciones matemáticas, comparaciones y lógica:

cantidad = var.cantidad_base + 2        # suma
es_prod  = var.entorno == "prod"        # comparación (da true/false)

Funciones built-in: transformar valores

Terraform incluye funciones integradas (built-in) para transformar y manipular valores. Son como las funciones de una hoja de cálculo. No puedes crear funciones nuevas, pero las que hay cubren casi todo lo que necesitas.

La sintaxis es nombre_funcion(argumentos). Veamos las más útiles agrupadas por tipo:

Funciones de texto

upper("hola")              # → "HOLA"
lower("HOLA")              # → "hola"
"${var.proyecto}-${var.entorno}"   # combinar textos
trimspace("  hola  ")      # → "hola" (quita espacios)

Funciones de colecciones (listas y maps)

length(["a", "b", "c"])    # → 3 (cuántos elementos)
element(var.lista, 0)      # → el primer elemento
concat(lista1, lista2)     # → une dos listas
lookup(var.mapa, "clave", "valor_por_defecto")  # busca en un map

Funciones numéricas

max(5, 10, 3)              # → 10
min(5, 10, 3)              # → 3

Funciones muy usadas en infraestructura

cidrsubnet("10.0.0.0/16", 8, 1)   # calcula subredes automáticamente
file("script.sh")                  # lee el contenido de un archivo
jsonencode({ clave = "valor" })    # convierte a formato JSON

cidrsubnet es muy práctico: calcula rangos de subredes a partir del rango de la VPC, sin que tengas que hacer las cuentas de CIDR a mano (recuerda el Capítulo 6). Por ejemplo, divide automáticamente tu 10.0.0.0/16 en subredes ordenadas.

No memorices todas las funciones. Hay decenas. Lo importante es saber que existen y que, cuando necesites transformar un valor, casi seguro hay una función para ello. La documentación de Terraform las lista todas.

Un ejemplo que junta todo

variable "proyecto" {
  type    = string
  default = "tienda"
}

variable "azs" {
  type    = list(string)
  default = ["eu-west-1a", "eu-west-1b"]
}

resource "aws_vpc" "principal" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "${var.proyecto}-vpc"        # interpolación
  }
}

resource "aws_subnet" "publica" {
  vpc_id            = aws_vpc.principal.id              # referencia (dependencia)
  cidr_block        = cidrsubnet(aws_vpc.principal.cidr_block, 8, 1)  # función
  availability_zone = element(var.azs, 0)              # función sobre lista
  tags = {
    Name = upper("${var.proyecto}-publica")            # función + interpolación
  }
}

Este código: nombra la VPC con interpolación, crea una subred que referencia la VPC (creando la dependencia), calcula su CIDR con una función, elige una zona de la lista con otra función, y pone el nombre en mayúsculas. Todo conectado y dinámico.

Lo que debes recordar

  • Las referencias (aws_vpc.principal.id, var.x, local.y) conectan recursos y valores entre sí.
  • Cuando un recurso referencia a otro, Terraform deduce automáticamente la dependencia y el orden de creación (no lo indicas tú).
  • Las expresiones combinan y calculan valores: la interpolación ${...} inserta valores en textos; también hay operaciones matemáticas y lógicas.
  • Las funciones built-in transforman valores (upper, length, lookup, cidrsubnet, file…). No puedes crear funciones nuevas, pero hay muchas integradas.
  • No memorices funciones: recuerda que existen y búscalas cuando las necesites.

En el último subcapítulo de HCL veremos cómo crear varios recursos a la vez y tomar decisiones con condicionales y bucles (count, for_each, for).

Cloud, AWS & Terraform — De cero a experto

Capítulo 1 · Qué es el cloud computing

Capítulo 2 · El mercado cloud y los grandes proveedores

Capítulo 3 · Regiones, zonas de disponibilidad y edge

Capítulo 4 · Cómputo: EC2

Capítulo 5 · Almacenamiento: S3

Capítulo 6 · Redes: VPC

Capítulo 7 · Identidad y acceso: IAM

Capítulo 8 · Bases de datos gestionadas

Capítulo 9 · Por qué Infraestructura como Código

Capítulo 10 · HCL: el lenguaje de Terraform

Capítulo 11 · Providers y estado

Capítulo 12 · Tu primera infraestructura real en Terraform

Capítulo 13 · Balanceo de carga y autoescalado

Capítulo 14 · Serverless con Lambda

Capítulo 15 · Mensajería y eventos

Capítulo 16 · Entrega de contenido y DNS

Capítulo 17 · Contenedores en AWS

Capítulo 18 · Módulos: reutilización y composición

Capítulo 19 · Workspaces y gestión de entornos

Capítulo 20 · Backends remotos y locking

Capítulo 21 · Testing de infraestructura

Capítulo 22 · Terraform en CI/CD

Capítulo 23 · Seguridad en profundidad

Capítulo 24 · Observabilidad: logs, métricas y trazas

Capítulo 25 · Optimización de costes

Capítulo 26 · Alta disponibilidad y disaster recovery

Capítulo 27 · Well-Architected Framework de AWS

Capítulo 28 · Arquitecturas serverless a escala

Capítulo 29 · Plataformas de datos en AWS

Capítulo 30 · Multi-cuenta y landing zones

Capítulo 31 · Platform Engineering e Internal Developer Platform

Capítulo 32 · Certificaciones AWS relevantes

Capítulo 33 · Proyectos para consolidar lo aprendido

Capítulo 34 · Recursos y comunidad

© Copyright 2024. Todos los derechos reservados