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
- El problema concret: infraestructura que només existeix en un historial
- Què és la infraestructura com a codi
- Declaratiu davant d'imperatiu, i idempotència
- L'estat: la idea que fa possible tota la resta
- Deployment Manager: l'eina nativa de GCP
- Plantilles en Jinja i en Python
- Un exemple real: la VPC i el tallafoc d'AlpinaShop
- L'avís central: Deployment Manager està descontinuat
- La successió: Infrastructure Manager, Config Connector i Terraform
- Com es migra de Deployment Manager a Terraform, pas a pas
- Els conceptes que es conserven entre eines
- 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.
- 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.
- 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/22Declaratiu és descriure el resultat desitjat, i deixar que l'eina calculi els passos:
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.
- 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.
- 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: trueLa 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-devDos advertiments operatius que convé tenir presents:
--previewés equivalent alplande 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 deleteesborra 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-devABANDON 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.
- 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/24Plantilla 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.
- 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-prodI 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.
- 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:
- 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
.yamli executardeployments describeés una habilitat pràctica. - 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.
- 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.
- 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=prodEl 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: REGIONALApliques 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ó |
- 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-prodUna 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.txtEl 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/redGenera 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-saludI 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:
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.
- 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:
- Descriu el resultat, no els passos. L'eina calcula el camí.
- 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. - Previsualitza sempre abans d'aplicar.
--previewoplan, sense excepcions en producció. - 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-legacyEl 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 planenganxat 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
- Què és Google Cloud Platform?
- Configuració del teu compte de GCP
- Descripció general de la consola de GCP
- Projectes, jerarquia de recursos i facturació
- Regions, zones i model de responsabilitat compartida
- Cloud Shell i la CLI de gcloud
Mòdul 2: Serveis principals de GCP
- Compute Engine: màquines virtuals a Google Cloud
- Cloud Storage: emmagatzematge d'objectes
- Cloud SQL: bases de dades relacionals gestionades
- App Engine: plataforma com a servei
- Google Kubernetes Engine (GKE)
- Bases de dades NoSQL: Firestore, Bigtable i Spanner
- Com triar el servei de còmput adequat
Mòdul 3: Xarxes i seguretat
- Xarxes VPC
- Balanceig de càrrega al núvol
- Cloud CDN
- Gestió d'identitat i accés (IAM)
- Cloud Armor
- Secrets i xifratge: Secret Manager i Cloud KMS
- Cloud DNS, certificats TLS i publicació segura de serveis
Mòdul 4: Dades i anàlisi
- BigQuery: el magatzem de dades analític
- Cloud Dataflow: processament de dades per lots i en temps real
- Cloud Dataproc: Spark i Hadoop gestionats
- Cloud Pub/Sub: missatgeria asíncrona
- Cloud Data Fusion: integració de dades sense codi
- Orquestració de pipelines amb Cloud Composer i Workflows
- Govern de les dades i taulers amb Dataplex i Looker Studio
Mòdul 5: Aprenentatge automàtic i IA
- Vertex AI: la plataforma d'aprenentatge automàtic de GCP
- AutoML: models a mida sense escriure codi
- TensorFlow a GCP: entrenament i servei de models
- API de llenguatge natural
- API de visió
- IA generativa a Vertex AI: models Gemini i incrustacions
- MLOps: del model al producte amb Vertex AI Pipelines
Mòdul 6: DevOps i monitoratge
- Cloud Build: integració contínua a GCP
- Cloud Source Repositories i gestió del codi font
- Cloud Functions: funcions sense servidor
- Cloud Monitoring (abans Stackdriver): mètriques, taulers i alertes
- Cloud Deployment Manager i infraestructura com a codi nativa
- Cloud Logging i Cloud Trace: registres, traces i diagnòstic
- Terraform a GCP: infraestructura com a codi a la pràctica
Mòdul 7: Temes avançats de GCP
- Híbrid i multinúvol amb Anthos
- Computació sense servidor amb Cloud Run
- Xarxes avançades: VPC compartida, aparellament i connectivitat híbrida
- Bones pràctiques de seguretat
- Gestió i optimització de costos
- Fiabilitat: SLO, alta disponibilitat i recuperació de desastres
- Govern a escala: organització, polítiques i auditoria
