Hi ha una pregunta que la Marta porta evitant des del mòdul 3, i que un auditor, un client corporatiu o un incident greu faran tard o d'hora: si demà calgués reconstruir tota la infraestructura d'AlpinaShop en una altra regió, quant de temps es trigaria?

La resposta honesta és que ningú no ho sap. La VPC alpinashop-vpc, les subxarxes sn-web-euw1 i sn-datos-euw1, el Cloud NAT, les regles fw-*, el balancejador global amb la seva comprovació d'estat i el seu mapa d'URL, la política de Cloud Armor, la zona de Cloud DNS, el certificat, el MIG, el clúster de GKE, els comptes de servei, els rols personalitzats: tot això es va crear amb comandes de gcloud que la Marta va executar al llarg de diverses setmanes. Algunes van sortir a la primera. D'altres es van ajustar després per consola. Unes quantes es van esborrar i es van refer. L'únic registre d'aquest procés és l'historial del seu terminal, que a més és incomplet perquè inclou comandes que es van desfer i omet els canvis fets amb el ratolí.

I hi ha una segona conseqüència, més insidiosa. alpinashop-dev es va crear a partir d'alpinashop-prod, però va anar divergint: una regla de tallafoc que es va relaxar per fer una prova, una mida de màquina diferent, una configuració de Cloud SQL que no es va replicar mai. Avui provar en desenvolupament no garanteix res sobre producció, perquè no són el mateix sistema. Això s'anomena deriva de configuració i és la raó per la qual desplegaments provats fallen en producció.

Aquesta lliçó ataca aquest problema. I ho fa amb un advertiment que cal donar aviat: l'eina que dona títol a la lliçó no és la que has d'utilitzar. Val la pena entendre per què, i sobretot què fer quan te la trobis.

Contingut

  1. El problema concret: infraestructura que només existeix en un historial
  2. Què és la infraestructura com a codi
  3. Declaratiu davant d'imperatiu, i idempotència
  4. L'estat: la idea que fa possible tota la resta
  5. Deployment Manager: l'eina nativa de GCP
  6. Plantilles en Jinja i en Python
  7. Un exemple real: la VPC i el tallafoc d'AlpinaShop
  8. L'avís central: Deployment Manager està descontinuat
  9. La successió: Infrastructure Manager, Config Connector i Terraform
  10. Com es migra de Deployment Manager a Terraform, pas a pas
  11. Els conceptes que es conserven entre eines

  1. El problema concret: infraestructura que només existeix en un historial

Val la pena posar xifres al que costa la situació actual, perquè l'argument a favor de la infraestructura com a codi no és estètic:

Situació real Conseqüència avui Amb IaC
Cal recrear l'entorn a europe-west4 Setmanes, amb errors garantits Canviar una variable i aplicar
Algú pregunta quines regles de tallafoc hi ha Es llisten per consola, sense saber per què existeixen Es llegeix el fitxer, amb els seus comentaris
Es vol revisar un canvi abans d'aplicar-lo Impossible: s'aplica i es veu què passa Pull request amb el pla adjunt
alpinashop-dev no s'assembla a producció Ningú no sap en què difereixen El mateix codi, diferents variables
La Marta se'n va de vacances Ningú no toca res Qualsevol pot llegir i proposar canvis
Un canvi trenca producció Què hi havia abans? Ningú no ho sap git revert i aplicar
Auditoria: qui va canviar el tallafoc i quan Registres d'auditoria, sense context ni motiu Commit amb autor, data i justificació

La fila de l'incident mereix èmfasi. Quan un canvi manual trenca producció, la pregunta urgent és «quina era la configuració anterior?». Sense IaC, l'única font és la memòria de qui ho va canviar, sota pressió i amb pressa. Amb IaC, la resposta és a Git i tornar enrere és una operació coneguda.

I la deriva entre entorns és la que surt més cara a mitjà termini, perquè erosiona el valor de les proves. Tota la feina de 06-01 —proves automàtiques, desplegament a alpinashop-dev, promoció a producció— descansa en la premissa que desenvolupament s'assembla a producció. Si no s'hi assembla, el pipeline dona una confiança que no està justificada.

  1. Què és la infraestructura com a codi

Infraestructura com a codi (IaC) és la pràctica de definir la infraestructura en fitxers de text versionats, i de crear-la i modificar-la exclusivament aplicant aquests fitxers amb una eina, mai a mà.

Aquesta última part és la que costa i la que dona tot el valor. Tenir fitxers de Terraform i continuar tocant coses per consola és el pitjor de tots dos mons: la complexitat de l'eina sense la garantia que el codi reflecteixi la realitat.

Benefici Què significa a la pràctica
Reproductibilitat El mateix codi produeix la mateixa infraestructura, sempre
Revisió Un canvi de tallafoc es discuteix en un pull request abans d'existir
Història git log sobre la infraestructura, amb autor i motiu
Reversió Tornar a la configuració d'ahir és una comanda
Documentació viva El codi és la documentació, i no queda obsoleta
Entorns coherents Desenvolupament i producció comparteixen definició
Automatització El pipeline de 06-01 pot aplicar canvis d'infraestructura
Recuperació davant de desastres Reconstruir és aplicar, no improvisar

La comparació directa amb la feina per consola:

Aspecte Consola / gcloud a mà Infraestructura com a codi
Velocitat la primera vegada Més ràpida Més lenta: cal escriure
Velocitat la desena vegada Igual de lenta cada vegada Instantània
Errors humans Freqüents i silenciosos Detectats en la revisió
Coneixement Al cap d'una persona Al repositori
Auditoria Registres sense context Commits amb motiu
Corba d'aprenentatge Cap Real

I convé ser honest amb el cost: IaC és més lent al principi. Crear una regla de tallafoc per consola són trenta segons; escriure-la, revisar-la i aplicar-la són deu minuts. La inversió es recupera la tercera o quarta vegada que cal tocar aquesta regla, i es multiplica quan cal replicar l'entorn o quan algú pregunta per què existeix.

  1. Declaratiu davant d'imperatiu, i idempotència

La diferència entre els dos enfocaments és la que fa que IaC funcioni.

Imperatiu és descriure els passos. És el que fa la Marta avui:

gcloud compute networks create alpinashop-vpc --subnet-mode=custom
gcloud compute networks subnets create sn-web-euw1 \
  --network=alpinashop-vpc --range=10.10.0.0/24 --region=europe-west1
gcloud compute firewall-rules create fw-permitir-salud \
  --network=alpinashop-vpc --allow=tcp:8080 \
  --source-ranges=35.191.0.0/16,130.211.0.0/22

Declaratiu és descriure el resultat desitjat, i deixar que l'eina calculi els passos:

resources:
  - name: alpinashop-vpc
    type: compute.v1.network
    properties:
      autoCreateSubnetworks: false

