Terraform en Google Cloud: los patrones que aguantan y las trampas del proveedor
El proveedor google tiene comportamientos que te sorprenderán la primera vez: recursos IAM autoritativos que barren bindings, proyectos que no se borran, APIs que hay que activar antes de que nada funcione. Esta es la configuración que usamos.
Terraform en Google Cloud es agradable hasta la tarde en que sustituyes toda la política de IAM de un proyecto con un recurso de tres líneas. Ese accidente concreto le ha pasado a suficientes equipos como para merecer ser la primera sección.
Los recursos de IAM, por orden de peligro
El proveedor google te da tres formas de conceder un rol, y no son equivalentes.
google_project_iam_member— aditivo. Concede un rol a un miembro y deja todo lo demás en paz. Esto es lo que quieres casi siempre.google_project_iam_binding— autoritativo para ese rol. Fija la lista completa de miembros de un rol y elimina a quien no esté en tu configuración.google_project_iam_policy— autoritativo para el proyecto entero. Sustituye todos los bindings del proyecto por exactamente lo que escribiste.
El último, aplicado a un proyecto cuyo IAM estaba en parte gestionado a mano o por otro equipo, elimina el acceso de todos los que no listaste. Incluida, a veces, la cuenta de servicio que ejecuta Terraform, lo que convierte un error en un error que no puedes arreglar con Terraform.
Usa _member salvo que necesites específicamente comportamiento autoritativo, y si usas _binding, úsalo solo para roles que posees por completo. El mismo patrón se repite para buckets, cuentas de servicio y todas las demás superficies de IAM del proveedor, con los mismos tres sufijos.
Arranque de proyectos y APIs
Dos cosas muerden en la primera hora:
Las APIs hay que activarlas antes de que existan los recursos, y activar una API es en sí eventualmente consistente. Usa google_project_service con disable_on_destroy = false —si no, destruir una carga desactiva una API de la que dependían en silencio los recursos de otro proyecto— y cuenta con necesitar una dependencia o una espera corta en el primer apply.
Los proyectos creados por Terraform conservan el comportamiento de deletionProtection y de los liens que configures. Los liens merecen la pena en proyectos de producción: un lien hace que el borrado del proyecto falle hasta que alguien lo quite a propósito, que es una buena propiedad para el recurso que contiene todo lo demás.
Los IDs de proyecto son únicos globalmente e inmutables. Usa una convención de nombres con sufijo aleatorio desde el principio en lugar de descubrir la colisión en prod.
Estado y estructura
El reparto sigue el mismo principio que en AWS: un estado por proyecto y capa, remoto en un bucket de GCS con versionado activado, en el proyecto bootstrap.
Los backends de GCS gestionan el bloqueo de forma nativa, así que no hay ningún equivalente a DynamoDB que montar. Activa el versionado del bucket antes del primer apply; recuperar un estado corrupto es trivial con él y un proyecto de reconstrucción sin él.
Las referencias entre capas van por data sources. Resiste el terraform_remote_state apuntando al bucket de otro equipo, por el mismo motivo que en todas partes: es un acoplamiento que nada hace visible.
Autenticación, sin claves
Terraform en CI autentica por Workload Identity Federation, no con una clave de cuenta de servicio. El token OIDC del pipeline se intercambia por una credencial de vida corta para una cuenta de servicio de Terraform, con una condición de atributos que la fija a tu repositorio. Los humanos usan gcloud auth application-default login más suplantación de esa misma cuenta para los planes, lo que significa que el plan corre con permisos de producción pero deja una traza de auditoría con su identidad.
Esto importa más en GCP que en otros sitios porque la clave de cuenta de servicio es una respuesta equivocada muy cómoda — mira por qué es la credencial que se filtra.
Rarezas del proveedor que conviene saber antes de que te cuesten un día
googlefrente agoogle-beta. Muchas funciones útiles son solo beta. Configura ambos proveedores y usa el beta por recurso, en lugar de cambiar toda la configuración.- Etiquetas y los valores por defecto del propio proveedor. El proveedor añade
goog-terraform-provisioned; si comparas etiquetas en comprobaciones de política, tenlo en cuenta. google_compute_instancerecrea ante muchos cambios. Mira el plan buscando-/+antes de aplicar a algo con estado; los cambios de tipo de máquina son in situ, pero algunos de disco y metadatos no.- Las org policies son jerárquicas y las gestionadas por Terraform pueden pelearse con las de consola. Gestiónalas en un solo sitio.
- Las conexiones de service networking para Cloud SQL privado se comparten por VPC y son una fuente clásica de "por qué se cuelga este apply" — tardan varios minutos y no paralelizan bien.
El pipeline
La misma forma que en todas partes: fmt, validate, tfsec o checkov, plan en el pull request con una identidad de solo lectura, aprobación manual para producción y apply desde el plan guardado. Añade la salida de gcloud recommender como informe semanal y no como puerta — las recomendaciones son consejos, y un consejo no va en un bloqueo de merge. Montamos esto al inicio de casi todos los proyectos cloud, normalmente junto a la estructura de carpetas y org policies.
Qué hacer esta semana
Busca en tu configuración google_project_iam_policy y _iam_binding. Cada coincidencia es un recurso que puede eliminar accesos que desconoce. Confirma que cada uno es intencionado y convierte el resto a _member.