A mercadofresco-artefactos hi ha un ZIP verificat: ha passat 214 proves, té el seu commit a les metadades i porta la versió al nom. I per portar-lo a producció, el Luis continua fent el de sempre: ssh a la primera instància de l'ASG, scp del ZIP, descomprimir, systemctl restart, mirar el web, repetir a la segona. Quaranta segons per instància servint errors, dues versions convivint mentre dura, i si alguna cosa va malament, buscar el ZIP anterior i repetir el ritual amb la botiga caiguda.

AWS CodeDeploy converteix aquest ritual en una operació governada. Sap treure una instància del grup de destinació abans de tocar-la, executar els teus scripts en un ordre definit, comprovar que l'aplicació respon abans de tornar-li trànsit, avançar a poc a poc per la flota i —el que de debò importa— tornar enrere sola quan una alarma de CloudWatch salta durant el desplegament. És la lliçó que tanca el quart problema del curs: els desplegaments arriscats.

Avís de cost. CodeDeploy és gratuït per a EC2, Lambda i ECS; només cobra 0,02 USD per actualització d'instància en servidors locals. El que costa és el del voltant: en blue/green dupliques temporalment les instàncies de l'ASG —uns 0,09 USD per desplegament de 30 minuts amb dos t3.medium— i les versions de Lambda no caduquen soles. Al final tens la neteja. Dades fictícies.

Contingut

  1. Què resol CodeDeploy i què no
  2. Les tres destinacions i les estratègies que admet cadascuna
  3. Conceptes: aplicació, grup de desplegament, revisió i configuració
  4. L'agent a les instàncies de l'ASG
  5. L'appspec.yml per a EC2 i els ganxos del cicle de vida
  6. Els scripts reals de MercadoFresco
  7. Desplegament al lloc: AllAtOnce, HalfAtATime i OneAtATime
  8. Blue/green amb l'ASG i els grups de destinació
  9. L'appspec de Lambda i d'ECS
  10. Canari i lineal: desplegar mercadofresco-cobrar-pago
  11. Reversió automàtica: la peça que resol el problema 4
  12. Comparació amb la reversió manual i amb Route 53 ponderat
  13. Migracions d'esquema: expansió i contracció
  14. Observabilitat del desplegament i diagnòstic d'una fallada
  15. Cost i neteja
  16. Errors habituals i consells
  17. Exercicis
  18. Conclusió

Què resol CodeDeploy i què no

CodeDeploy no construeix, no decideix quan s'ha de desplegar i no defineix infraestructura. Fa una cosa: agafa una revisió —un ZIP a S3 o una imatge— i la instal·la en un conjunt de destinacions seguint un pla, amb ganxos on poses els teus scripts i amb condicions d'aturada.

Problema del desplegament manual Què aporta CodeDeploy
La instància serveix errors mentre s'actualitza La treu del grup de destinació abans de tocar-la
Dues versions convivint sense control Controla quantes instàncies hi ha a cada versió
«S'ha reiniciat bé el servei?» ValidateService ho comprova i falla si no
Tornar enrere és repetir el ritual a mà Reversió automàtica en minuts
Ningú no sap què es va desplegar ni quan Històric amb revisió, autor i resultat
El desplegament és igual en dev que en prod Grups de desplegament amb configuració diferent

I el que no aporta: no coordina l'ordre entre serveis diferents —per a això hi ha el pipeline de 08-04—, no migra la teva base de dades i no compensa una aplicació que no pot conviure amb ella mateixa en dues versions. Aquesta última limitació és el tema de la secció sobre migracions d'esquema.

Les tres destinacions i les estratègies que admet cadascuna

Destinació Al lloc Blue/green Canari Lineal Agent
EC2 / ASG No No
Servidors locals No No No
AWS Lambda No Sí (per àlies) No
Amazon ECS No No

Tres observacions que eviten confusions freqüents. A EC2 no hi ha canari ni lineal: el desplaçament percentual és cosa de Lambda i d'ECS, on el trànsit es reparteix per pes d'àlies o de grup de destinació; a EC2 el més semblant és OneAtATime, que és granularitat d'instància, no de percentatge de peticions. A Lambda i ECS no hi ha desplegament al lloc: sempre es crea la versió nova al costat de la vella i es desplaça trànsit, que és més segur per construcció. I l'agent només cal a EC2 i als servidors locals; a Lambda i ECS, CodeDeploy parla amb l'API del servei.

Conceptes: aplicació, grup de desplegament, revisió i configuració

Quatre objectes, i confondre'ls causa la meitat dels dubtes inicials:

Objecte Què és A MercadoFresco
Aplicació Contenidor lògic: nom i plataforma app-mercadofresco-tienda, app-mercadofresco-cobrar-pago
Grup de desplegament On i com: destinacions, estratègia, alarmes, reversió dg-mercadofresco-tienda-desarrollo / -produccion
Revisió Què es desplega: el ZIP amb el seu appspec.yml s3://mercadofresco-artefactos/tienda/1.5.0-a3f9c21/
Configuració de desplegament El ritme i quant ha de continuar sa CodeDeployDefault.HalfAtATime, o una de pròpia

L'important és el grup de desplegament: la mateixa aplicació i la mateixa revisió es comporten de manera molt diferent segons el grup. En desenvolupament, AllAtOnce sense alarmes perquè sigui ràpid; en producció, blue/green amb alarmes i reversió automàtica. Aquest és el mecanisme amb què se separen els entorns.

aws deploy create-application --application-name app-mercadofresco-tienda \
  --compute-platform Server --profile mercadofresco-dev --region eu-west-1

aws deploy create-deployment-group \
  --application-name app-mercadofresco-tienda \
  --deployment-group-name dg-mercadofresco-tienda-produccion \
  --service-role-arn arn:aws:iam::111122223333:role/rol-codedeploy-mercadofresco \
  --auto-scaling-groups asg-mercadofresco-tienda \
  --deployment-config-name CodeDeployDefault.HalfAtATime \
  --load-balancer-info '{"targetGroupInfoList":[{"name":"tg-mercadofresco-tienda"}]}' \
  --alarm-configuration '{"enabled": true, "ignorePollAlarmFailure": false,
    "alarms": [{"name":"mercadofresco-alb-latencia-alta"},
               {"name":"mercadofresco-pedidos-fallidos"}]}' \
  --auto-rollback-configuration '{"enabled": true,
    "events": ["DEPLOYMENT_FAILURE", "DEPLOYMENT_STOP_ON_ALARM"]}' \
  --profile mercadofresco-dev --region eu-west-1