La diferència pràctica és en què passa en executar-ho dues vegades:

Imperatiu Declaratiu
Primera execució Crea els recursos Crea els recursos
Segona execució Falla: «ja existeix» No fa res: ja està com ha d'estar
Si es va modificar a mà No se n'assabenta Detecta la diferència i la corregeix
Si s'elimina alguna cosa del fitxer No se n'assabenta L'esborra

Aquesta propietat —que aplicar N vegades produeix el mateix resultat que aplicar-ne una— és la idempotència, i és el que permet executar el procés amb confiança. Pots aplicar la configuració cada matí: si no ha canviat res, no passa res; si algú va tocar alguna cosa a mà, es corregeix.

La tercera fila amaga el benefici més valuós: el declaratiu detecta i corregeix la deriva. Si algú obre el port 22 a tot internet en una prova i s'oblida de tancar-lo, la propera aplicació de la configuració ho detecta i ho reverteix. La infraestructura convergeix cap al que diu el codi.

I la quarta fila amaga el perill: si esborres un recurs del fitxer, l'eina el destrueix. No l'ignora: l'elimina, perquè el fitxer declara l'estat desitjat complet. Esborrar per descuit trenta línies d'un .yaml pot significar esborrar una base de dades.

  1. L'estat: la idea que fa possible tota la resta

Perquè una eina declarativa sàpiga que ha de modificar un recurs en lloc de crear-lo, necessita saber quins recursos gestiona. Aquest registre és l'estat.

