Terraform 21: Condicionales (ternario) y bloques dynamic
easy⏱ 5 mincourseterraform
El condicional ternario
condición ? valor_verdadero : valor_falso devuelve uno de dos valores — la única expresión condicional en HCL (no hay sentencia if). Usalo para ajustes por entorno: SKUs más grandes en prod, más baratos en dev; un null para caer al default del provider.
variable "environment" {
type = string
default = "dev"
}
locals {
is_prod = var.environment == "prod"
sku_name = local.is_prod ? "P1v3" : "B1" # value chosen by env
capacity = local.is_prod ? 3 : 1
}
resource "azurerm_service_plan" "api" {
name = "orders-api-plan"
resource_group_name = azurerm_resource_group.main.name
location = "westus2"
os_type = "Linux"
sku_name = local.sku_name
}
Los bloques dynamic generan bloques anidados
Algunos recursos aceptan bloques anidados repetibles (p. ej. security_rule, ip_restriction). Un dynamic "<bloque>" itera una colección con for_each y emite un bloque por elemento; dentro de content, <bloque>.value es el elemento actual. Es for_each para bloques anidados en lugar de recursos enteros.
variable "ingress_rules" {
type = list(object({
name = string
priority = number
port = string
}))
default = [
{ name = "https", priority = 100, port = "443" },
{ name = "http", priority = 110, port = "80" },
]
}
resource "azurerm_network_security_group" "app" {
name = "orders-app-nsg"
resource_group_name = azurerm_resource_group.main.name
location = "westus2"
dynamic "security_rule" {
for_each = var.ingress_rules
content {
name = security_rule.value.name
priority = security_rule.value.priority
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = security_rule.value.port
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
}
Colección vacía = cero bloques
Pasá una lista vacía a un bloque dynamic para emitir cero bloques anidados — el idioma para configuración opcional: for_each = var.docker == null ? [] : [var.docker]. No abuses de dynamic; un par de bloques estáticos se leen mejor que un loop de un solo elemento.
Modelá un ternario + expansión dynamic
Escribí skuFor(env) que devuelva "P1v3" si env === "prod" y si no "B1" (un ternario). Después escribí expandDynamic(rules) que devuelva un { name, port } por regla (lo que emite un bloque dynamic). Con las dos reglas por defecto, logueá skuFor("dev") y expandDynamic(rules).length — esperado una línea con B1 y una línea con 2.