Fixa't en ignorePollAlarmFailure: false: si CodeDeploy no aconsegueix consultar una alarma, el desplegament falla en lloc de continuar a cegues. És el correcte —si el mecanisme de seguretat no respon, no continuïs— però produeix fallades desconcertants quan al rol li falta cloudwatch:DescribeAlarms.

L'agent a les instàncies de l'ASG

L'agent és un procés que sondeja CodeDeploy, descarrega la revisió i executa els ganxos. Sense ell, la instància es queda en Pending fins al timeout i el desplegament falla amb un missatge poc explicatiu.

Es pot instal·lar integrat dins de l'AMI, des del user data de lt-mercadofresco-tienda, o —el recomanable— com a associació de Systems Manager amb actualització automàtica:

aws ssm create-association --name AWSCodeDeployAgentUpdate \
  --targets Key=tag:Proyecto,Values=mercadofresco \
  --schedule-expression "rate(14 days)" \
  --profile mercadofresco-dev --region eu-west-1

Aquesta última és la que fa servir MercadoFresco perquè resol el problema real: un agent desactualitzat deixa de funcionar sense avisar, i actualitzar-lo a mà en instàncies que l'ASG crea i destrueix és impossible.

Dos requisits que s'obliden. El rol de la instància ha de poder llegir l'artefacte:

{
  "Version": "2012-10-17",
  "Statement": [
    { "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:GetObjectVersion", "s3:ListBucket"],
      "Resource": ["arn:aws:s3:::mercadofresco-artefactos",
                   "arn:aws:s3:::mercadofresco-artefactos/tienda/*"] },
    { "Effect": "Allow", "Action": ["kms:Decrypt"],
      "Resource": "arn:aws:kms:eu-west-1:111122223333:key/*",
      "Condition": {"StringEquals": {"kms:ViaService": "s3.eu-west-1.amazonaws.com"}} }
  ]
}

El segon bloc cal perquè el bucket està xifrat amb alias/mercadofresco-datos: sense permís de KMS, l'agent descarrega l'objecte i falla en desxifrar-lo, amb un error d'accés denegat que sembla un problema d'S3. El segon requisit és sortida a internet o VPC endpoints: l'agent parla amb l'API de CodeDeploy i amb S3, i una subxarxa privada sense NAT ni endpoints deixa el desplegament penjat. Per diagnosticar, systemctl status codedeploy-agent i el registre a /var/log/aws/codedeploy-agent/codedeploy-agent.log.

L'appspec.yml per a EC2

L'appspec.yml va a l'arrel del ZIP, no en un subdirectori, i diu a l'agent què cal copiar i què cal executar:

version: 0.0
os: linux

files:
  - source: /app
    destination: /opt/mercadofresco/app
  - source: /scripts
    destination: /opt/mercadofresco/scripts
  - source: /VERSION
    destination: /opt/mercadofresco

# Sense aixo, un fitxer que ja existeixi al desti fa fallar el desplegament sencer
file_exists_behavior: OVERWRITE

permissions:
  - object: /opt/mercadofresco/app
    owner: mercadofresco
    mode: 640
    type: [file]

hooks:
  ApplicationStop:
    - { location: scripts/parar_servicio.sh, timeout: 60, runas: root }
  BeforeInstall:
    - { location: scripts/comprobar_espacio.sh, timeout: 30, runas: root }
  AfterInstall:
    - { location: scripts/instalar_dependencias.sh, timeout: 300, runas: mercadofresco }
    - { location: scripts/cargar_configuracion.sh, timeout: 60, runas: mercadofresco }
  ApplicationStart:
    - { location: scripts/arrancar_servicio.sh, timeout: 120, runas: root }
  ValidateService:
    - { location: scripts/comprobar_salud.sh, timeout: 180, runas: mercadofresco }
    - { location: scripts/calentar_cache.sh, timeout: 120, runas: mercadofresco }

file_exists_behavior: OVERWRITE mereix un avís: sense ell, el valor per defecte és DISALLOW i el desplegament falla si un fitxer ja existeix a la destinació. Com que la destinació gairebé sempre té la versió anterior, és la primera fallada que troba tothom. RETAIN existeix per a fitxers que l'aplicació genera i no s'han de sobreescriure.

Els ganxos del cicle de vida, un a un

Ganxo Quan Revisió Per a què serveix
ApplicationStop Abans de res L'ANTERIOR Aturar el servei netament
BeforeInstall Abans de copiar La nova Comprovacions prèvies, còpies
AfterInstall Després de copiar La nova Dependències, permisos, configuració
ApplicationStart Després d'instal·lar La nova Arrencar el servei
ValidateService L'últim La nova Comprovar que funciona de debò
BeforeAllowTraffic Només blue/green La nova Escalfar abans de rebre trànsit
AfterAllowTraffic Només blue/green La nova Validar ja amb trànsit real

Tres coses que cal entendre bé. ApplicationStop s'executa des de la revisió ANTERIOR, i és la font d'un problema clàssic: si el desplegament anterior va deixar un parar_servicio.sh trencat, el desplegament nou falla al primer ganxo encara que el codi nou sigui perfecte —i al primer desplegament d'una instància no s'executa, perquè no hi ha revisió anterior—. Escriu-lo a prova de bales i fes que acabi amb èxit encara que no trobi el servei. ValidateService és el ganxo que justifica tota la resta: sense ell, «desplegat» vol dir «els fitxers estan copiats i systemctl no s'ha queixat», que no és el mateix que «la botiga funciona». I els timeouts són per ganxo, amb un màxim d'una hora: un AfterInstall sense memòria cau pot passar de 300 segons, i un ValidateService amb 10 segons falla sempre a la primera instància, que és la més lenta a escalfar.

Els scripts reals de MercadoFresco

Aturar el servei sense fallar si no hi és:

#!/bin/bash
# scripts/parar_servicio.sh  -> ApplicationStop
# ATENCIO: s'executa des de la revisio ANTERIOR. Ha de ser a prova de bales.
set -u    # NO hi posem 'set -e': volem controlar les fallades nosaltres

systemctl list-unit-files | grep -q '^mercadofresco.service' || {
  echo "El servei encara no existeix (primer desplegament)."; exit 0; }

systemctl stop mercadofresco
for i in $(seq 1 30); do
  systemctl is-active --quiet mercadofresco || {
    echo "Aturat netament en ${i}s"; exit 0; }
  sleep 1
done

echo "No s'ha aturat en 30s. Forcant."
systemctl kill -s SIGKILL mercadofresco || true
exit 0      # MAI no fallem aqui: bloquejaria tots els desplegaments futurs

L'exit 0 final és deliberat: un ApplicationStop que falla deixa la instància en un estat del qual només se surt recreant el grup de desplegament.

