Terraform Associate
Deep Dive
Las variables hacen los módulos parametrizables y reutilizables. Los outputs exponen valores hacia afuera. Los locals son valores intermedios calculados. Dominar su precedencia y comportamiento es clave para el examen.
Contenido
# Declaración completa de una variable
variable "instance_type" {
type = string # tipo de dato
default = "t3.micro" # valor por defecto (hace la variable opcional)
description = "Tipo de instancia EC2" # documentación
sensitive = false # si true, oculta el valor en los logs
validation {
condition = contains(["t3.micro", "t3.small", "t3.medium"], var.instance_type)
error_message = "instance_type debe ser t3.micro, t3.small o t3.medium."
}
}
# Variable sin default (OBLIGATORIA — Terraform preguntará el valor)
variable "db_password" {
type = string
sensitive = true
description = "Contraseña de la base de datos"
}
# Variable con tipo complejo
variable "allowed_cidrs" {
type = list(string)
default = ["10.0.0.0/8", "172.16.0.0/12"]
}
variable "tags" {
type = map(string)
default = {
Environment = "dev"
Team = "platform"
}
}💡 Validación con condition
El bloque validation dentro de una variable permite validar el valor antes de que Terraform ejecute el plan. La condition debe ser una expresión booleana que use var.nombre. Si evalúa a false, Terraform muestra el error_message.
Terraform evalúa las variables en orden de precedencia. Los métodos de mayor número en la lista sobrescriben a los anteriores.
Valor default en el bloque variable {}
default = "us-east-1"
Archivo terraform.tfvars
aws_region = "us-west-2"
Archivo *.auto.tfvars (orden alfabético)
prod.auto.tfvars — se carga automáticamente
Variables de entorno TF_VAR_nombre
export TF_VAR_aws_region="eu-west-1"
Flag -var-file=archivo.tfvars
terraform plan -var-file=prod.tfvars
Flag -var="clave=valor"
terraform plan -var="aws_region=ap-southeast-1"
# terraform.tfvars — se carga automáticamente si existe en el directorio
aws_region = "us-east-1"
instance_type = "t3.small"
db_password = "super-secret" # ⚠️ no commitear si tiene secretos
# prod.auto.tfvars — se carga automáticamente (por el .auto.)
environment = "prod"
instance_type = "t3.large" # sobrescribe terraform.tfvars
# Referencia en código: var.nombre_variable
resource "aws_instance" "web" {
instance_type = var.instance_type
ami = var.ami_id
}🎯 Para el examen: la pregunta de precedencia
El examen suele preguntar: "Si la variable X está definida como default, en terraform.tfvars y con -var, ¿qué valor se usa?". La respuesta es -var (la mayor precedencia). Memoriza el orden: default → tfvars → auto.tfvars → TF_VAR → -var-file → -var.
El atributo sensitive = true en una variable le indica a Terraform que oculte su valor en la salida del CLI (plan, apply). Sin embargo, tiene limitaciones importantes.
✅ Qué SÍ hace sensitive = true
(sensitive value)⚠️ Qué NO hace sensitive = true
variable "db_password" {
type = string
sensitive = true
}
# En el plan verás:
# + db_password = (sensitive value) ← valor oculto en CLI
# PERO en terraform.tfstate verás:
# "db_password": "mi-password-secreto" ← en texto plano ⚠️
# Por eso se recomienda:
# 1. Usar backend remoto con cifrado (S3 + KMS o HCP Terraform)
# 2. Recuperar secretos de Vault/Secrets Manager en tiempo de ejecuciónLos valores efímeros son valores que Terraform utiliza en memoria durante el plan/apply pero no persiste en el state ni en los logs. Diseñados para manejar secretos reales (contraseñas, tokens) de forma segura.
# Variable efímera — no se escribe en el state
variable "db_password" {
type = string
ephemeral = true # nuevo en Terraform 1.10+
}
# Ephemeral resource — datos que no persisten en state
ephemeral "aws_secretsmanager_secret_version" "db_creds" {
secret_id = "prod/db/password"
}
# Argument write-only — acepta valor efímero en un recurso
resource "aws_db_instance" "main" {
identifier = "prod-db"
engine = "postgres"
password = ephemeral.aws_secretsmanager_secret_version.db_creds.secret_string
# password tiene write_only = true: se envía a la API pero no se guarda en state
}variable ephemeral
Valor de entrada que no se guarda en state. Ideal para passwords y tokens que solo se necesitan durante el apply.
ephemeral resource
Bloque ephemeral {} para datos externos (Vault, Secrets Manager) cuyo valor no debe persistir en state.
write-only argument
Atributo de recurso que Terraform envía a la API del proveedor pero no almacena en el state ni muestra en el plan.
🎯 Para el examen (004)
sensitive = true oculta el valor en la salida del CLI pero sigue guardándose en el stateephemeral = true (Terraform 1.10+) hace que el valor no se persista en el state en absoluto — seguridad real para secretsephemeral resources pueden usarse con proveedores de secretos (Vault, AWS Secrets Manager)Los outputs exponen valores del módulo al exterior: al usuario (se muestran en el apply), al módulo padre (accesibles como module.nombre.output), y como datos del estado (accesibles via terraform output).
# Declaración de outputs
output "vpc_id" {
value = aws_vpc.main.id
description = "ID de la VPC principal"
}
output "db_endpoint" {
value = aws_db_instance.main.endpoint
description = "Endpoint de conexión a la base de datos"
sensitive = true # oculto en CLI, pero disponible para módulos padres
}
output "subnet_ids" {
value = aws_subnet.public[*].id # lista de IDs con splat expression
description = "IDs de las subnets públicas"
}
# Acceso desde módulo padre:
# module.networking.vpc_id
# module.networking.subnet_ids
# Acceso desde CLI:
# terraform output vpc_id
# terraform output -json| Argumento | Requerido | Descripción |
|---|---|---|
| value | ✅ Sí | La expresión cuyo resultado se expone como output |
| description | ❌ No | Documentación del output (buena práctica, recomendado siempre) |
| sensitive | ❌ No | Si true, oculta el valor en CLI. Se hereda si value referencia una variable sensitive. |
| depends_on | ❌ No | Declara dependencias explícitas cuando el valor no las tiene implícitas |
Los locals son valores calculados dentro del módulo que puedes reutilizar en múltiples lugares. A diferencia de las variables, no pueden ser sobreescritos desde fuera del módulo.
# Bloque locals (plural: el bloque se llama "locals")
locals {
# Combinar variables para crear un nombre estándar
name_prefix = "${var.project}-${var.environment}"
# Tags comunes aplicados a todos los recursos
common_tags = {
Project = var.project
Environment = var.environment
ManagedBy = "terraform"
Owner = var.team
}
# Cálculo complejo
is_production = var.environment == "prod"
instance_type = local.is_production ? "t3.large" : "t3.micro"
}
# Acceso: local.nombre (singular: "local")
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = merge(local.common_tags, {
Name = "${local.name_prefix}-vpc"
})
}| Característica | variable {} | locals {} |
|---|---|---|
| ¿Configurable desde fuera? | ✅ Sí — eso es su propósito | ❌ No — son internos al módulo |
| ¿Puede contener expresiones? | Solo en default y validation | ✅ Sí — cualquier expresión HCL |
| Prefijo de acceso | var.nombre | local.nombre (singular) |
| Bloque de declaración | variable "nombre" {} | locals {} (único bloque con varias claves) |
| Cuándo usar | Parámetro que el usuario define | Valor derivado/calculado interno del módulo |
¿Entendiste este tema?
Pon a prueba lo que acabas de aprender
Un ingeniero define una variable db_password con sensitive = true y la usa como argumento en un recurso aws_db_instance. Después ejecuta terraform apply con éxito. ¿Dónde aparecerá la contraseña en texto plano?