GKE de nivel productivo con Terraform y una Shared VPC
Llevar un parque de GKE aprovisionado a mano al 100% de infraestructura como código: una Shared VPC, clusters privados, un despliegue en 8 fases y las protecciones que detienen un destroy accidental. Además, las landing zones de código abierto que construí para GCP, AWS y Azure con el mismo patrón.
Módulos reutilizables de Terraform aprovisionan los límites de red y los recursos de GKE de forma consistente.
Contribución de un vistazo
- Mi responsabilidad
- Terraform modular, límites de red y un despliegue por fases de la plataforma de GKE.
- Alcance
- Shared VPC e infraestructura de entornos aislados; los ejemplos públicos de landing zone son código reutilizable aparte.
- Colaboración y límites
- Diseñé e implementé la base de infraestructura descrita aquí; los ejemplos públicos generalizan el patrón en lugar de exponer la configuración del empleador.
- Resultado
- Aprovisionamiento de entornos reutilizable y recursos de red compartida protegidos, entregados mediante una transición de propiedad por fases.
Imagina un parque de GKE y la red que lo sostiene, todo aprovisionado a mano. Sin infraestructura como código, sin una historia consistente entre entornos y sin nada que impida que un terraform destroy accidental elimine la red compartida. Este es un relato de cómo reconstruí eso en una Shared VPC, clusters privados, una base de código modular de Terraform y un despliegue en ocho fases que nunca dejó el sistema a medio gestionar.
Todo lo que hay aquí es la técnica, sin nombres internos ni detalles específicos. Al final enlazo las landing zones de código abierto que construí para GCP, AWS y Azure, para que puedas leer el código real detrás del mismo patrón.
El punto de partida
Los clusters y la red se crearon a través de la consola y un archivo de Terraform monolítico, copiado y pegado. No había ningún módulo reutilizable, ninguna estrategia por entorno ni prevent_destroy en la red. En otras palabras, el único recurso que no puedes recrear a la ligera, la VPC, era lo menos protegido del proyecto.
La arquitectura objetivo
- Shared VPC. Un único host project es dueño de la VPC, las subnets, Cloud NAT y el firewall. Cada entorno es un service project adjunto a él, de modo que la red vive en un solo lugar y los clusters nunca son dueños de su propia VPC.
- Clusters privados. Los nodos no tienen IPs públicas. Todo el egress sale a través de Cloud NAT, de modo que la superficie expuesta a internet es una sola puerta de enlace, no cada nodo.
- Workload Identity. Los pods se autentican como service accounts de GCP sin claves a nivel de nodo que gestionar o filtrar.
- Shielded nodes. Secure Boot e Integrity Monitoring en cada nodo.
- Mínimo privilegio. Una service account dedicada por entorno, acotada a lo que ese entorno necesita.
- Estado remoto. El estado de Terraform en un backend de GCS, no en la laptop de nadie.
El despliegue, en ocho fases
El objetivo de dividirlo en fases era no tener nunca una ventana en la que la red estuviera a medio gestionar. Cada fase dejó el sistema en un estado funcional.
- 1. Diseño de arquitectura. Topología de la Shared VPC, estrategia de subnets y requisitos de los clusters para cuatro entornos.
- 2. Configuración de proyectos. Proyectos, APIs habilitadas y service accounts de IAM con asignaciones de mínimo privilegio.
- 3. Red. Host project de la Shared VPC, subnets, Cloud NAT y reglas de firewall, todo mediante Terraform.
- 4. Terraform modular. Se refactorizó de recursos monolíticos en línea a módulos reutilizables; la configuración raíz pasó a ser llamadas a módulos más un archivo de variables por entorno.
- 5. CI/CD. GitHub Actions:
terraform planen el pull request,terraform applyen el merge, un workflow separado por entorno. - 6. Clusters. Los cuatro clusters de GKE (dev, stg, prd, sandbox) desplegados a través de los pipelines.
- 7. Protecciones.
prevent_destroy = trueen la VPC, las subnets y Cloud NAT. - 8. Documentación. Diagramas de arquitectura, runbooks y documentación de los módulos para el traspaso.
La protección que más importa
Un bloque lifecycle prevent_destroy en la VPC, las subnets y Cloud NAT hace que un terraform destroy accidental de la red falle en lugar de tener éxito. La red es lo único que no puedes recrear a la ligera, así que es lo único que debería negarse a ser eliminado. Cuesta tres líneas y ha evitado caídas reales.
Resultados
- Cada recurso de red y de cluster se gestiona en Terraform. Ya nada se crea a clics.
- Los cuatro clusters se levantan en una sola ejecución automatizada del pipeline.
- Un nuevo entorno es un nuevo archivo de variables, no código nuevo.
- La red compartida está protegida contra la destrucción accidental, y todos los service projects enrutan el egress a través de una sola puerta de enlace NAT.
El mismo patrón, como código abierto
El relato anterior se mantiene genérico, así que aquí está el mismo patrón como código que sí puedes leer. Construí una landing zone para cada nube principal: una configuración de Terraform más GitHub Actions para Kubernetes multientorno, con los valores de seguridad por defecto ya integrados (estado remoto, sin secrets en el repositorio, IAM de mínimo privilegio, un aviso de seguridad destacado en cada README).
- GCP landing zone — GKE, Shared VPC, Terraform y GitHub Actions. El reflejo más cercano de la arquitectura anterior.
- AWS landing zone — la misma forma sobre EKS: VPC, IAM y Terraform multientorno.
- Azure landing zone — AKS con foco en gobernanza, seguridad y despliegues multientorno.
Lo que le diría a alguien que empieza esto
- Pon la red en un host project con Shared VPC desde el primer día. Adaptarla después a clusters que ya son dueños de su VPC es doloroso.
- Agrega
prevent_destroya todo lo que no puedas permitirte recrear, antes de necesitarlo, no después del primer susto. - Haz que un nuevo entorno sea un archivo de variables, no un copiar y pegar del código. Si agregar un entorno implica editar recursos, la configuración todavía no es modular.
- Mantén el estado remoto y los secrets fuera del repositorio. Las landing zones de arriba muestran los valores por defecto que uso.
Decisiones y próximos pasos
Una mirada retrospectiva al enfoque y sus límites. La próxima mejora es una propuesta, no un resultado entregado.
Alternativa y justificación
Un stack monolítico es rápido de empezar; separar la red compartida de las cargas de trabajo por entorno reduce el acoplamiento destructivo.
Contrapartida
Los módulos añaden interfaces y límites de estado que requieren propiedad, versionado y migración segura.
Lo que mejoraría a continuación
Próxima mejora: automatizar las verificaciones de drift y validar la recuperación desde cada límite de estado de la infraestructura.