Comprovar la salut de debò:

#!/bin/bash
# scripts/comprobar_salud.sh  -> ValidateService
set -euo pipefail

for i in $(seq 1 30); do
  RESPOSTA=$(curl -sf -m 5 http://localhost:8080/salud 2>/dev/null || echo '{}')
  if [ "$(echo "$RESPOSTA" | jq -r '.estado // "ko"')" = "ok" ]; then
    # No n'hi ha prou amb un 200: comprovem les dependencies critiques una a una
    for dep in aurora redis sqs; do
      SALUT=$(echo "$RESPOSTA" | jq -r ".dependencias.${dep} // \"ko\"")
      [ "$SALUT" = "ok" ] || { echo "Dependencia ${dep} en estat ${SALUT}"; exit 1; }
    done
    # I que la versio viva sigui la que acabem de desplegar
    VERSIO_VIVA=$(echo "$RESPOSTA" | jq -r '.version')
    [ "$VERSIO_VIVA" = "$(cat /opt/mercadofresco/VERSION)" ] || {
      echo "Serveix ${VERSIO_VIVA}, no l'esperada"; exit 1; }
    echo "Salut OK, versio ${VERSIO_VIVA}"; exit 0
  fi
  echo "Intent ${i}/30"; sleep 5
done

echo "No s'ha passat la comprovacio de salut en 150s"
exit 1

Aquest script és el cor de la seguretat del desplegament, i fa tres comprovacions que un curl -f /salud simple no fa: que les dependències crítiques responguin —de res no serveix que el procés sigui viu si no arriba a Aurora—, que la versió que respon sigui la que acabes d'instal·lar —detecta el cas en què el servei no va arribar a reiniciar-se— i que tot passi dins d'un termini. El seu exit 1 és el que dispara la reversió.

Escalfar la memòria cau abans de rebre trànsit:

#!/bin/bash
# scripts/calentar_cache.sh  -> ValidateService (o BeforeAllowTraffic en blue/green)
set -euo pipefail
curl -sf -m 30 -X POST http://localhost:8080/interno/precargar-catalogo
for sku in FRUT-0012 VERD-0034 PESC-0007 CARN-0021; do
  curl -sf -m 5 "http://localhost:8080/productos/${sku}" > /dev/null
done
echo "Memoria cau calenta"

Sense aquest pas, la primera onada de trànsit troba la memòria cau buida, va a Aurora, i TiempoConfirmacionPedido es dispara durant dos minuts. Al pic del divendres amb 900 comandes/hora, això és exactament el que fa saltar mercadofresco-alb-latencia-alta i reverteix un desplegament que estava bé.

Desplegament al lloc: AllAtOnce, HalfAtATime i OneAtATime

Configuració Alhora Capacitat mínima Durada (4 instàncies) Quan
AllAtOnce Totes 0 ~3 min Desenvolupament. Mai en producció
HalfAtATime 50 % 50 % ~6 min Producció amb marge de capacitat
OneAtATime 1 N-1 ~12 min Màxima prudència; flotes petites

AllAtOnce en producció és una caiguda, no un desplegament. Totes les instàncies fora alhora és el que es vol evitar; i si falla, no queda cap instància amb la versió bona a la qual tornar.

Es pot definir una configuració pròpia amb aws deploy create-deployment-config i --minimum-healthy-hosts type=FLEET_PERCENT,value=90. Però compte: amb aquest 90 % i una flota de 2 instàncies, el mínim sa és 2 (arrodoneix cap amunt) i cap desplegament no pot començar; amb flotes petites fes servir HOST_COUNT en lloc de percentatges.

Blue/green amb l'ASG i els grups de destinació

En blue/green no es toca cap instància existent: se'n creen de noves, es comproven, se'ls passa el trànsit i només llavors es terminen les antigues.

flowchart TB
    ALB[alb-mercadofresco-tienda] -->|100% abans| TGA[tg-mercadofresco-tienda]
    ALB -.->|100% despres| TGV[tg-mercadofresco-tienda-verde]
    TGA --> AZUL[Blau: v1.4.3<br/>i-aaa1, i-aaa2]
    TGV --> VERDE[Verd: v1.5.0<br/>i-vvv1, i-vvv2]
    VERDE --> H[BeforeAllowTraffic:<br/>escalfar memoria cau]
    H --> S{Estat OK?}
    S -->|No| F[Terminar el verd<br/>El blau continua servint]
    S -->|Si| C[Canviar l'oient de l'ALB]
    C --> W[Esperar 30 min<br/>vigilant les alarmes]
    W -->|Alarma| R[REVERSIO:<br/>tornar al blau en 90 s]
    W -->|Tot be| T[Terminar el blau]
aws deploy update-deployment-group \
  --application-name app-mercadofresco-tienda \
  --current-deployment-group-name dg-mercadofresco-tienda-produccion \
  --deployment-style '{"deploymentType":"BLUE_GREEN",
                       "deploymentOption":"WITH_TRAFFIC_CONTROL"}' \
  --blue-green-deployment-configuration '{
    "terminateBlueInstancesOnDeploymentSuccess": {
      "action": "TERMINATE", "terminationWaitTimeInMinutes": 30 },
    "deploymentReadyOption": { "actionOnTimeout": "CONTINUE_DEPLOYMENT" },
    "greenFleetProvisioningOption": { "action": "COPY_AUTO_SCALING_GROUP" }}' \
  --profile mercadofresco-dev --region eu-west-1

terminationWaitTimeInMinutes: 30 és la finestra en què l'entorn blau continua existint, apagat però íntegre, després del canvi de trànsit: és el que fa que la reversió sigui de noranta segons, perquè només cal tornar l'oient al grup de destinació blau —amb 0 estalvies cèntims i tornar enrere passa a ser un desplegament complet de deu minuts—. actionOnTimeout: CONTINUE_DEPLOYMENT fa el canvi de trànsit automàtic; l'alternativa STOP_DEPLOYMENT espera que algú premi «reencaminar trànsit», útil el primer dia i insostenible com a pràctica. I COPY_AUTO_SCALING_GROUP crea un ASG nou copiant lt-mercadofresco-tienda, davant de DISCOVER_EXISTING amb instàncies ja etiquetades.

Aspecte Al lloc Blue/green
Cost durant el desplegament Cap Capacitat duplicada
Temps de reversió Desplegament complet (~10 min) ~90 segons
Risc per a la versió estable Se sobreescriu Intacta fins al final
Durada total 6-12 min 15-40 min
Estat local al disc Es conserva Es perd: instàncies noves

