Terraform 39: Key Vault y secretos bien hechos
easy⏱ 5 mincourseterraform
Buscá el vault, no lo crees acá
Un Key Vault suele ser un recurso compartido y de larga vida, propiedad de un equipo de plataforma. Tu servicio lo lee con un data source (por nombre + resource group) para obtener su id sin gestionar su ciclo de vida. Después escribís secretos en él.
data "azurerm_key_vault" "app" {
name = "orders-kv-dev"
resource_group_name = "myorg-orders-dev-rg"
}
# data.azurerm_key_vault.app.id is now usable everywhere below
Un secreto por entrada del mapa con for_each
Manejá la creación de secretos desde un mapa local para que agregar un secreto sea un cambio de una línea, no un bloque copiado. Cada each.key es el nombre del secreto y each.value su origen — idealmente el output de otro recurso, no un literal.
locals {
secrets = {
"orders-db-connection" = azurerm_postgresql_flexible_server.orders.connection_string
"orders-storage-endpoint" = azurerm_storage_account.orders.primary_blob_endpoint
}
}
resource "azurerm_key_vault_secret" "app" {
for_each = local.secrets
name = each.key
value = each.value
key_vault_id = data.azurerm_key_vault.app.id
expiration_date = "2099-12-30T00:00:00Z"
}
Nunca pongas valores de secretos en state ni en vars
No hardcodees un secreto, ni lo pases como default de una variable, ni lo versiones en terraform.tfvars. Tomá los valores de atributos de otros recursos (connection strings, keys) o seteálos por fuera. Además tratá el archivo de state como sensible: guardalo en un backend remoto cifrado con locking y acceso restringido — nunca versiones terraform.tfstate.
# ANTI-PATTERN — never do this
variable "db_password" {
default = "S3cr3t!" # committed in VCS, printed in plans, saved in state
}
# DO THIS — value comes from a resource attribute, not a literal
# value = azurerm_postgresql_flexible_server.orders.administrator_password
Poné una expiración y apoyate en soft-delete
Muchos controles de compliance exigen expiration_date en cada secreto. El soft-delete + purge protection de Key Vault también hacen que un secreto borrado se pueda recuperar — configurá el feature block key_vault del provider en consecuencia en vez de forzar el purge al destruir.
Listá los secretos que for_each crearía
Dado secretSources (un mapa nombre-de-secreto → descripción de origen), escribí secretNames(sources) que devuelva el array ordenado de claves — justo los nombres que azurerm_key_vault_secret produciría. Logueá secretNames(secretSources).join(", "). NO debe loguear ningún valor de origen (esa es la parte sensible).