flowchart LR
    A[Codi:<br/>estat DESITJAT] --> C{Comparació}
    B[Estat:<br/>el que l'eina<br/>GESTIONA] --> C
    D[Realitat a GCP:<br/>el que EXISTEIX] --> C
    C --> E[Pla de canvis:<br/>crear, modificar, destruir]

L'estat respon a tres preguntes que l'eina no pot contestar d'una altra manera:

  • Quins recursos gestiono? Distingeix el que va crear ella del que ja existia. Sense aquesta distinció, aplicar una configuració podria destruir recursos creats per un altre equip.
  • Quin identificador té cadascun? El nom lògic del fitxer (red_principal) no és l'identificador real a GCP.
  • Com estaven l'última vegada? Per calcular la diferència sense consultar tota l'API en cada execució.

La gran diferència entre les dues eines d'aquesta lliçó és precisament aquí:

Eina On viu l'estat Conseqüència
Deployment Manager Gestionat per Google, en el mateix servei No cal gestionar-lo, però no es veu ni es manipula
Terraform Un fitxer que tu gestiones (.tfstate) Control total, i responsabilitat total

Deployment Manager t'estalvia el problema de l'estat. Terraform te'l lliura, amb les seves conseqüències: cal desar-lo en un lloc compartit, amb bloqueig perquè dues persones no apliquin alhora, amb versionatge per si es corromp, i mai a Git, perquè conté valors sensibles. Tot això es resol a 06-07.

  1. Deployment Manager: l'eina nativa de GCP

Cloud Deployment Manager és l'eina d'infraestructura com a codi nativa de Google Cloud, disponible des del 2015. El seu model:

  • Una configuració en YAML declara recursos.
  • Cada recurs té un tipus derivat directament de les APIs de GCP (compute.v1.network, sqladmin.v1beta4.instance).
  • Un desplegament (deployment) és un conjunt de recursos gestionats com una unitat, amb el seu estat desat pel servei.
  • Les plantilles, en Jinja o Python, permeten parametritzar i reutilitzar.

La configuració mínima:

# red.yaml
resources:
  - name: alpinashop-vpc
    type: compute.v1.network
    properties:
      autoCreateSubnetworks: false
      description: "VPC principal d'AlpinaShop"

  - name: sn-web-euw1
    type: compute.v1.subnetwork
    properties:
      # $(ref....) crea una DEPENDÈNCIA IMPLÍCITA: la subxarxa espera la xarxa
      network: $(ref.alpinashop-vpc.selfLink)
      region: europe-west1
      ipCidrRange: 10.10.0.0/24
      privateIpGoogleAccess: true

La sintaxi $(ref.recurso.propiedad) és el mecanisme central: a més d'obtenir un valor que no es coneix fins que el recurs existeix, declara una dependència. Deployment Manager construeix un graf i crea els recursos en l'ordre correcte, paral·lelitzant el que pot. És exactament la mateixa idea que a Terraform, amb una altra sintaxi.

Les comandes del cicle de vida:

# Previsualitzar: calcula què faria, sense tocar res
gcloud deployment-manager deployments create red-alpinashop \
  --config=red.yaml --preview --project=alpinashop-dev

# Veure el pla calculat
gcloud deployment-manager deployments describe red-alpinashop \
  --project=alpinashop-dev

# Confirmar i executar
gcloud deployment-manager deployments update red-alpinashop \
  --project=alpinashop-dev

# Actualitzar després de canviar el fitxer
gcloud deployment-manager deployments update red-alpinashop \
  --config=red.yaml --project=alpinashop-dev

# Veure els recursos gestionats
gcloud deployment-manager resources list \
  --deployment=red-alpinashop --project=alpinashop-dev

# Destruir TOT el desplegament
gcloud deployment-manager deployments delete red-alpinashop \
  --project=alpinashop-dev

Dos advertiments operatius que convé tenir presents:

  • --preview és equivalent al plan de Terraform i no s'ha de saltar mai en un entorn seriós. Mostra què es crearà, es modificarà o es destruirà abans de tocar res.
  • deployments delete esborra tots els recursos del desplegament. No és «oblidar la configuració»: és destruir la VPC, les subxarxes i tot el que contingui. Executat sobre el desplegament equivocat en producció, és catastròfic.

També existeixen les polítiques d'actualització, que controlen què fer quan un canvi exigeix recrear un recurs:

gcloud deployment-manager deployments update red-alpinashop \
  --config=red.yaml \
  --delete-policy=ABANDON \
  --create-policy=CREATE_OR_ACQUIRE \
  --project=alpinashop-dev

ABANDON deixa de gestionar el recurs en lloc d'esborrar-lo —útil per treure alguna cosa del desplegament sense destruir-la— i CREATE_OR_ACQUIRE adopta un recurs que ja existeix amb aquest nom en lloc de fallar. Aquest últim és el mecanisme d'importació de Deployment Manager, i és molt més limitat que el de Terraform.

  1. Plantilles en Jinja i en Python

Una configuració plana no escala: si cal crear cinc regles de tallafoc gairebé idèntiques, copiar i enganxar és exactament el problema que IaC ve a resoldre. Les plantilles parametritzen.

Plantilla en Jinja, per al que és senzill:

{# subred.jinja #}
resources:
  - name: {{ properties["nom"] }}
    type: compute.v1.subnetwork
    properties:
      network: {{ properties["xarxaSelfLink"] }}
      region: {{ properties["region"] }}
      ipCidrRange: {{ properties["rang"] }}
      privateIpGoogleAccess: {{ properties.get("accesPrivatGoogle", true) }}

outputs:
  - name: selfLink
    value: $(ref.{{ properties["nom"] }}.selfLink)

I el seu ús:

# red.yaml
imports:
  - path: subred.jinja

resources:
  - name: alpinashop-vpc
    type: compute.v1.network
    properties:
      autoCreateSubnetworks: false

  - name: subred-web
    type: subred.jinja
    properties:
      nom: sn-web-euw1
      xarxaSelfLink: $(ref.alpinashop-vpc.selfLink)
      region: europe-west1
      rang: 10.10.0.0/24

  - name: subred-datos
    type: subred.jinja
    properties:
      nom: sn-datos-euw1
      xarxaSelfLink: $(ref.alpinashop-vpc.selfLink)
      region: europe-west1
      rang: 10.20.0.0/24

Plantilla en Python, quan cal lògica de veritat. Una plantilla Python és una funció GenerateConfig(context) que retorna un diccionari amb els recursos:

# firewall.py
"""Genera les regles de tallafoc d'AlpinaShop a partir d'una llista."""

REGLES_BASE = [
    {"nom": "fw-permitir-salud", "ports": ["tcp:8080"],
     "origens": ["35.191.0.0/16", "130.211.0.0/22"],  # sondes de Google (03-02)
     "etiquetes": ["catalogo-web"]},
    {"nom": "fw-permitir-web-interno", "ports": ["tcp:8080"],
     "origens": ["10.10.0.0/24"], "etiquetes": ["catalogo-web"]},
    {"nom": "fw-permitir-sql", "ports": ["tcp:5432"],
     "origens": ["10.10.0.0/24"], "etiquetes": ["base-datos"]},
]


def GenerateConfig(context):
    xarxa = context.properties["xarxaSelfLink"]
    entorn = context.properties["entorn"]
    recursos = []

    for regla in REGLES_BASE:
        recursos.append({
            "name": f"{regla['nom']}-{entorn}",
            "type": "compute.v1.firewall",
            "properties": {
                "network": xarxa,
                "sourceRanges": regla["origens"],
                "targetTags": regla["etiquetes"],
                "allowed": [
                    {"IPProtocol": p.split(":")[0], "ports": [p.split(":")[1]]}
                    for p in regla["ports"]
                ],
                "description": f"Generada per IaC - entorn {entorn}",
            },
        })

    # Regla EXCLUSIVA de desenvolupament: SSH des de la VPN de l'oficina.
    # En producció no existeix, i aquest és exactament l'avantatge d'usar codi.
    if entorn == "dev":
        recursos.append({
            "name": "fw-permitir-ssh-oficina-dev",
            "type": "compute.v1.firewall",
            "properties": {
                "network": xarxa,
                "sourceRanges": [context.properties["cidrOficina"]],
                "allowed": [{"IPProtocol": "tcp", "ports": ["22"]}],
            },
        })

    return {"resources": recursos}

El bloc condicional del final il·lustra el benefici principal: la diferència entre entorns deixa de ser accidental i passa a estar escrita. Avui ningú no sap en què difereix alpinashop-dev d'alpinashop-prod; amb això, la diferència són cinc línies de codi amb un if explícit, revisades en un pull request.

Deployment Manager admet a més esquemes (.schema) que validen els paràmetres d'una plantilla —tipus, valors obligatoris, expressions regulars— i produeixen errors clars abans de tocar res. És una bona idea que Terraform recull després amb la validació de variables.

  1. Un exemple real: la VPC i el tallafoc d'AlpinaShop

Ajuntant-ho tot, així quedaria la xarxa d'AlpinaShop a Deployment Manager:

# alpinashop-red.yaml
imports:
  - path: subred.jinja
  - path: firewall.py

resources:
  - name: alpinashop-vpc
    type: compute.v1.network
    properties:
      autoCreateSubnetworks: false
      routingConfig:
        routingMode: REGIONAL
      description: "VPC principal d'AlpinaShop - gestionada per IaC"

  - name: subred-web
    type: subred.jinja
    properties:
      nom: sn-web-euw1
      xarxaSelfLink: $(ref.alpinashop-vpc.selfLink)
      region: europe-west1
      rang: 10.10.0.0/24

  - name: subred-datos
    type: subred.jinja
    properties:
      nom: sn-datos-euw1
      xarxaSelfLink: $(ref.alpinashop-vpc.selfLink)
      region: europe-west1
      rang: 10.20.0.0/24

  - name: reglas-firewall
    type: firewall.py
    properties:
      xarxaSelfLink: $(ref.alpinashop-vpc.selfLink)
      entorn: prod
      cidrOficina: 192.0.2.0/24

  - name: alpinashop-router-euw1
    type: compute.v1.router
    properties:
      network: $(ref.alpinashop-vpc.selfLink)
      region: europe-west1

  - name: alpinashop-nat-euw1
    type: compute.v1.router
    properties:
      network: $(ref.alpinashop-vpc.selfLink)
      region: europe-west1
      nats:
        - name: alpinashop-nat-euw1
          natIpAllocateOption: AUTO_ONLY
          sourceSubnetworkIpRangesToNat: ALL_SUBNETWORKS_ALL_IP_RANGES

outputs:
  - name: redSelfLink
    value: $(ref.alpinashop-vpc.selfLink)
  - name: subredWeb
    value: $(ref.subred-web.selfLink)
gcloud deployment-manager deployments create alpinashop-red \
  --config=alpinashop-red.yaml --preview --project=alpinashop-prod

I aquí hi ha el punt de la lliçó: aquest fitxer, revisat en un pull request i aplicat des del pipeline, substitueix quinze comandes soltes a l'historial de la Marta. La xarxa passa a ser un artefacte que es llegeix, es discuteix i es reprodueix.

Però abans que ningú es posi a escriure'l, cal dir el següent.

  1. L'avís central: Deployment Manager està descontinuat

Cloud Deployment Manager està descontinuat. Google va anunciar-ne la retirada, no rep funcionalitat nova des de fa anys i el seu final de suport està fixat. No s'ha d'utilitzar per a cap projecte nou.

Tot el de l'apartat anterior és correcte i funciona avui. I seria un error començar a escriure'l.

Les quatre raons per les quals Deployment Manager no va prosperar, que són instructives per si mateixes:

Raó Detall
Només GCP Terraform gestiona GCP, AWS, Azure, GitHub, Cloudflare, Datadog… amb un mateix llenguatge
Ecosistema inexistent Terraform té milers de mòduls públics reutilitzables; Deployment Manager, gairebé cap
Cobertura de recursos incompleta Serveis nous trigaven a tenir tipus, o no en tenien mai
Adopció baixa La comunitat va triar Terraform, i amb ella els exemples, els llibres i les ofertes de feina

La tercera és la que més es patia a la pràctica: quan apareixia un servei nou, calia recórrer als tipus genèrics basats en l'API REST, amb una experiència força ingrata.

Aleshores, per què hi ha aquesta lliçó al curs? Per tres motius concrets:

  1. Te la trobaràs. Hi ha molta infraestructura desplegada amb Deployment Manager en organitzacions que porten anys a GCP, incloses plantilles del Marketplace. Saber llegir un .yaml i executar deployments describe és una habilitat pràctica.
  2. Els conceptes són transferibles. Declaratiu, dependències, plantilles, sortides, previsualització, estat: són els mateixos en qualsevol eina. Aprendre'ls aquí serveix per a 06-07.
  3. Perquè l'important és saber migrar. Si et trobes Deployment Manager, la teva feina serà treure'l d'aquí. Això és l'apartat 10, i és el veritablement útil d'aquesta lliçó.

I hi ha una lliçó de fons que transcendeix l'eina: triar tecnologia no és només triar capacitats, és triar un ecosistema. Deployment Manager era tècnicament raonable. Va perdre perquè la comunitat, els exemples, els mòduls, els llibres i els professionals formats eren a l'altre costat. En avaluar una eina, pregunta també quanta gent la fa servir i què passa si el proveïdor deixa d'invertir-hi.

  1. La successió: Infrastructure Manager, Config Connector i Terraform

Google no va deixar un buit: va proposar successors, i cadascun respon a un perfil diferent.

Infrastructure Manager (sovint abreujat Infra Manager) és el successor gestionat i oficial. I el que és interessant és què executa per dins: Terraform. Google va reconèixer que Terraform havia guanyat i, en lloc de competir-hi, va muntar un servei gestionat que l'executa per tu.

gcloud infra-manager deployments apply proyectos/alpinashop-prod/locations/europe-west1/deployments/red \
  --service-account=projects/alpinashop-prod/serviceAccounts/[email protected] \
  --local-source=./terraform/red \
  --input-values=entorno=prod

El que aporta sobre executar Terraform tu mateix: gestiona l'estat per tu —adeu al bucket i al bloqueig—, s'autentica amb un compte de servei de GCP sense claus, s'integra amb Cloud Build i amb els registres d'auditoria, i manté un historial de desplegaments consultable. El que costa: només GCP, i menys flexibilitat que executar Terraform al teu propi pipeline.

Config Connector és una proposta diferent: un complement de GKE que permet gestionar recursos de GCP com a objectes de Kubernetes.

apiVersion: compute.cnrm.cloud.google.com/v1beta1
kind: ComputeNetwork
metadata:
  name: alpinashop-vpc
  namespace: tienda
spec:
  autoCreateSubnetworks: false
  routingMode: REGIONAL

Apliques això amb kubectl apply i el controlador crea la VPC de veritat. L'avantatge és la reconciliació contínua: el controlador vigila permanentment i corregeix la deriva tot sol, sense esperar que ningú executi res. Té sentit per a equips que ja viuen a Kubernetes i usen GitOps; per a AlpinaShop, que té un clúster però no una cultura de GitOps, seria afegir una dependència gran per resoldre un problema que Terraform resol més simple.

Terraform és l'estàndard de facto, i per això té la seva pròpia lliçó.

Eina Model Estat Multiproveïdor Per a AlpinaShop?
Deployment Manager YAML + plantilles Gestionat No No: descontinuat
Infrastructure Manager Terraform gestionat Gestionat No Bona opció, s'esmenta a 06-07
Config Connector CRD de Kubernetes Al clúster No No: complexitat desproporcionada
Terraform HCL Teu Sí Sí: l'elecció

  1. Com es migra de Deployment Manager a Terraform, pas a pas

Aquest és l'apartat útil de la lliçó, i serveix per a dos escenaris alhora: migrar des de Deployment Manager i —el cas real d'AlpinaShop— portar a codi una infraestructura creada a mà. El procediment és pràcticament el mateix, perquè en tots dos casos l'objectiu és que Terraform prengui el control de recursos que ja existeixen sense destruir-los ni recrear-los.

flowchart TD
    A[1. Inventariar<br/>què existeix realment] --> B[2. Exportar la configuració<br/>bulk-export]
    B --> C[3. Revisar i netejar<br/>l'HCL generat]
    C --> D[4. Importar a l'estat<br/>terraform import]
    D --> E[5. Verificar:<br/>terraform plan BUIT]
    E --> F{Pla buit?}
    F -->|No| C
    F -->|Sí| G[6. Abandonar el desplegament<br/>de Deployment Manager]
    G --> H[7. Refactoritzar<br/>amb calma]

Pas 1: inventariar

No es pot importar el que no es coneix. I la font de veritat no és la memòria de ningú, ni un document: és GCP.

# Si hi ha desplegaments de Deployment Manager, llistar-ne els recursos
gcloud deployment-manager deployments list --project=alpinashop-prod
gcloud deployment-manager resources list --deployment=alpinashop-red \
  --project=alpinashop-prod --format='table(name, type, id)'

# I en qualsevol cas, inventariar la realitat recurs per recurs
gcloud compute networks list --project=alpinashop-prod
gcloud compute networks subnets list --project=alpinashop-prod
gcloud compute firewall-rules list --project=alpinashop-prod
gcloud compute forwarding-rules list --project=alpinashop-prod
gcloud sql instances list --project=alpinashop-prod
gcloud storage buckets list --project=alpinashop-prod

Una alternativa molt més completa és Cloud Asset Inventory, que enumera tot el que existeix en un projecte d'una sola vegada:

gcloud asset search-all-resources \
  --scope=projects/alpinashop-prod \
  --format='table(assetType, displayName, name)' > inventario-prod.txt

El resultat d'aquest pas és una llista escrita de què hi ha. I sol deparar sorpreses: recursos de proves que ningú no va esborrar, una IP estàtica reservada i sense usar que s'està pagant, regles de tallafoc duplicades. Aquesta troballa ja justifica l'exercici, fins i tot abans d'escriure una línia de Terraform.

Pas 2: exportar la configuració actual

L'eina que estalvia la major part de la feina:

# Exportar TOTS els recursos suportats del projecte a fitxers .tf
gcloud beta resource-config bulk-export \
  --project=alpinashop-prod \
  --resource-format=terraform \
  --path=./terraform-exportado

# O acotat a un tipus concret, que és més manejable
gcloud beta resource-config bulk-export \
  --project=alpinashop-prod \
  --resource-format=terraform \
  --resource-types=ComputeNetwork,ComputeSubnetwork,ComputeFirewall \
  --path=./terraform-exportado/red

Genera fitxers .tf amb la configuració real dels recursos existents. No és codi llest per a producció, i cal assumir-ho des del principi: noms lletjos i generats automàticament, tots els valors literals sense variables, camps calculats pel servidor que no hi haurien de ser, sense mòduls i sense estructura. És un punt de partida, i com a punt de partida estalvia dies.

També existeix l'exportació a format Deployment Manager (--resource-format=krm per a Config Connector), però per al nostre destí volem terraform.

Pas 3: revisar i netejar

La feina manual, i no hi ha drecera. El que cal fer amb l'exportat:

Tasca Per què
Reanomenar els recursos google_compute_network.tfer--alpinashop-vpc → red_principal
Treure els camps calculats self_link, id, creation_timestamp, fingerprint: els posa GCP
Substituir literals per referències network = "https://..." → network = google_compute_network.red_principal.id
Extreure variables El projecte, la regió i els CIDR han de ser variables
Organitzar en fitxers red.tf, firewall.tf, sql.tf, iam.tf
Afegir comentaris Per què existeix cada regla: això no ho exporta cap eina
Fixar la versió del proveïdor Reproductibilitat

La tercera fila és la més important tècnicament. Un fitxer exportat té valors literals que no expressen relacions; substituir-los per referències és el que fa que Terraform entengui l'ordre de creació i que el codi sigui reutilitzable.

I la sisena és la més important en el pla humà. L'exportació reprodueix què hi ha, mai per què. La regla fw-permitir-salud amb els rangs 35.191.0.0/16 i 130.211.0.0/22 és incomprensible sense un comentari que digui que són les sondes de comprovació d'estat de Google. Aquest moment de la migració és l'única ocasió en què algú mirarà cada recurs un per un; és quan cal escriure aquests comentaris, perquè després no es farà.

Pas 4: importar a l'estat

Terraform té el codi, però el seu estat és buit: creu que no gestiona res. Si apliquessis ara, intentaria crear-ho tot de nou i fallaria amb errors de «ja existeix» —o pitjor, crearia duplicats—.

Importar associa cada recurs real amb el seu bloc de codi. La forma clàssica, recurs a recurs:

terraform import google_compute_network.red_principal \
  projects/alpinashop-prod/global/networks/alpinashop-vpc

terraform import google_compute_subnetwork.web \
  projects/alpinashop-prod/regions/europe-west1/subnetworks/sn-web-euw1

terraform import google_compute_firewall.permitir_salud \
  projects/alpinashop-prod/global/firewalls/fw-permitir-salud

I la forma moderna, disponible des de Terraform 1.5 i clarament preferible, amb blocs import declaratius:

# importaciones.tf — un fitxer temporal que s'esborra en acabar
import {
  to = google_compute_network.red_principal
  id = "projects/alpinashop-prod/global/networks/alpinashop-vpc"
}

import {
  to = google_compute_subnetwork.web
  id = "projects/alpinashop-prod/regions/europe-west1/subnetworks/sn-web-euw1"
}

import {
  to = google_compute_firewall.permitir_salud
  id = "projects/alpinashop-prod/global/firewalls/fw-permitir-salud"
}

L'avantatge dels blocs import és enorme per a una migració gran: són codi versionable i revisable, apareixen a terraform plan abans d'executar-se, i no depenen que algú recordi l'ordre de cinquanta comandes. A més, terraform plan -generate-config-out=generado.tf pot generar l'HCL corresponent als recursos importats, la qual cosa redueix encara més la feina del pas 3.

El format de l'identificador varia per tipus de recurs i està documentat al final de la pàgina de cada recurs a la documentació del proveïdor. És el detall més tediós de tot el procediment.

Pas 5: verificar que el pla surt buit

Aquest és el pas que valida tota la migració, i és el criteri d'èxit:

terraform plan
No changes. Your infrastructure matches the configuration.

Un pla buit significa que el codi descriu exactament la realitat, que l'estat la reflecteix i que Terraform ha pres el control sense canviar res. És l'objectiu.

Si el pla no surt buit, llegeix-lo amb atenció perquè cada tipus de diferència significa una cosa diferent:

El que mostra el pla Causa habitual Què fer
~ update d'un camp trivial Un valor per defecte que no vas escriure Afegir-lo al codi amb el valor real
~ update d'un camp calculat Vas copiar self_link o fingerprint Treure'l del codi
-/+ replace Un camp immutable no coincideix PARAR: aplicar-ho destruiria el recurs
+ create d'una cosa que existeix Falta importar-la Importar-la
- destroy d'una cosa que existeix És a l'estat però no al codi Afegir-la al codi

La tercera fila mereix un advertiment en majúscules. Un -/+ replace sobre google_sql_database_instance destruiria la base de dades de comandes d'AlpinaShop. Mai no s'aplica un pla de migració que contingui un reemplaçament sense haver entès exactament per què apareix. Gairebé sempre és un camp immutable mal transcrit i es corregeix al codi.

La recomanació operativa: fes tota la migració primer a alpinashop-dev. Si alguna cosa surt malament, es perd un entorn de proves, no la botiga.

Pas 6: abandonar el desplegament antic

Quan es venia de Deployment Manager, queda un detall crític. Ara hi ha dues eines que creuen gestionar els mateixos recursos, i això és perillós: un deployments delete els esborraria per sota de Terraform.

# ABANDON deixa de gestionar-los SENSE ESBORRAR-LOS. No usis mai delete aquí.
gcloud deployment-manager deployments delete alpinashop-red \
  --delete-policy=ABANDON \
  --project=alpinashop-prod

--delete-policy=ABANDON és la diferència entre una migració neta i un desastre. Sense aquest paràmetre, la comanda destrueix la infraestructura que acabes d'importar.

Pas 7: refactoritzar amb calma

Només ara, amb el pla buit i el control a Terraform, comença la millora: extreure mòduls, parametritzar entorns, afegir prevent_destroy al que és crític, integrar-ho al pipeline. I la regla d'or: cada canvi de refactorització ha d'acabar també amb un pla buit. Si en moure codi a un mòdul el pla proposa destruir i recrear alguna cosa, has canviat el significat, no la forma.

Un resum de l'esforç real, perquè ningú no s'endugui una sorpresa:

Fase Esforç Es pot automatitzar
Inventariar Hores Bastant
Exportar Minuts Sí
Netejar i comentar Dies Poc
Importar Hores Sí, amb blocs import
Verificar el pla buit Dies d'iteració No
Refactoritzar Continu No

És una feina tediosa. I és d'una sola vegada: quan està feta, està feta per sempre.

  1. Els conceptes que es conserven entre eines

Tanco amb el que fa que aprendre Deployment Manager no sigui temps perdut. Els conceptes són els mateixos en totes les eines d'IaC, i només canvia la sintaxi:

Concepte Deployment Manager Terraform Config Connector
Unitat declarativa Recurs en YAML Bloc resource Objecte CRD
Referència entre recursos $(ref.x.selfLink) google_x.y.id Ref de Kubernetes
Dependència implícita Per la referència Per la referència Per la referència
Dependència explícita metadata.dependsOn depends_on Anotacions
Parametrització Propietats de plantilla variable Kustomize / Helm
Reutilització Plantilles Jinja/Python Mòduls Charts
Valors de sortida outputs output Estat de l'objecte
Previsualització --preview plan --dry-run
Estat Gestionat per Google Fitxer teu Al clúster (etcd)
Validació .schema validation en variables Esquema del CRD
Entorns Desplegaments diferents Workspaces o carpetes Namespaces

Els quatre principis que valen en totes elles:

  1. Descriu el resultat, no els passos. L'eina calcula el camí.
  2. Deixa que les dependències s'infereixin de les referències. Declarar l'ordre a mà és font d'errors; depends_on és l'últim recurs.
  3. Previsualitza sempre abans d'aplicar. --preview o plan, sense excepcions en producció.
  4. El codi és la font de veritat. Tan bon punt algú toca alguna cosa a mà, el sistema deixa de ser fiable i tornes al punt de partida.

Errors Habituals i Consells

Començar un projecte nou amb Deployment Manager. Està descontinuat. Tot el d'aquesta lliçó serveix per entendre i migrar el que ja existeix, no per escriure res nou.

Executar deployments delete sense --delete-policy=ABANDON durant una migració. Destrueix la infraestructura en lloc de deixar de gestionar-la. És l'error més car possible en aquest procediment.

Aplicar un pla de migració amb un -/+ replace sense entendre'l. Un reemplaçament sobre Cloud SQL destrueix la base de dades. Si el pla proposa recrear alguna cosa, para i esbrina quin camp immutable no coincideix.

Donar per bo el codi exportat per bulk-export. És un punt de partida, no un resultat. Sense netejar, tindràs camps calculats que provoquen diferències eternes i literals que impedeixen reutilitzar el codi.

No comentar per què existeix cada recurs durant la migració. És l'única vegada que algú mirarà cada recurs individualment. Si no s'escriu el motiu llavors, es perd per sempre.

Continuar tocant coses a mà després d'adoptar IaC. És el pitjor de tots dos mons. Tan bon punt el codi i la realitat divergeixen, la confiança en l'eina desapareix.

Migrar directament en producció. Fes tot el procediment primer a alpinashop-dev. Els errors d'una migració es paguen cars i allà no costen res.

Esborrar recursos del fitxer pensant que «deixaran de gestionar-se». En una eina declarativa, treure un recurs del codi significa destruir-lo. Per deixar de gestionar-lo sense esborrar-lo existeix terraform state rm o la política ABANDON.

Importar sense verificar el pla buit. Importar no valida que el codi sigui correcte: només associa un identificador. El pla buit és l'única prova que la migració està ben feta.

Consell final: comença pel que és menys perillós. Migra primer les regles de tallafoc i els buckets, després la xarxa, i deixa per al final Cloud SQL i tot el que contingui dades. Quan arribis al que és delicat tindràs el procediment dominat i sabràs llegir un pla amb soltesa.

Exercicis

Exercici 1: llegir i traduir una configuració heretada

T'incorpores a un projecte i trobes un desplegament de Deployment Manager anomenat plataforma-legacy amb un fitxer que defineix una VPC, dues subxarxes, una regla de tallafoc que permet tcp:22 des de 0.0.0.0/0 i una instància de Cloud SQL. Descriu quines comandes executaries per entendre què gestiona aquest desplegament, què faries amb la regla de tallafoc i en quin ordre migraries els quatre tipus de recurs a Terraform, justificant l'ordre.

Exercici 2: diagnosticar un pla que no surt buit

Durant la migració d'AlpinaShop, després d'importar la xarxa i el tallafoc, terraform plan mostra: un ~ update sobre google_compute_network.red_principal que canvia description de "VPC principal" a ""; un ~ update sobre google_compute_subnetwork.web que canvia private_ip_google_access de true a false; i un -/+ replace sobre google_compute_subnetwork.datos perquè ip_cidr_range passaria de 10.20.0.0/24 a 10.20.0.0/22. Explica la causa de cadascun, quin és més perillós i com corregir-los.

Exercici 3: planificar la migració completa d'AlpinaShop

La Marta et demana un pla realista per portar a Terraform tota la infraestructura d'alpinashop-prod: VPC amb dues subxarxes i Cloud NAT, unes vuit regles de tallafoc, el balancejador global complet, la política de Cloud Armor, la zona de Cloud DNS amb el certificat, el MIG amb la seva plantilla, el clúster de GKE Autopilot, la instància de Cloud SQL, tres buckets, quatre comptes de servei amb les seves vinculacions IAM i un rol personalitzat. Proposa un pla per fases amb criteris d'agrupació, indica quins recursos NO importaries i per què, i defineix el criteri de finalització de cada fase.

Solucions

Solució 1

Comandes per entendre el desplegament:

# 1. Quins recursos gestiona, amb els seus tipus i identificadors
gcloud deployment-manager resources list --deployment=plataforma-legacy \
  --format='table(name, type, id, update.state)'

# 2. El manifest: la configuració expandida REAL que es va aplicar
gcloud deployment-manager manifests list --deployment=plataforma-legacy
gcloud deployment-manager manifests describe MANIFEST_ID \
  --deployment=plataforma-legacy --format='value(expandedConfig)'

# 3. Qui i quan ho va canviar per última vegada
gcloud deployment-manager deployments describe plataforma-legacy

El manifest és la peça clau i la que la gent no coneix: conté la configuració expandida, és a dir, amb totes les plantilles resoltes i tots els valors per defecte emplenats. El .yaml original pot tenir plantilles parametritzades difícils de llegir; el manifest mostra exactament què es va crear.

La regla de tallafoc tcp:22 des de 0.0.0.0/0 és una troballa de seguretat, i cal tractar-la com a tal. Deixa SSH obert a tot internet, contra tot el que s'estableix a 03-01 i 03-04.

I la decisió correcta és migrar-la tal com està, i arreglar-la després, encara que faci mal. Les raons:

  • Canviar-la durant la migració trenca el criteri del pla buit, que és l'única manera de verificar que la migració és correcta. Si barreges migració i correcció, quan alguna cosa falli no sabràs quina de les dues coses ho ha causat.
  • Pot ser que alguna cosa en depengui —un procés operatiu, un accés d'un proveïdor—, i esbrinar-ho requereix una investigació que no ha de bloquejar la migració.
  • Un cop a Terraform, corregir-la és un pull request revisable, amb història i amb marxa enrere. És a dir, es corregeix millor després.

El que sí que cal fer immediatament: documentar la troballa, comunicar-la i posar-hi data. I si l'exposició es considera inacceptable a curt termini, restringir l'origen als rangs de l'oficina com a mesura provisional, abans de començar la migració, perquè la migració parteixi d'un estat ja acceptable.

Ordre de migració, de menys a més perillós:

Ordre Recurs Per què aquí
1 Regles de tallafoc Independents, fàcils d'importar, un error no destrueix dades
2 VPC Base de tot; cal tenir-la abans que les subxarxes
3 Subxarxes Depenen de la VPC; compte amb ip_cidr_range, és immutable
4 Cloud SQL L'última sempre: conté dades i un replace és irreversible

El criteri general: comença pel que es pot recrear sense conseqüències i acaba pel que conté dades. Quan arribis a Cloud SQL hauràs importat diversos recursos, sabràs llegir un pla amb soltesa i reconeixeràs un -/+ replace a l'instant. I per a aquesta importació en concret, afegeix lifecycle { prevent_destroy = true } abans d'executar terraform apply per primera vegada: és una xarxa de seguretat de dues línies que pot salvar la base de dades.

Solució 2

Diferència 1 — description passaria de "VPC principal" a "".

Causa: el recurs real té descripció, però el codi HCL no inclou l'atribut description. Terraform interpreta l'absència com «ha d'estar buit» i intenta esborrar-la.

Gravetat: baixa. Canviar una descripció no afecta el funcionament.

Correcció: afegir l'atribut al codi amb el valor real.

resource "google_compute_network" "red_principal" {
  name        = "alpinashop-vpc"
  description = "VPC principal d'AlpinaShop"   # faltava
  auto_create_subnetworks = false
}

Lliçó: és el símptoma més comú després d'importar. Apareix sempre que un recurs té atributs opcionals configurats que el codi no esmenta.

Diferència 2 — private_ip_google_access passaria de true a false.

Causa: la mateixa —l'atribut falta al codi— però les conseqüències són completament diferents. Aquest ajust és el que permet que les instàncies sense IP pública arribin a les APIs de Google. Aplicar-ho deixaria les VM d'sn-web-euw1 sense accés a Cloud Storage, a Secret Manager ni a Cloud Logging.

Gravetat: alta. És una interrupció funcional real, i a més difícil de diagnosticar: no cau res de cop, simplement comencen a fallar crides a APIs de manera aparentment aleatòria.

Correcció:

resource "google_compute_subnetwork" "web" {
  name                     = "sn-web-euw1"
  ip_cidr_range            = "10.10.0.0/24"
  region                   = "europe-west1"
  network                  = google_compute_network.red_principal.id
  private_ip_google_access = true      # CRÍTIC: faltava
}

Lliçó important: un ~ update no és automàticament inofensiu. Dues diferències sintàcticament idèntiques —un atribut absent— tenen impactes radicalment diferents. Cal llegir quin camp canvia, no només el símbol que el precedeix.

Diferència 3 — -/+ replace de la subxarxa de dades per canvi de CIDR.

Causa: el codi diu /22 i la realitat és /24. És un error de transcripció, molt probablement en copiar de l'inventari o en escriure de memòria. I ip_cidr_range no es pot modificar en calent en una subxarxa existent amb recursos a dins, així que Terraform només pot destruir-la i crear-la de nou.

Gravetat: crítica. Destruir sn-datos-euw1 implicaria desconnectar tot el que hi viu —la instància de Cloud SQL entre altres coses— i l'operació fallaria a mitges, deixant la infraestructura en un estat incoherent. I si per algun motiu aconseguís completar-se, les IP privades canviarien i tot el que les referencia deixaria de funcionar.

Correcció: posar al codi el valor real, 10.20.0.0/24.

Quin és més perillós i per què. El -/+ replace és el més perillós, i no només per l'impacte: és l'únic que Terraform no pot desfer. Els dos ~ update són reversibles —es corregeix el codi i es torna a aplicar—; un recurs destruït no torna. Per això la regla de l'apartat 10 és categòrica: un replace inesperat en una migració ha d'aturar-te sempre.

I una recomanació de procediment que aquest exercici il·lustra bé: en una migració, executa terraform plan després de cada importació, no al final de totes. Amb cinquanta recursos importats de cop, el pla té centenars de línies i les tres diferències importants es perden entre el soroll. Importar de tres en tres i verificar és més lent i moltíssim més segur.

Solució 3

Criteri d'agrupació per fases: de menys a més perillós, i respectant les dependències.

Fase 0 — Preparació (mig dia). Bucket alpinashop-terraform-estado amb versionatge, backend configurat, proveïdor google amb versió fixada, inventari complet amb Cloud Asset Inventory i exportació amb bulk-export. Repositori alpinashop-infra de 06-02 amb protecció de branques i CODEOWNERS exigint revisió de seguretat.

Criteri de finalització: terraform init funciona i l'estat remot és buit però accessible.

Fase 1 — Recursos independents i sense dades (1-2 dies). Buckets —tret del seu contingut—, comptes de servei, rol personalitzat analistaCatalogo i vinculacions IAM.

Per què primer: no depenen de res, són fàcils d'importar i un error no destrueix res irrecuperable. És on l'equip aprèn a llegir plans.

Criteri: pla buit i una prova que els comptes de servei continuen funcionant.

Fase 2 — Xarxa base (2-3 dies). VPC, dues subxarxes, router, Cloud NAT alpinashop-nat-euw1 i les vuit regles de tallafoc.

Per què aquí: és la base de tot el que ve després, i encara no toca dades. Màxima atenció a ip_cidr_range i a private_ip_google_access, pel que s'ha vist a l'exercici 2.

Criteri: pla buit i verificació funcional real: la botiga continua responent, les VM continuen sortint pel NAT i continuen arribant a les APIs de Google.

Fase 3 — Publicació (2-3 dies). Balancejador complet —IP alpinashop-lb-ip, hc-catalogo, bs-catalogo-web, bb-catalogo-imagenes, alpinashop-url-map, proxy i regla de reenviament—, política de Cloud Armor pol-catalogo-web, zona de Cloud DNS alpinashop-publica i certificat alpinashop-cert.

Per què juntes: estan fortament acoblades i separar-les deixaria estats intermedis estranys. És la fase amb més recursos interdependents i on l'ordre d'importació importa més.

Criteri: pla buit, la botiga respon per HTTPS amb el certificat correcte i la CDN continua servint encerts.

Fase 4 — Còmput (2 dies). Plantilla d'instància, MIG alpinashop-web-mig i clúster GKE Autopilot alpinashop-cluster.

Precaució específica: les plantilles d'instància són immutables per disseny; qualsevol diferència produeix un replace, i allà un replace és acceptable sempre que el MIG faci una actualització progressiva i no una recreació simultània. Cal verificar-ho al pla abans d'aplicar.

Criteri: pla buit i comprovació que el MIG no ha recreat instàncies inesperadament.

Fase 5 — Dades (2 dies, amb màxima cautela). Instància de Cloud SQL alpinashop-pedidos i la seva base de dades tienda.

Precaucions obligatòries: còpia de seguretat verificada abans de començar; lifecycle { prevent_destroy = true } escrit abans del primer apply; i aplicació en una finestra de manteniment amb algú mirant.

Criteri: pla buit i l'aplicació connectant amb normalitat.

Recurs Importar? Motiu
Contingut dels buckets No Terraform gestiona el contenidor, no les dades
Files i esquema de Cloud SQL No Les migracions d'esquema són de l'aplicació (06-01)
Valors de Secret Manager No El secret sí, el seu valor mai: acabaria a l'estat
Datasets i taules de BigQuery Depèn El dataset sí; les taules creades per pipelines, no
Objectes de Kubernetes del namespace tienda No Van a alpinashop-catalogo amb els seus manifests
Instàncies individuals del MIG No Les gestiona el MIG, no Terraform
Certificats gestionats per Google Sí, el recurs La renovació la fa Google

La regla que unifica la columna d'exclusions: Terraform gestiona la forma, no el contingut. El bucket sí, els objectes no. La base de dades sí, les files no. El secret sí, el seu valor mai —perquè qualsevol valor que Terraform gestioni acaba escrit al fitxer d'estat, i això convertiria l'estat en un magatzem de credencials, contradient tot el de 03-06—.

Estimació total: entre dues i tres setmanes de feina no contínua, compaginada amb l'operació normal. I les tres recomanacions finals:

  • Tot primer a alpinashop-dev. El cost d'un error allà és zero, i la fase 5 en particular no s'hauria de tocar en producció sense haver-la assajat.
  • Una fase per pull request, amb el terraform plan enganxat a la descripció. És el que converteix la migració en una feina revisable i no en una operació heroica d'una persona.
  • Cada fase acaba amb pla buit i verificació funcional, no només amb pla buit. Un pla buit diu que el codi coincideix amb l'estat; que la botiga funcioni ho diu la botiga.

Conclusió

AlpinaShop té ara un pla per deixar de dependre de l'historial d'un terminal.

Saps quin era el problema concret i quant costava: infraestructura irreproduïble, canvis sense revisar, alpinashop-dev derivant d'alpinashop-prod fins que provar va deixar de significar res, i cap resposta a la pregunta de quina configuració hi havia abans del canvi que va trencar alguna cosa.

Saps què és la infraestructura com a codi i per què el seu valor no està a escriure fitxers sinó a no tornar a tocar res a mà. Entens la diferència entre declaratiu i imperatiu i la seva conseqüència pràctica: la idempotència, que permet aplicar la configuració tantes vegades com vulguis, i la detecció de deriva, que corregeix el que algú va canviar pel seu compte. Amb el perill associat: en una eina declarativa, esborrar un recurs del fitxer significa destruir-lo.

Comprens què és l'estat i per què és imprescindible —saber què es gestiona, amb quin identificador i com estava—, i la diferència fonamental entre les dues eines: Deployment Manager el gestiona per tu, Terraform te'l lliura amb tota la responsabilitat que això implica.

Coneixes Deployment Manager de veritat: configuracions YAML amb tipus derivats de les APIs, $(ref....) creant dependències implícites, plantilles en Jinja per al que és simple i en Python quan cal lògica, esquemes de validació, el cicle create --preview / update / delete, i les polítiques ABANDON i CREATE_OR_ACQUIRE. Saps escriure la xarxa completa d'AlpinaShop amb això.

I saps que no l'has d'utilitzar. Està descontinuat, va perdre per ser només de GCP, per no tenir ecosistema, per la cobertura incompleta de recursos i perquè la comunitat va triar una altra cosa. Amb la lliçó de fons que va més enllà de l'eina: triar tecnologia és triar un ecosistema, i una eina tècnicament correcta sense comunitat al darrere és una aposta perduda.

Coneixes la successió: Infrastructure Manager, que és Terraform gestionat per Google —el reconeixement explícit de qui va guanyar—; Config Connector, amb la seva reconciliació contínua, per a qui ja viu a Kubernetes; i Terraform com a estàndard de facto.

I tens el veritablement útil d'aquesta lliçó: el procediment de migració complet, que serveix tant per sortir de Deployment Manager com per portar a codi una infraestructura creada a mà. Inventariar amb Cloud Asset Inventory, exportar amb gcloud beta resource-config bulk-export, netejar l'HCL generat —traient camps calculats, substituint literals per referències i, sobretot, escrivint per què existeix cada recurs, perquè és l'única vegada que algú els mirarà un a un—, importar amb terraform import o amb els blocs import declaratius, i verificar que el pla surt buit, que és l'únic criteri vàlid d'èxit. Amb la taula per diagnosticar un pla que no surt buit i la regla categòrica: un -/+ replace inesperat ha d'aturar-te sempre. I el --delete-policy=ABANDON que separa una migració neta d'un desastre.

Finalment, tens els conceptes que es conserven entre eines —recursos, referències, dependències, parametrització, reutilització, sortides, previsualització, estat— i els quatre principis que valen en qualsevol d'elles: descriu el resultat, deixa que les dependències s'infereixin, previsualitza sempre i tracta el codi com l'única font de veritat.

Amb això, AlpinaShop sap què vol fer i com arribar-hi. Li falta l'eina amb què fer-ho.

Abans d'això, però, queda pendent la resta de l'observabilitat. Les mètriques de 06-04 avisen que passa alguna cosa, però no diuen què. A 06-06 arriben Cloud Logging i Cloud Trace: els registres que responen què va passar exactament en cada cas, les traces que diuen on se'n va anar el temps, i el recorregut complet d'un incident d'AlpinaShop des de l'alerta fins a la línia de codi. Després, a 06-07, Terraform tanca el mòdul posant en pràctica tot el que aquí has après a planificar.

Curs de Google Cloud Platform (GCP)

Mòdul 1: Introducció a Google Cloud Platform

Mòdul 2: Serveis principals de GCP

Mòdul 3: Xarxes i seguretat

Mòdul 4: Dades i anàlisi

Mòdul 5: Aprenentatge automàtic i IA

Mòdul 6: DevOps i monitoratge

Mòdul 7: Temes avançats de GCP

Mòdul 8: Projecte final

© Copyright 2026. Tots els drets reservats