MercadoFresco fa servir al lloc amb HalfAtATime en desenvolupament i blue/green en producció. Duplicar dos t3.medium mitja hora són uns nou cèntims per desplegament; noranta segons de reversió valen força més que això.

L'appspec de Lambda i d'ECS

Per a Lambda i ECS l'appspec és una altra cosa: no copia fitxers, declara quina versió ha de rebre el trànsit. Admet YAML o JSON.

# appspec-lambda.yml
version: 0.0
Resources:
  - mercadofresco-cobrar-pago:
      Type: AWS::Lambda::Function
      Properties:
        Name: mercadofresco-cobrar-pago
        Alias: produccion
        CurrentVersion: "7"      # la que serveix ara
        TargetVersion: "8"       # la nova
Hooks:
  - BeforeAllowTraffic: mercadofresco-validar-antes-de-trafico
  - AfterAllowTraffic: mercadofresco-validar-despues-de-trafico

Diferència important: a Lambda els ganxos són funcions Lambda, no scripts, i tenen una obligació que sempre s'oblida: comunicar el seu resultat amb PutLifecycleEventHookExecutionStatus, o CodeDeploy espera fins al timeout i falla.

import boto3, json, os
cd = boto3.client("codedeploy")
lam = boto3.client("lambda")

def handler(event, context):
    id_desplegament = event["DeploymentId"]
    estat = "Failed"
    try:
        # Invoquem la versio NOVA directament, abans que rebi transit real
        r = lam.invoke(
            FunctionName=f"mercadofresco-cobrar-pago:{os.environ['VERSION_NUEVA']}",
            Payload=json.dumps({"modo": "prueba_humo", "importe_eur": 1.00,
                                "clave_idempotencia": f"humo-{id_desplegament}"}))
        cos = json.loads(r["Payload"].read())
        if r["StatusCode"] == 200 and cos.get("estado") == "cobrado":
            estat = "Succeeded"
    except Exception as e:
        print(f"Prova de fum fallida: {e}")

    # SENSE aquesta crida, CodeDeploy espera fins al timeout i falla el desplegament
    cd.put_lifecycle_event_hook_execution_status(
        deploymentId=id_desplegament,
        lifecycleEventHookExecutionId=event["LifecycleEventHookExecutionId"],
        status=estat)
    return {"status": estat}

Fixa't en la clave_idempotencia derivada de l'identificador del desplegament: la prova de fum passa pel mateix camí que un cobrament real, i sense una clau única cada desplegament reutilitzaria l'anterior. És la idempotència de 07-05 aplicada al desplegament mateix. A ECS l'appspec referencia la definició de tasca i el contenidor; el detall d'ECS és el mòdul 10.

Canari i lineal: desplegar mercadofresco-cobrar-pago

Aquí sí que hi ha desplaçament percentual de trànsit, la millor xarxa de seguretat que ofereix CodeDeploy.

Configuració Com desplaça Durada Quan
AllAtOnce 100 % de cop Segons Desenvolupament
Canary10Percent5Minutes 10 %, espera 5 min, la resta ~5 min Cobraments: poques peticions dolentes
Canary10Percent30Minutes 10 %, espera 30 min, la resta ~30 min Canvis de risc alt
Linear10PercentEvery1Minute +10 % cada minut ~10 min Degradació gradual

Canari o lineal, amb criteri. El canari manté un percentatge petit una estona i després salta al 100 %: si la fallada és evident, només el 10 % la pateix i poc temps. El lineal puja a poc a poc i detecta millor les degradacions que depenen de la càrrega —una fuita de memòria, un pool que s'esgota— però exposa el 50 % abans de la meitat del desplegament. Per a mercadofresco-cobrar-pago, la Marta tria Canary10Percent5Minutes: una fallada en el cobrament és evident en segons, no gradual, i amb 900 comandes/hora al pic, cinc minuts al 10 % són unes 7 comandes exposades.

El mecanisme es recolza en versions i àlies, que vam veure a 02-05: mercadofresco-cobrar-pago:produccion apunta a la versió 7, i CodeDeploy li afegeix un pes cap a la 8 pujant-lo segons la configuració. Tot el que invoca la funció fa servir l'àlies i no s'assabenta de res.

Es llança amb aws deploy create-deployment i --deployment-config-name CodeDeployDefault.LambdaCanary10Percent5Minutes, passant l'appspec a --revision. L'alarma que ho vigila va sobre els errors de l'àlies, no de la funció sencera:

aws cloudwatch put-metric-alarm \
  --alarm-name mercadofresco-cobrar-pago-errores-canario \
  --namespace AWS/Lambda --metric-name Errors --statistic Sum \
  --dimensions Name=FunctionName,Value=mercadofresco-cobrar-pago \
               Name=Resource,Value=mercadofresco-cobrar-pago:produccion \
  --period 60 --evaluation-periods 1 --threshold 3 \
  --comparison-operator GreaterThanThreshold --treat-missing-data notBreaching \
  --alarm-actions arn:aws:sns:eu-west-1:111122223333:alertas-mercadofresco \
  --profile mercadofresco-dev --region eu-west-1

El període de 60 segons i un sol període d'avaluació són deliberats: amb una finestra de 5 minuts per al canari, una alarma de 3 períodes de 5 minuts saltaria quan el desplegament ja és al 100 %. L'alarma ha de ser més ràpida que el desplegament que vigila.

Reversió automàtica: la peça que resol el problema 4

Aquesta és la secció per la qual existeix la lliçó. CodeDeploy reverteix sola en tres situacions, declarades a autoRollbackConfiguration: DEPLOYMENT_FAILURE quan un ganxo retorna diferent de 0 o expira, DEPLOYMENT_STOP_ON_ALARM quan una alarma d'alarmConfiguration passa a ALARM durant el desplegament, i DEPLOYMENT_STOP_ON_REQUEST quan algú l'atura a mà.

L'important és entendre què vol dir «revertir» en cada modalitat, perquè no és el mateix. Al lloc, CodeDeploy llança un desplegament nou amb la revisió anterior: complet, amb els seus ganxos i els seus minuts. En blue/green dins de la finestra d'espera, torna l'oient de l'ALB al grup de destinació blau: noranta segons, i les instàncies blaves ni se n'han assabentat. A Lambda o ECS, torna el pes de l'àlies a la versió anterior: segons.

Alarma Què detecta Per què és aquí
mercadofresco-alb-latencia-alta p95 > 1.500 ms, 2 períodes de 60 s Una versió lenta és una versió trencada
mercadofresco-pedidos-fallidos DLQ > 5 missatges en 5 min El consumidor nou no processa bé
mercadofresco-tienda-degradada Composta (05-01) Visió de conjunt

Triar les alarmes és la decisió de disseny d'aquesta secció, i han de complir tres condicions. Detectar el que provoca un desplegament dolent: una alarma de cost no hi pinta res; una de latència o de 5xx, sí. Ser més ràpides que el desplegament, perquè una de 3 períodes de 5 minuts no protegeix un desplegament de 10. I no saltar per causes alienes: si mercadofresco-alb-latencia-alta salta cada divendres a les 19:00 pel pic normal, revertirà desplegaments correctes i l'equip acabarà desactivant la reversió. Mira-les un mes abans de connectar-les.

L'estat inicial de l'alarma importa. Si en començar ja és en ALARM, CodeDeploy no arrenca: és correcte —no despleguis sobre un sistema que ja va malament— però desconcerta la primera vegada.

Comparació amb la reversió manual i amb Route 53 ponderat

Mecanisme Temps de reversió Automàtic Granularitat
Manual per SSH (el d'avui) 10-30 min, amb nervis No Instància
CodeDeploy al lloc ~10 min Instància
CodeDeploy blue/green ~90 s Entorn complet
CodeDeploy canari (Lambda) Segons % d'invocacions
Route 53 ponderat (03-05) 60 s + TTL No de sèrie % de resolucions DNS

Val la pena comparar amb Route 53 ponderat, que a 03-05 també repartia trànsit i podria semblar alternatiu. No ho és, per dues raons. El TTL del DNS: encara que posis el pes a 0 a l'instant, els resolutors i els navegadors continuen fent servir la resposta desada durant el TTL, així que «revertir» triga minuts i mai no és complet. I que el repartiment és de resolucions, no de peticions: un client que resol una vegada i manté la connexió es queda on ha caigut. Route 53 ponderat és excel·lent per moure trànsit entre regions; CodeDeploy és el mecanisme correcte per desplegar una versió, perquè opera sobre el balancejador i és immediat i complet.

Migracions d'esquema: expansió i contracció

Aquí hi ha l'advertiment més important de la lliçó, i no és un detall tècnic sinó una regla de procés: el desplegament del codi i el canvi de l'esquema no han d'anar al mateix pas.

El raonament és senzill. Durant qualsevol desplegament gradual conviuen dues versions del codi contra una sola base de dades: si l'AfterInstall de la nova executa ALTER TABLE pedidos DROP COLUMN direccion_antigua, la vella —que continua servint la meitat del trànsit— comença a fallar. I si el desplegament reverteix, la reversió no desfà l'ALTER TABLE: et quedes amb el codi vell i l'esquema nou, el pitjor dels estats possibles. La resposta és expansió i contracció, en tres desplegaments:

Fase Què es fa Compatible amb Quan
1. Expandir Afegir el nou sense treure res: columna NULLABLE Totes dues versions Abans del codi
2. Migrar Codi que escriu als dos i llegeix del nou amb reserva Totes dues versions Desplegament normal
3. Contraure Treure el vell Només la nova Dies o setmanes després

Aplicat a la franja horària que el Luis afegirà:

-- FASE 1 (expandir): ABANS de desplegar el codi. Sense NOT NULL, sense DEFAULT i sense
-- index: no reescriu la taula ni bloqueja. La 1.4.3 no coneix la columna i la ignora.
ALTER TABLE pedidos ADD COLUMN franja_entrega VARCHAR(10) NULL;

-- FASE 3 (contraure): setmanes despres, quan CAP instancia no serveix ja la 1.4.3
ALTER TABLE pedidos ALTER COLUMN franja_entrega SET NOT NULL;
CREATE INDEX CONCURRENTLY idx_pedidos_franja ON pedidos(franja_entrega);

Quatre regles pràctiques que se'n deriven. No executis mai migracions en un ganxo de CodeDeploy: el ganxo corre a cada instància, així que amb quatre instàncies tens quatre ALTER TABLE simultanis, i si falla a mitges el desplegament reverteix però l'esquema no. La migració és un pas propi del pipeline, abans del desplegament de l'aplicació; això és 08-04. Tota migració d'expansió ha de ser reversible o innòcua: una columna NULLABLE sobra però no molesta si el codi reverteix. I CREATE INDEX CONCURRENTLY per no bloquejar la taula, fora del desplegament. El recorregut complet, amb el consumidor de la cua i el contracte de l'esdeveniment, és la lliçó 08-05.

Observabilitat del desplegament i diagnòstic d'una fallada

CodeDeploy publica a EventBridge cada canvi d'estat, així que tot el de 07-03 s'hi aplica, amb un patró sobre source: ["aws.codedeploy"], detail-type: ["CodeDeploy Deployment State-change Notification"] i detail.state: ["FAILURE", "STOP"].

Amb destinació a alertas-mercadofresco i una transformació d'entrada que deixi un missatge llegible: quina aplicació, quina versió, quin estat i l'enllaç a la consola. Un desplegament que reverteix sol a les 19:15 d'un divendres és una bona notícia, però només si algú se n'assabenta. El diagnòstic d'una fallada:

# Quin desplegament ha fallat i per que; despres, quina instancia i quin ganxo concret
aws deploy get-deployment --deployment-id d-A1B2C3D4E \
  --query 'deploymentInfo.[status,errorInformation.code,errorInformation.message]' --output table
aws deploy get-deployment-target --deployment-id d-A1B2C3D4E --target-id i-0abc123def456 \
  --query 'deploymentTarget.instanceTarget.lifecycleEvents[?status==`Failed`]'
Codi d'error Què significa On cal mirar
HEALTH_CONSTRAINTS Menys instàncies sanes de les exigides Percentatge amb flota petita?
SCRIPT_FAILED Un ganxo ha retornat diferent de 0 El registre de l'agent en aquella instància
SCRIPT_TIMED_OUT Un ganxo ha superat el seu timeout Puja el timeout o accelera l'script
NO_INSTANCES Cap instància no encaixa Etiquetes o nom de l'ASG
AGENT_ISSUE_* L'agent no respon És viu? Hi ha sortida de xarxa?
ALARM_ACTIVE Una alarma era en ALARM en començar Arregla el sistema abans de desplegar

Cost i neteja

Concepte Cost
CodeDeploy a EC2, Lambda i ECS 0 USD (0,02 USD/instància en servidors locals)
Capacitat duplicada en blue/green ~0,09 USD per desplegament (2 × t3.medium, 30 min)
Emmagatzematge de versions de Lambda Quota de 75 GB per regió
Total de MercadoFresco ~2 USD/mes amb 20 desplegaments
# Les versions antigues de Lambda NO s'esborren soles i consumeixen quota
aws lambda list-versions-by-function --function-name mercadofresco-cobrar-pago \
  --query 'Versions[?Version!=`$LATEST`].[Version,LastModified]' --output table
aws lambda delete-function --function-name mercadofresco-cobrar-pago:3

# ASG orfes d'un blue/green fallit: instancies corrent i facturant
aws autoscaling describe-auto-scaling-groups \
  --query "AutoScalingGroups[?starts_with(AutoScalingGroupName,'CodeDeploy_')].[AutoScalingGroupName,DesiredCapacity]"

Els ASG orfes són el cost ocult d'aquesta lliçó. Un blue/green interromput a mitges pot deixar un ASG amb prefix CodeDeploy_ i les seves instàncies vives, servint a ningú i facturant. Revisa'ls després de cada desplegament fallit.

Errors Habituals i Consells

Un ApplicationStop que pot fallar. S'executa des de la revisió anterior i bloqueja tots els desplegaments futurs d'aquella instància. Acaba sempre amb exit 0.

Oblidar file_exists_behavior: OVERWRITE. El valor per defecte DISALLOW fa fallar el desplegament tan bon punt un fitxer ja existeix a la destinació, que és sempre a partir del segon.

Un ValidateService que només comprova que el procés és viu. Un que no arriba a Aurora passa la comprovació i rep trànsit: valida dependències i versió.

Executar migracions de base de dades en un ganxo. Corre a cada instància, no és transaccional respecte al desplegament, i la reversió no ho desfà. És l'error més car del mòdul.

AllAtOnce en producció, que no és un desplegament sinó una caiguda programada; i percentatges de flota sana amb flotes petites, perquè FLEET_PERCENT=90 amb 2 instàncies exigeix 2 de sanes i cap desplegament no pot començar. Fes servir HOST_COUNT.

terminationWaitTimeInMinutes: 0 en blue/green. Estalvies cèntims i perds la reversió de 90 segons, que és la raó per la qual vas triar blue/green.

Alarmes més lentes que el desplegament, que salten quan ja està tot desplegat; o alarmes amb falsos positius connectades a la reversió, que revertiran desplegaments bons fins que l'equip desactivi la reversió sencera. Mira-les un mes abans de connectar-les.

Oblidar PutLifecycleEventHookExecutionStatus en un ganxo de Lambda, que fa esperar fins al timeout amb un missatge que no esmenta la crida que falta; o manca de permisos de KMS al rol de la instància, que impedeix desxifrar el ZIP amb un error que sembla d'S3.

Consell: prova la reversió a propòsit. Desplega una versió amb ValidateService que retorni 1 i cronometra: una reversió que ningú no ha assajat és una hipòtesi. Tingues un /salud que digui la veritat, amb l'estat de cada dependència i la versió que serveix, perquè és la peça sobre la qual es recolza tota la resta. I desplega primer en desenvolupament: els ganxos trencats es descobreixen igual de bé allà.

Exercicis

Exercici 1: el desplegament que es va quedar encallat

El Luis desplega la 1.5.0 a dg-mercadofresco-tienda-produccion (al lloc, HalfAtATime, 4 instàncies). La primera meitat va bé; la segona falla amb SCRIPT_FAILED a ApplicationStop. La reversió es llança i també falla a ApplicationStop. Resultat: 2 instàncies amb 1.5.0, 2 amb 1.4.3 i cap desplegament possible. Investigant, veu que el parar_servicio.sh de la 1.4.3 fa set -e i systemctl stop mercadofresco && rm /var/run/mercadofresco.pid, i que aquest fitxer PID ja no existeix des de la 1.4.2.

Respon: (a) per què la reversió falla al mateix lloc; (b) per què les dues primeres instàncies sí que van funcionar; (c) com desbloqueges la situació ara mateix, amb les ordres; (d) com evites que torni a passar; (e) què hauria canviat si el grup fos blue/green.

Exercici 2: triar estratègia per a tres components

Per a cada component indica destinació, configuració de desplegament, alarmes connectades a la reversió i justificació. (a) La botiga web a asg-mercadofresco-tienda (2-4 instàncies), amb pic els divendres de 17:00 a 21:00 i 900 comandes/hora, on un error 500 és una venda perduda. (b) La Lambda mercadofresco-cobrar-pago, unes 900 invocacions/hora al pic, ja idempotent (07-05), on una fallada pot cobrar dues vegades o no cobrar. (c) Els treballadors d'asg-mercadofresco-trabajadores, que consumeixen cola-mercadofresco-pedidos, no reben trànsit de l'ALB i si s'aturen 5 minuts la cua creix i es buida després.

Exercici 3: la migració que va trencar la reversió

El dimarts a les 11:00, el Luis desplega la 1.6.0 en blue/green. La 1.6.0 reanomena la columna direccion a direccion_entrega, i l'AfterInstall executa ALTER TABLE pedidos RENAME COLUMN direccion TO direccion_entrega;. El verd arrenca bé, passa ValidateService i rep el 100 % del trànsit. Al cap de 8 minuts, mercadofresco-pedidos-fallidos salta: el consumidor de la cua, que encara és 1.5.2, falla a cada missatge. CodeDeploy reverteix al blau en 90 segons. I llavors la botiga sencera deixa de funcionar.

Respon: (a) per què la reversió va empitjorar les coses; (b) quantes vegades es va executar l'ALTER TABLE i què va passar a la segona; (c) el pla de recuperació immediata; (d) com s'hauria d'haver fet el canvi, amb les fases i què es desplega a cadascuna; (e) quin control automàtic hauria impedit que això arribés a producció.

Solucions

Solució 1

(a) Perquè ApplicationStop s'executa sempre des de la revisió anterior instal·lada a la instància, i a les instàncies 3 i 4 la revisió anterior és la 1.4.3, l'script de la qual està trencat. La reversió és un desplegament nou de la 1.4.3, i el seu primer ganxo torna a ser l'ApplicationStop del que hi ha instal·lat —que continua sent la 1.4.3 trencada—. S'executa el mateix script defectuós i falla igual. El bucle és exactament el motiu pel qual aquest ganxo ha de ser a prova de bales.

(b) Per casualitat, i val la pena entendre-la: a les instàncies 1 i 2 el fitxer PID existia —eren més antigues i n'arrossegaven un de la 1.4.1—, així que rm va retornar 0 i l'script va acabar bé. A les 3 i 4, recreades per l'ASG amb la 1.4.3 neta, no hi havia fitxer, rm va retornar 1 i set -e va avortar. Un desplegament que funciona a mitja flota i falla a l'altra meitat gairebé sempre assenyala estat divergent entre instàncies, i això ja és un problema en si: les instàncies d'un ASG haurien de ser indistingibles.

(c) Desbloquejar. El camí ràpid, si la botiga serveix malament, és arreglar l'script a mà a les instàncies afectades per Session Manager, editant el deployment-root/<id>/deployment-archive/scripts/parar_servicio.sh, i tornar a llançar. El net és saltar-se el ganxo una sola vegada: a la consola es pot llançar un desplegament marcant l'opció d'ometre ApplicationStop, BeforeBlockTraffic i AfterBlockTraffic, pensada exactament per a aquest cas. L'alternativa equivalent per CLI és esborrar i recrear el grup de desplegament, perquè això elimina la referència a l'última revisió coneguda i ApplicationStop deixa d'executar-se:

aws deploy delete-deployment-group --application-name app-mercadofresco-tienda \
  --deployment-group-name dg-mercadofresco-tienda-produccion \
  --profile mercadofresco-dev --region eu-west-1
# ...recrear-lo, i desplegar la 1.4.3 de nou amb create-deployment.

(d) Tres mesures. A l'script, treure set -e, posar exit 0 incondicional al final i fer servir rm -f, que no falla si el fitxer no existeix. Al procés, una prova dels ganxos a CodeBuild: un contenidor que executi cada script contra un sistema net i comprovi que retornen 0 en els casos «el servei no existeix», «el servei està aturat» i «el servei està corrent». I desplegar sempre primer en desenvolupament, on aquesta fallada hauria aparegut sense conseqüències.

(e) Amb blue/green no hauria passat res: les instàncies verdes són noves i no tenen revisió anterior, així que ApplicationStop ni s'executa. Si el desplegament fallés per un altre motiu, el blau —intacte, amb la 1.4.3 funcionant— continuaria servint el 100 % i la reversió seria tornar l'oient de l'ALB. És un argument a favor de blue/green que no apareix a les taules: elimina d'arrel tota una classe de fallades, les heretades del desplegament anterior.

Solució 2

(a) La botiga web. EC2 amb l'ASG, blue/green, terminationWaitTimeInMinutes: 30 i actionOnTimeout: CONTINUE_DEPLOYMENT. Alarmes: mercadofresco-alb-latencia-alta i mercadofresco-tienda-degradada. Justificació: amb 2-4 instàncies, un desplegament al lloc deixa la meitat de la capacitat fora justament quan més falta fa; blue/green manté el 100 % durant tot el procés, i la reversió de 90 segons és el que permet desplegar sense por. Regla operativa afegida: cap desplegament de la botiga entre les 16:00 i les 22:00 del divendres, no per desconfiar del mecanisme sinó perquè equivocar-se al pic surt desproporcionadament car. Ganxos: BeforeAllowTraffic escalfa la memòria cau —clau, o la primera onada dispara la latència i reverteix un desplegament bo— i AfterAllowTraffic fa una prova de fum amb trànsit real.

(b) La Lambda de cobraments. Canary10Percent5Minutes, amb mercadofresco-cobrar-pago-errores-canario (període 60 s, 1 avaluació, llindar 3) i una sobre Duration p99. Justificació: una fallada de cobrament és evident en segons, no gradual, així que el canari detecta abans i exposa menys que el lineal. Amb 900 invocacions/hora, 5 minuts al 10 % són unes 7 comandes exposades, i la idempotència de 07-05 evita que un reintent després de la reversió dupliqui el cobrament. Més un BeforeAllowTraffic que invoca la versió nova amb un pagament de prova d'1,00 €. El detall que no s'ha d'oblidar: l'alarma ha de portar la dimensió Resource de l'àlies, o mesuraria els errors de totes les versions juntes i es contaminaria amb les invocacions de la vella.

(c) Els treballadors. Al lloc amb AllAtOnce, sense alarmes de latència, amb mercadofresco-pedidos-fallidos connectada a la reversió. Justificació: aquí el raonament canvia del tot, i aquest és l'interès de l'apartat. No reben trànsit de l'ALB, així que no hi ha peticions que puguin fallar: si s'aturen cinc minuts, la cua creix i es buida després, que és exactament l'amortiment que buscàvem a 07-01. Blue/green seria complexitat i cost sense benefici. El que que cal garantir és un ApplicationStop net, que deixi acabar el missatge en curs i no l'esborri a mitges, o quedaran missatges en vol reapareixent en expirar la visibilitat. I vigilar ApproximateAgeOfOldestMessage després del desplegament: si no baixa en deu minuts, el consumidor nou no processa encara que el procés sigui viu.

Solució 3

(a) Perquè la reversió va tornar el codi a la 1.5.2 però no va desfer l'esquema. La 1.5.2 consulta direccion, que ja no existeix. Abans de la reversió almenys la botiga funcionava amb la 1.6.0 i només fallava el consumidor; després falla tot, perquè el 100 % del trànsit el serveix un codi incompatible amb l'esquema. És el parany que la lliçó adverteix: la reversió reverteix artefactes, no bases de dades, i un canvi d'esquema destructiu converteix la teva xarxa de seguretat en un accelerador de l'incident.

(b) Es va executar una vegada per instància verda, és a dir 2 vegades. La primera va tenir èxit; la segona va fallar amb ERROR: column "direccion" does not exist, perquè el canvi de nom ja estava fet. Que el desplegament no s'aturés aquí depèn de si l'script s'empassava l'error. Aquest comportament és la demostració de per què les migracions no van en ganxos: no són idempotents i s'executen tantes vegades com instàncies hi hagi.

(c) Recuperació immediata, amb la botiga caiguda, així que ràpid i sense elegàncies. Convergir cap endavant, no cap enrere: l'esquema ja és a l'estat nou i tornar a canviar-li el nom és una altra migració amb risc, així que redesplegar la 1.6.0, que sí que és compatible, i recuperar la botiga. Després, desplegar la versió compatible del consumidor, que continua a 1.5.2 i continua fallant; mentrestant els missatges s'acumulen a cola-mercadofresco-pedidos i acabaran a la DLQ, però no es perden. Amb la botiga servint, aplicar el runbook de la DLQ de 07-05 —contenir, classificar, reprocessar—. I un post-mortem sense buscar culpables, amb la regla de procés escrita.

(d) Com s'hauria d'haver fet, en tres desplegaments separats per dies. Desplegament 1 (expandir), dilluns: només esquema, sense codi nou —ALTER TABLE pedidos ADD COLUMN direccion_entrega VARCHAR(255) NULL; més un UPDATE que copiï els valors—; la 1.5.2 continua funcionant perquè no coneix la columna nova i no li molesta. Desplegament 2 (migrar), dimarts: el codi 1.6.0 escriu a les dues columnes i llegeix de direccion_entrega amb reserva a direccion, cosa que el fa compatible en tots dos sentits —conviu amb la 1.5.2 durant el desplegament gradual i funciona si cal revertir—; aquí el consumidor de la cua es desplega abans que la botiga, perquè sàpiga llegir el camp nou abans que comenci a arribar, que és l'ordre productor/consumidor que tanca 08-05. Desplegament 3 (contraure), la setmana següent, quan cap instància no serveix ja la 1.5.2: ALTER TABLE pedidos DROP COLUMN direccion;. I cada fase d'esquema com a pas propi del pipeline, executat una sola vegada des d'una tasca dedicada, mai des d'un ganxo.

(e) Tres controls, de més barat a més car. Una anàlisi de les migracions a CodeBuild que faci fallar la construcció si detecta DROP COLUMN, RENAME COLUMN, ALTER COLUMN ... NOT NULL o DROP TABLE sense una etiqueta explícita de «contracció aprovada»: són trenta línies d'script i haurien parat això en sec. Una prova de compatibilitat cap enrere que arrenqui la versió anterior del codi contra l'esquema nou i executi la suite de fum —simula directament la reversió, i és sorprenentment rara a la pràctica—. I revisió obligatòria de tot canvi a migraciones/ mitjançant una regla de propietaris de codi, perquè cap canvi d'esquema no entri amb una aprovació distreta.

Conclusió

El ritual del Luis s'ha acabat. Ja no hi ha ssh, ni scp, ni quaranta segons d'errors per instància, ni dues versions convivint sense control. Hi ha una aplicació app-mercadofresco-tienda, dos grups de desplegament que fan que la mateixa revisió es comporti de manera diferent en desenvolupament i en producció, un artefacte identificat a mercadofresco-artefactos i un pla que CodeDeploy executa igual totes les vegades. I sobretot, una cosa que no existia: una tornada enrere que no depèn que algú estigui mirant.

Coneixes les tres destinacions i què admet cadascuna —a EC2 no hi ha canari ni lineal; a Lambda i ECS no hi ha desplegament al lloc— i saps que l'agent només cal a EC2, instal·lat com a associació de Systems Manager perquè s'actualitzi sol. Domines l'appspec.yml amb els seus files, permissions i hooks, inclòs file_exists_behavior: OVERWRITE, la primera fallada que troba tothom. I coneixes els ganxos un a un, amb les dues veritats que més incidents eviten: que ApplicationStop s'executa des de la revisió anterior —i per això ha d'acabar sempre amb exit 0— i que ValidateService és el ganxo que justifica tota la resta, comprovant dependències i versió en lloc de conformar-se amb un procés viu.

Saps triar el ritme: AllAtOnce només en desenvolupament, HalfAtATime amb marge de capacitat, OneAtATime quan la prudència importa més que el rellotge, i per què un FLEET_PERCENT alt amb dues instàncies impedeix arrencar qualsevol desplegament. Tens el blue/green amb el seu terminationWaitTimeInMinutes de 30 minuts —literalment el preu de la reversió de 90 segons— i el seu avantatge amagat: en ser instàncies noves, elimina d'arrel les fallades heretades del desplegament anterior. I el canari de mercadofresco-cobrar-pago amb Canary10Percent5Minutes, la seva alarma sobre la dimensió Resource de l'àlies i períodes més curts que el desplegament mateix, perquè una alarma més lenta que allò que vigila no protegeix res.

La peça central és la reversió automàtica, i ara saps què vol dir en cada cas: un desplegament complet al lloc, noranta segons en blue/green dins de la finestra, segons a Lambda. Saps que triar les alarmes és una decisió de disseny amb tres condicions —que detectin el que provoca un desplegament dolent, que siguin més ràpides que el desplegament i que no tinguin falsos positius, perquè una alarma sorollosa acaba amb l'equip desactivant la reversió sencera—. I per què Route 53 ponderat no serveix per a això: el TTL del DNS fa que revertir sigui lent i incomplet.

I t'endús l'advertiment més important del mòdul, que no és tècnic sinó de procés: el desplegament de l'aplicació i el canvi d'esquema no van al mateix pas. Perquè conviuen dues versions contra una sola base de dades, perquè un ganxo s'executa una vegada per instància, i sobretot perquè la reversió reverteix artefactes, no bases de dades —un RENAME COLUMN mal col·locat converteix la teva xarxa de seguretat en un accelerador de l'incident—. La resposta és expansió i contracció en tres desplegaments separats.

I aquí hi ha el que falta. Cada peça funciona, però ningú no les ha encadenat. El Luis encara ha de recordar-se de llançar la construcció en fusionar, copiar la ruta de l'artefacte, escriure aws deploy create-deployment amb el bucket i la clau correctes, esperar, mirar si ha anat bé i repetir-ho per a l'entorn següent. El pas d'esquema s'executa a mà. Ningú no comprova que el que es desplega en producció sigui exactament el que es va validar en preproducció, ni hi ha un moment en què la Marta aprovi formalment que un canvi surti. Eines excel·lents i zero orquestració: continuem depenent que una persona recordi la seqüència un divendres a la tarda.

A 08-04, «AWS CodePipeline», s'encadena tot. Veurem la diferència entre lliurament continu i desplegament continu i per què MercadoFresco tria el primer, amb aprovació manual abans de producció; l'estructura de pipelines, etapes, accions i artefactes que flueixen entre elles; els tipus V1 i V2, els disparadors per branca, etiqueta o ruta de fitxer, i les variables de pipeline; l'aprovació manual amb la informació exacta que la Marta necessita per decidir en trenta segons; les etapes de desenvolupament, preproducció i producció; les portes de qualitat amb una acció Lambda que consulta les mètriques de MercadoFresco/Tienda i atura el pipeline si alguna cosa es degrada; els reintents, els permisos per acció i l'accés entre comptes; i les notificacions cap a alertas-mercadofresco i Slack.

Curs d'AWS

Mòdul 1: Introducció a AWS

Mòdul 2: Serveis principals d'AWS

Mòdul 3: Xarxes i lliurament de contingut

Mòdul 4: Seguretat i identitat

Mòdul 5: Monitoratge i gestió

Mòdul 6: Bases de dades

Mòdul 7: Integració d'aplicacions

Mòdul 8: Eines per a desenvolupadors

Mòdul 9: Infraestructura com a codi i govern de comptes

Mòdul 10: Contenidors a AWS

Mòdul 11: Millors pràctiques i gestió de costos

© Copyright 2026. Tots els drets reservats