Actualización del módulo Terraform en los clústeres públicos de GKE

Introducción

De vez en cuando, Google introduce nuevas características y cambios que a veces también obligan a los módulos de Terraform a actualizarse. En Geko, estábamos usando el módulo GKE para la implementación y administración de clústeres públicos en la versión 5.x. Hace unos días, cuando planeamos actualizar algunos parámetros, descubrimos que Google había eliminado la compatibilidad con el panel de control de Kubernetes. Estaba completamente en desuso y el módulo estaba fallando debido a ello, por lo que nos vimos obligados a actualizar el módulo para cumplir con las nuevas condiciones. Hubo hasta 3 actualizaciones de versiones principales disponibles, por lo que decidimos probarlo y usar la última. Sin embargo, no era una solución independiente, ya que requería gestionar las incoherencias del estado de Terraform.

El objetivo de este laboratorio es aprender cómo actualizar el módulo oficial Terraform destinado a implementar y administrar un clúster GKE público. Nos ocuparemos especialmente de los cambios de ruptura del módulo (kubernetes-engine.beta-public-cluster), y lograremos obtener el estado consistente que teníamos antes de la falla que precedió a la actualización.

Tiempo estimado para terminar este laboratorio: ~ 20 minutos

1. Eliminar los recursos anteriores

¡Se recomienda encarecidamente realizar una copia de seguridad de archivos tfstate antes de continuar!

Es especialmente importante eliminar todos los recursos conflictivos del tfstate de Terraform ya que están vinculados entre ellos como dependencias. El objetivo aquí es eliminar cualquier enlace obsoleto antes de importarlo nuevamente desde la «imagen» actual que ya se ha desplegado.

Los componentes principales en un clúster de Kubernetes son las redes (y subredes), el grupo de nodos y el clúster en sí. Centrémonos en ellos.

terraform state rm module.gke.google_container_cluster.primary
terraform state rm module.gke.google_container_node_pool.pools[0]
terraform state rm module.vpc.google_compute_network.network
terraform state rm module.vpc.google_compute_subnetwork.subnetwork[0]
terraform state rm module.vpc.google_compute_subnetwork.subnetwork[1]

2. Actualizar versiones

Una vez eliminados los estados anteriores, el siguiente paso es configurar la última versión los módulos requeridos. Para el módulo GKE, la última versión disponible a fecha de hoy es 8.1.0, pero se permite aplicar automáticamente actualizaciones menores («~>»).

Actualizar el módulo clúster GKE
 module "gke" {
   source  = "terraform-google-modules/kubernetes-engine/google//modules/beta-public-cluster"
-  version = "~> 5.0"
+  version = "~> 8.1"
Actualizar el módulo VPC
 module "vpc" {
-  source  = "github.com/terraform-google-modules/terraform-google-network?ref=v1.1.0"
+  source  = "github.com/terraform-google-modules/terraform-google-network?ref=v2.3.0"
Comprobar los nuevos recursos

Para saber si los nuevos recursos han experimentado un cambio de nombre (debido a la actualización de los módulos), se recomienda encarecidamente lanzar un plan de Terraform.

En este caso, se ha encontrado que la jerarquía interna de algunos módulos y también los índices de la lista han cambiado.

  module.gke.google_container_cluster.primary
  
- module.gke.google_container_node_pool.pools[0]
+ module.gke.google_container_node_pool.pools["default-node-pool"]

  module.vpc.google_compute_network.network
  
- module.vpc.google_compute_subnetwork.subnetwork[0]
+ module.vpc.module.subnets.google_compute_subnetwork.subnetwork["southamerica-east1/my-cluster-public"]

- module.vpc.google_compute_subnetwork.subnetwork[1]
+ module.vpc.module.subnets.google_compute_subnetwork.subnetwork["southamerica-east1/my-cluster-private"]

3. Importar los nuevos recursos

Ten en cuenta que la zona/región depende del tipo de clúster. Si es de zona, debe usar la zona maestra (por ejemplo, southamerica-east1-a). Por otro lado, si se trata de un clúster regional, debe usar la región (por ejemplo, southamerica-east1). El siguiente ejemplo supone un clúster regional ubicado en southamerica-east1, en el proyecto «my-project» y con el nombre de clúster «my-cluster». Los nombres de red se configuraron de acuerdo con el nombre del clúster, simplemente agregando los sufijos «private» y «public» a las subredes para diferenciarlos adecuadamente.

Ten en cuenta también la nueva jerarquía de módulos e indexación.

# Global vars
REGION="southamerica-east1"
PROJECT="my-project"
CLUSTER="my-cluster"

# Cluster
CLUSTER_LOCAL="module.gke.google_container_cluster.primary"
CLUSTER_REMOTE="${PROJECT}/${REGION}/${CLUSTER}"
terraform import $CLUSTER_LOCAL $CLUSTER_REMOTE

# Node pool
POOL_LOCAL="module.gke.google_container_node_pool.pools["default-node-pool"]"
POOL_REMOTE="${CLUSTER_REMOTE}/default-node-pool"
terraform import $POOL_LOCAL $POOL_REMOTE

# Subnetworks
BASE_SUBNET_LOCAL="module.vpc.module.subnets.google_compute_subnetwork.subnetwork"

## Public
PUBLIC_SUBNET_LOCAL="${BASE_SUBNET_LOCAL}["${REGION}/${CLUSTER}-public"]"
PUBLIC_SUBNET_REMOTE="${CLUSTER_REMOTE}-public"
terraform import $PUBLIC_SUBNET_LOCAL $PUBLIC_SUBNET_REMOTE

## Private
PRIVATE_SUBNET_LOCAL="${BASE_SUBNET_LOCAL}["${REGION}/${CLUSTER}-private"]"
PRIVATE_SUBNET_REMOTE="${CLUSTER_REMOTE}-private"
terraform import $PRIVATE_SUBNET_LOCAL $PRIVATE_SUBNET_REMOTE

# Network
NETWORK_LOCAL="module.vpc.module.vpc.google_compute_network.network"
NETWORK_REMOTE="${PROJECT}/${CLUSTER}"
terraform import $NETWORK_LOCAL $NETWORK_REMOTE

 4. Actualizar parámetros

Es muy probable que encuentres que, después de lanzar un plan de Terraform, el recurso google_container_cluster todavía necesite actualizarse debido a un cambio en el parámetro de subred. Las nuevas claves de subred han hecho que los índices cambien su orden. Simplemente edita el módulo GKE para reemplazar el parámetro subnetwork como se muestra a continuación.

- subnetwork = module.vpc.subnets_names[0]
+ subnetwork = module.vpc.subnets_names[1]

Conclusión

Como habrás visto anteriormente, a veces, al depender de terceros, puede suceder que se introduzca un cambio importante y tengas problemas para recuperar el servicio nuevamente. Además de esto, la solución podría introducir daños colaterales que requerirán subsoluciones adicionales. En este caso particular con respecto a Terraform, lidiar con estados inconsistentes no es realmente común ni recomendado, pero es el único método que tiene disponible para resolverlos en su conjunto de herramientas.


Espero que hayas disfrutado de este post y te animo a que revises nuestro blog para leer otrosposts que puedan ser de tu interés. No dudes en contactarnos si deseas que te ayudemos en tus proyectos.

¡Nos vemos en la próxima entrada!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *