El codi de MercadoFresco ja viu en un repositori amb regles, branques curtes i pull requests que algú revisa. Però revisar una PR és una persona llegint un diff, i hi ha preguntes que ningú no pot respondre llegint: passen les 214 proves? arrenca el projecte en una màquina neta, o només al portàtil del Luis on hi ha un psycopg2 instal·lat a mà el 2024? té alguna de les 87 dependències una vulnerabilitat publicada aquesta setmana? s'ha colat una clau en un fitxer de configuració?

AWS CodeBuild respon tot això automàticament. És un servei de construcció gestionat i sense servidors: arrenca un contenidor net, clona el teu codi, executa el que li diguis en un buildspec.yml, desa els resultats i s'apaga, cobrant per minut d'execució i no per tenir-lo. Aquí és on «funciona al meu portàtil» deixa de ser un argument, perquè a partir d'ara l'únic que compta és si funciona en un contenidor buit que ningú no ha tocat.

Avís de cost. CodeBuild cobra per minut segons la mida de còmput: a eu-west-1, un BUILD_GENERAL1_SMALL uns 0,005 USD/min i un MEDIUM uns 0,010, amb 100 minuts gratis al mes del tipus petit. Amb 20 construccions diàries de 4 minuts en MEDIUM, MercadoFresco pagarà uns 24 USD al mes. El car no és això: és una construcció de 22 minuts que ningú no optimitza, o construir dins de la VPC sense ser conscient del cost del NAT, que veurem al final. Dades fictícies.

Contingut

  1. Què és la integració contínua i quin problema resol
  2. Anatomia d'un projecte de CodeBuild
  3. El rol de servei i els seus permisos
  4. El buildspec.yml de MercadoFresco, comentat
  5. Les fases, una a una
  6. Variables d'entorn i secrets sense fuites als registres
  7. Proves unitàries i informes de proves i cobertura
  8. Què fer quan una prova falla
  9. Proves d'integració: simulació o clon d'Aurora
  10. Anàlisi estàtica, dependències i secrets filtrats
  11. Qualitat com a porta, no com a informe
  12. Artefactes, memòria cau i construccions en paral·lel
  13. CodeBuild dins de la VPC, amb el seu avís de cost
  14. Depurar una construcció que falla
  15. Mètriques, alarmes i cost real
  16. Errors habituals i consells
  17. Exercicis
  18. Conclusió

Què és la integració contínua i quin problema resol

Integració contínua significa que cada canvi s'integra a la branca compartida i es verifica automàticament, diverses vegades al dia. L'important és la segona meitat: es verifica automàticament. Sense verificació, «integració contínua» és només empènyer codi sovint.

Símptoma Causa real Què l'elimina
«Al meu portàtil funciona» El portàtil té estat acumulat Contenidor net a cada construcció
«Se'm va oblidar executar les proves» Executar-les és voluntari Execució automàtica a cada push
«Aquesta prova fa mesos que falla» Ningú no mira el resultat La construcció en vermell bloqueja la PR
«Funcionava abans del teu canvi» Ningú no sap quan es va trencar Historial de construccions per commit
«No sé quina versió hi ha desplegada» Es desplega una carpeta, no un artefacte Artefacte versionat i immutable

Fixa't en el patró: en tots els casos l'arranjament és treure a les persones la responsabilitat de recordar-se'n. Un procés que depèn de la disciplina individual falla el dia que hi ha pressa, que és exactament el dia que més falta fa. El flux que muntarem:

flowchart LR
    A[Push o PR] --> B[Contenidor net]
    B --> C[install] --> D[pre_build<br/>secrets, lint, escanejos]
    D --> E[build<br/>proves + empaquetatge] --> F[post_build]
    F --> G{Tot verd?}
    G -->|Si| H[Artefacte a<br/>mercadofresco-artefactos] --> J[Desplegament: 08-03]
    G -->|No| I[Vermell: alertas-mercadofresco] --> K[La PR no es fusiona]

Anatomia d'un projecte de CodeBuild

Un projecte és la definició de com construir alguna cosa. Les seves set peces:

Peça Què defineix Decisió de MercadoFresco
Origen D'on surt el codi GitHub via conn-mercadofresco-github
Entorn Imatge, mida de còmput, privilegis amazonlinux2-x86_64-standard:5.0, MEDIUM
Rol de servei Què pot fer la construcció a AWS rol-codebuild-mercadofresco-tienda
Buildspec Les ordres que cal executar buildspec.yml a l'arrel del repositori
Artefactes Què es desa i on ZIP a mercadofresco-artefactos
Memòria cau Què es reutilitza entre construccions Local (custom + docker layer)
Registres On va la sortida /aws/codebuild/build-mercadofresco-tienda

Sobre la imatge de l'entorn. Les gestionades d'AWS porten Python, Node, Java, Go, la CLI i Docker preinstal·lats, i s'actualitzen soles. Una imatge pròpia a ECR té sentit quan instal·lar dependències del sistema triga més de dos o tres minuts a cada construcció: mous aquest temps a una construcció d'imatge ocasional. MercadoFresco comença amb la gestionada.

Sobre la mida de còmput. És la decisió amb més impacte en cost i durada, i la intuïció enganya:

Mida vCPU / RAM USD/min Durada a MercadoFresco Cost per construcció
SMALL 2 / 3 GB 0,005 9 min 40 s 0,048 USD
MEDIUM 4 / 7 GB 0,010 4 min 10 s 0,042 USD
LARGE 8 / 15 GB 0,020 3 min 30 s 0,070 USD

MEDIUM és més barat que SMALL aquí, perquè el doble de preu per minut es compensa amb més del doble de velocitat: les proves corren amb pytest -n auto i aprofiten els 4 vCPU. De MEDIUM a LARGE, en canvi, el temps baixa poc i el cost puja, perquè la feina ja no és paral·lelitzable. Cal mesurar, no suposar: la mida òptima depèn de si la teva construcció sap fer servir els nuclis que li dónes.

Sobre privilegedMode. Només cal per construir imatges de Docker, perquè el dimoni necessita privilegis. Activa'l únicament quan el necessitis: un contenidor privilegiat que executa codi d'un repositori té més superfície d'atac.

aws codebuild create-project \
  --name build-mercadofresco-tienda \
  --source '{"type": "GITHUB",
    "location": "https://github.com/mercadofresco/mercadofresco-tienda.git",
    "buildspec": "buildspec.yml", "gitCloneDepth": 1, "reportBuildStatus": true}' \
  --environment '{"type": "LINUX_CONTAINER",
    "image": "aws/codebuild/amazonlinux2-x86_64-standard:5.0",
    "computeType": "BUILD_GENERAL1_MEDIUM", "privilegedMode": false,
    "environmentVariables": [
      {"name": "BUCKET_ARTEFACTOS", "value": "mercadofresco-artefactos", "type": "PLAINTEXT"}]}' \
  --artifacts '{"type": "S3", "location": "mercadofresco-artefactos",
                "packaging": "ZIP", "namespaceType": "BUILD_ID"}' \
  --cache '{"type": "LOCAL", "modes": ["LOCAL_CUSTOM_CACHE", "LOCAL_DOCKER_LAYER_CACHE"]}' \
  --service-role arn:aws:iam::111122223333:role/rol-codebuild-mercadofresco-tienda \
  --timeout-in-minutes 20 --queued-timeout-in-minutes 30 \
  --tags Key=Proyecto,Value=mercadofresco Key=Entorno,Value=produccion \
         Key=Componente,Value=cicd Key=Propietario,Value=luis Key=CentroCoste,Value=plataforma \
  --profile mercadofresco-dev --region eu-west-1

Dos paràmetres mereixen atenció. gitCloneDepth: 1 clona només l'últim commit: els 1.847 commits del Luis afegeixen 40 segons a cada construcció sense aportar res —tret que necessitis la història per a git describe, cas en què hi has de posar 0—. I timeout-in-minutes 20 és un fre d'emergència: una construcció penjada consumiria el temps d'espera per defecte de 60 minuts, i això són minuts facturats.

El rol de servei i els seus permisos

La construcció actua a AWS amb el rol de servei, i aquí el privilegi mínim de 04-01 importa molt: aquest rol el fa servir codi que canvia a cada commit. Amb PowerUserAccess, qualsevol que pugui fusionar una PR podria fer qualsevol cosa al compte.

{
  "Version": "2012-10-17",
  "Statement": [
    { "Sid": "Registros", "Effect": "Allow",
      "Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
      "Resource": "arn:aws:logs:eu-west-1:111122223333:log-group:/aws/codebuild/build-mercadofresco-*:*" },
    { "Sid": "ArtefactosSoloEnSuPrefijo", "Effect": "Allow",
      "Action": ["s3:PutObject", "s3:GetObject", "s3:GetObjectVersion"],
      "Resource": "arn:aws:s3:::mercadofresco-artefactos/tienda/*" },
    { "Sid": "ConfiguracionNoSensible", "Effect": "Allow",
      "Action": ["ssm:GetParameters", "ssm:GetParameter"],
      "Resource": "arn:aws:ssm:eu-west-1:111122223333:parameter/mercadofresco/construccion/*" },
    { "Sid": "SoloElSecretoDePruebas", "Effect": "Allow",
      "Action": "secretsmanager:GetSecretValue",
      "Resource": "arn:aws:secretsmanager:eu-west-1:111122223333:secret:mercadofresco/pruebas/*" },
    { "Sid": "InformesDePruebas", "Effect": "Allow",
      "Action": ["codebuild:CreateReportGroup", "codebuild:CreateReport",
                 "codebuild:UpdateReport", "codebuild:BatchPutTestCases",
                 "codebuild:BatchPutCodeCoverages"],
      "Resource": "arn:aws:codebuild:eu-west-1:111122223333:report-group/build-mercadofresco-*" }
  ]
}

L'important és als Resource, no a les accions. El rol no pot llegir mercadofresco/produccion/rds/mfadmin: només secrets sota mercadofresco/pruebas/. És la diferència entre una construcció compromesa que espatlla un entorn de proves i una que té la contrasenya de producció. Un projecte de construcció no necessita mai credencials de producció, i si creus que les necessita, és que estàs desplegant des de la construcció en lloc de des de CodeDeploy (08-03).

El buildspec.yml de MercadoFresco, comentat

Aquest fitxer viu a l'arrel de mercadofresco-tienda, versionat juntament amb el codi, i és el cor de la lliçó:

version: 0.2

# Variables. Les de 'variables' son publiques i apareixen als registres.
# Les de 'parameter-store' i 'secrets-manager' es resolen en temps d'execucio
# i CodeBuild les emmascara a la sortida.
env:
  variables:
    BUCKET_ARTEFACTOS: "mercadofresco-artefactos"
    COBERTURA_MINIMA: "75"
  parameter-store:
    URL_API_PRUEBAS: "/mercadofresco/construccion/url_api_pruebas"
    HOST_AURORA_PRUEBAS: "/mercadofresco/construccion/host_aurora_pruebas"
  secrets-manager:
    CLAVE_PASARELA_PRUEBAS: "mercadofresco/pruebas/pasarela:clave_api"
  exported-variables:
    - VERSION_APP
    - COMMIT_CORTO

phases:

  install:
    runtime-versions:
      python: 3.12
    commands:
      - pip install --upgrade pip
      - pip install -r requirements.txt -r requirements-dev.txt
      - pip install --quiet bandit pip-audit ruff

  pre_build:
    commands:
      - export COMMIT_CORTO=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c1-7)
      - export VERSION_APP=$(cat VERSION)-${COMMIT_CORTO}
      - echo "Construint versio ${VERSION_APP}"
      # Portes ordenades de mes rapida a mes lenta
      - ruff check app/ tests/ && ruff format --check app/ tests/
      - git secrets --scan || (echo "SECRET DETECTAT AL CODI"; exit 1)
      - pip-audit --strict --desc
      - bandit -r app/ -ll -f json -o informe-bandit.json

  build:
    commands:
      # Proves unitaries alhora, amb informe JUnit i cobertura.
      - |
        pytest tests/unitarias -n auto \
          --junitxml=informes/junit-unitarias.xml \
          --cov=app --cov-report=xml:informes/cobertura.xml \
          --cov-fail-under=${COBERTURA_MINIMA}
      # Proves d'integracio contra serveis simulats (moto).
      - pytest tests/integracion --junitxml=informes/junit-integracion.xml
      # Empaquetatge: nomes el que cal en produccio.
      - mkdir -p paquete
      - pip install -r requirements.txt --target paquete/ --quiet
      - cp -r app/ scripts/ appspec.yml paquete/
      - echo "${VERSION_APP}" > paquete/VERSION
      - cd paquete && zip -rq ../mercadofresco-tienda-${VERSION_APP}.zip . && cd ..

  post_build:
    # finally s'executa ENCARA QUE les ordres anteriors fallin.
    commands:
      - |
        if [ "${CODEBUILD_BUILD_SUCCEEDING}" = "1" ]; then
          aws s3 cp mercadofresco-tienda-${VERSION_APP}.zip \
            s3://${BUCKET_ARTEFACTOS}/tienda/${VERSION_APP}/ \
            --metadata commit=${CODEBUILD_RESOLVED_SOURCE_VERSION},version=${VERSION_APP}
          echo "Artefacte publicat: ${VERSION_APP}"
        else
          echo "Construccio fallida: no es publica artefacte"
        fi
    finally:
      - echo "Duracio total: $((SECONDS / 60))m $((SECONDS % 60))s"

# Els informes es registren a CodeBuild i es veuen a la consola amb el seu historic.
reports:
  pruebas-unitarias:
    files: ["informes/junit-unitarias.xml"]
    file-format: JUNITXML
  cobertura:
    files: ["informes/cobertura.xml"]
    file-format: COBERTURAXML

artifacts:
  files: [mercadofresco-tienda-*.zip]
  discard-paths: yes

cache:
  paths: ["/root/.cache/pip/**/*", ".ruff_cache/**/*"]

Les fases, una a una

Fase Per a què serveix Si falla Durada
install Temps d'execució i eines Avorta; només s'executa finally 20-90 s
pre_build Credencials, variables, comprovacions ràpides Avorta abans de gastar en proves 30-60 s
build Compilar, provar, empaquetar Avorta, però post_build sí que s'executa 2-4 min
post_build Publicar, notificar, netejar Marca la construcció com a fallida 10-30 s

Dos comportaments confonen tothom la primera vegada. post_build s'executa encara que build falli, i és deliberat: vols publicar els informes de les proves precisament quan han fallat. Per això el post_build de dalt comprova CODEBUILD_BUILD_SUCCEEDING; sense aquesta comprovació publicaries a S3 l'artefacte d'una construcció les proves de la qual van fallar, l'error més perillós d'aquesta lliçó. I l'ordre dins de pre_build no és casual: ruff triga 2 segons, l'escaneig de secrets 5, bandit 15 i pip-audit 20, així que un error de format falla en 2 segons en lloc de en 40. Ordena sempre les teves portes per cost creixent.

Variables d'entorn i secrets sense fuites als registres

Els registres van a CloudWatch Logs i els llegeix qualsevol amb permís sobre aquest grup. Qualsevol valor que hi imprimeixis és visible, i un set -x o un echo de depuració poden imprimir un secret sense que ningú se n'adoni.

Tipus On es desa Emmascarat? Per a què
PLAINTEXT Definició del projecte No Configuració pública
PARAMETER_STORE Parameter Store Sí (si és SecureString) Configuració per entorn
SECRETS_MANAGER Secrets Manager Contrasenyes, claus d'API

La sintaxi del bloc secrets-managerNOM_VARIABLE: nom-secret:clau-json:etiqueta— és la que més s'equivoca. Els dos punts separen el nom del secret de la clau concreta dins del JSON: sense :clave_api, la variable rebria el JSON sencer —{"clave_api": "...", "url": "..."}— i el teu codi fallaria amb un error confús. I si el secret té rotació de 04-03, AWSCURRENT garanteix que fas servir la versió vigent.

Com emmascara CodeBuild. Substitueix per *** els valors resolts des de Parameter Store i Secrets Manager. Però és una coincidència de cadenes, no màgia, i s'escapa en tres casos: si transformes el valor (echo $CLAVE | base64), el que s'imprimeix ja no coincideix i surt en clar; si el secret acaba en un fitxer que després imprimeixes amb cat; i si una eina l'inclou en un missatge d'error, com una cadena de connexió completa a l'excepció d'un driver.

Tres regles pràctiques: mai set -x en un buildspec que manegi secrets; redirigeix a /dev/null allò que pugui portar credencials quan no necessitis la sortida; i no posis secrets en variables PLAINTEXT, ni «temporalment per provar», perquè queden a la definició del projecte i a CloudTrail.

Proves unitàries i informes de proves i cobertura

Les proves de MercadoFresco viuen a tests/ i proven el que importa. Un exemple real —la idempotència del consumidor que vam construir a 07-05, que és exactament el tipus de propietat que ningú no verifica a mà:

# tests/unitarias/test_idempotencia.py
import pytest
from app.pedidos import processar_missatge_comanda

def test_mateix_missatge_dues_vegades_cobra_una_sola_vegada(taula_idempotencia, passarela_falsa):
    """L'escenari del modul 7: SQS lliura dues vegades la mateixa comanda."""
    missatge = {"id_pedido": "PED-2026-00841", "importe_eur": 48.20,
                "clave_idempotencia": "PED-2026-00841:cobro"}

    primera = processar_missatge_comanda(missatge)
    segona = processar_missatge_comanda(missatge)   # el duplicat

    assert primera["estado"] == "cobrado"
    assert segona["desde_cache"] is True
    assert passarela_falsa.nombre_de_cobraments == 1     # L'ASSERCIO que importa
    assert passarela_falsa.total_cobrat == pytest.approx(48.20)


def test_franja_invalida_es_rebutja_sense_tocar_aurora(aurora_falsa):
    with pytest.raises(ValueError, match="franja_entrega"):
        processar_missatge_comanda({"id_pedido": "X", "franja_entrega": "noche"})
    assert aurora_falsa.escriptures == 0   # rebuig ABANS d'escriure

Fixa't en què s'afirma. No es comprova «que la funció retorni alguna cosa»: es comprova que la passarel·la es va cridar exactament una vegada i que una dada invàlida no va arribar a escriure's a Aurora. Una prova que no pot fallar quan el comportament es trenca no és una prova, és decoració.

El bloc reports converteix l'XML de JUnit en alguna cosa que CodeBuild entén: a la consola veuràs per construcció quantes proves van passar, quines van fallar amb la seva traça i la tendència històrica. Sense ell hauries de buscar la fallada en 2.000 línies de registre.

Sobre --cov-fail-under=75. La cobertura mesura quines línies van executar les proves, no si ho van fer bé: es pot tenir un 95 % sense una sola asserció útil. Tot i així serveix per detectar codi que ningú no executa, i un llindar que falla la construcció impedeix que baixi sense que ningú se n'adoni. El criteri de la Marta és assenyat: el llindar comença en el valor actual i només pot pujar, mai no es baixa per «desbloquejar» una PR. Baixar-lo una vegada és baixar-lo per sempre.

Què fer quan una prova falla

És la secció més curta i important del mòdul, perquè d'ella depèn que tota la resta serveixi.

Situació Reacció correcta Reacció que arruïna el sistema
Falla per una prova mal escrita Arreglar la prova a la mateixa PR Marcar-la @pytest.mark.skip
Falla de manera intermitent Investigar avui: sol ser una cursa real Reintentar fins que passi
Falla per un servei extern caigut Simular-lo; la unitària no surt a la xarxa Desactivar la prova
Falla i hi ha pressa per desplegar Revertir el commit i desplegar l'anterior Saltar-se la construcció

Les proves intermitents són el perill més gran, més que les que fallen sempre. Una que falla sempre s'arregla; una que falla una de cada quinze vegades ensenya l'equip a prémer «reintentar», i a partir d'aquí una fallada real també es reintenta fins que passa. Solen assenyalar alguna cosa certa: dependència de l'ordre d'execució, una espera fixa en lloc d'una condició, o una condició de cursa que també existeix en producció. Tracta-la com una fallada de prioritat alta o esborra-la, però no la deixis parpellejant. I la regla que ho sosté tot: una construcció en vermell bloqueja la fusió; sense ella, l'equip aprèn en dues setmanes que el vermell és opcional. Aquesta porta es tanca del tot a 08-04.

Proves d'integració: simulació o clon d'Aurora

Les proves unitàries no toquen la xarxa. Les d'integració sí, i hi ha dues estratègies amb equilibris molt diferents:

Estratègia Fidelitat Velocitat Cost Quan
Serveis simulats (moto, LocalStack) Mitjana Segons 0 La majoria de casos
Contenidor real (Postgres en Docker) Alta per a SQL 30-60 s 0 Consultes i esquema
Clon aurora-mf-pruebas-luis Total Minuts ENI + NAT Migracions i rendiment

Amb moto, les crides a AWS s'intercepten en memòria:

# tests/integracion/test_flujo_pedido.py
import boto3, json
from moto import mock_aws
from app.pedidos import confirmar_comanda

@mock_aws
def test_comanda_confirmada_encua_i_publica_esdeveniment():
    sqs = boto3.client("sqs", region_name="eu-west-1")
    sns = boto3.client("sns", region_name="eu-west-1")
    url_cua = sqs.create_queue(QueueName="cola-mercadofresco-pedidos")["QueueUrl"]
    tema = sns.create_topic(Name="mercadofresco-pedido-confirmado")["TopicArn"]

    resultat = confirmar_comanda(
        {"id_cliente": "CLI-4471", "lineas": [{"sku": "FRUT-0012", "uds": 3}],
         "franja_entrega": "tarde"}, url_cua=url_cua, tema_arn=tema)

    missatges = sqs.receive_message(QueueUrl=url_cua, MaxNumberOfMessages=10)
    cos = json.loads(missatges["Messages"][0]["Body"])
    assert cos["id_pedido"] == resultat["id_pedido"]
    assert cos["franja_entrega"] == "tarde"
    assert cos["version_evento"] == "2"     # veure 08-05

Això verifica el flux complet —confirmar, encuar, publicar— en menys d'un segon i sense cost, i per al 90 % dels casos és suficient. El clon d'Aurora es reserva per al que la simulació no et pot dir: si una migració triga 4 segons o 40 minuts sobre 340 GB reals, si un índex nou es fa servir de debò, si una consulta es degrada amb el volum de producció. Això exigeix VPC, i la VPC té un cost.

Anàlisi estàtica, dependències i secrets filtrats

Eina Què busca Bloquejant Cost
ruff Errors d'estil, imports sense fer servir, bugs evidents 0
git-secrets Patrons de credencials al codi Sí, sempre 0
pip-audit CVE coneguts en dependències Sí, amb matisos 0
bandit Patrons de codi insegur Informe 0
Amazon Inspector Vulnerabilitats en imatges d'ECR i Lambda Configurable Per recurs

git-secrets és la xarxa que faltava a 08-01. El .gitignore protegeix del descuit; això protegeix també del git add -f:

- git secrets --register-aws                          # patrons d'AWS: AKIA, claus secretes
- git secrets --add 'sk_live_[0-9a-zA-Z]{24}'         # claus de passarela de pagament
- git secrets --add 'postgres://[^:]+:[^@]+@'         # cadenes de connexio amb contrasenya
- git secrets --add --allowed 'AKIAIOSFODNN7EXAMPLE'  # el de la documentacio, permes

Que sigui bloquejant no es discuteix: un fals positiu costa afegir una excepció --allowed; un fals negatiu costa rotar credencials en producció.

pip-audit amb matisos. Falla si alguna dependència té un CVE conegut, cosa que és correcta però té una manera de fallar que cal anticipar: es publica un CVE en una biblioteca popular un dimarts a la tarda i totes les teves construccions es posen en vermell, inclosa la d'una correcció urgent que no té res a veure. Evita la sortida fàcil de --ignore-vuln, que es converteix en una llista que només creix; el correcte és fallar i avisar per alertas-mercadofresco amb l'identificador de la construcció, de manera que existeixi un procediment i no una excepció permanent.

Amazon CodeGuru Reviewer mereix una menció: analitza el codi amb models entrenats sobre el mateix codi d'Amazon i detecta el que un linter no veu —fuites de recursos, condicions de cursa, ús incorrecte de les API d'AWS—. És de pagament i les seves recomanacions són suggeriments, no portes: per a tres persones és un luxe prescindible; per a cinquanta pot compensar.

Qualitat com a porta, no com a informe

Aquí hi ha el criteri que separa un pipeline útil d'un teatre de qualitat. Una comprovació és o una porta —falla la construcció i bloqueja la fusió— o un informe que ningú no llegirà. No hi ha punt intermedi: un informe que no bloqueja res s'ignora al tercer dia.

Comprovació Porta? Per què
Proves unitàries Una prova en vermell és un comportament trencat
Cobertura < 75 % Impedeix que baixi sense que ningú se n'adoni
Secrets detectats El cost del fals negatiu és rotar en producció
ruff Ràpid i objectiu; discutir estil a les PR és temps perdut
CVE en dependències , amb avís Amb procediment per al dimarts a la tarda
bandit No, informe Molts falsos positius; es revisa setmanalment
Complexitat ciclomàtica No, informe Llindar arbitrari; genera discussions estèrils

La regla per decidir: si no estàs disposat a aturar un desplegament per això, no és una porta. I si no ho és, sigues honest sobre el fet que gairebé ningú no ho llegirà: posa-li un moment explícit de revisió —«els dilluns es mira l'informe de bandit»— o treu-ho del buildspec.

Artefactes: el paquet de l'aplicació i les imatges

El resultat de la construcció és un artefacte immutable i versionat, i aquest és el canvi conceptual més important davant de l'scp del Luis: ja no es desplega «el que hi ha a la carpeta», es desplega mercadofresco-tienda-1.5.0-a3f9c21.zip, un fitxer que existeix, té identificador, es pot descarregar sis mesos després i és exactament el que es va provar.

El bucket mercadofresco-artefactos es crea amb tres propietats no negociables: versionat, que CodePipeline exigeix i que protegeix d'una sobreescriptura accidental; xifratge amb alias/mercadofresco-datos i BucketKeyEnabled per reduir les crides a KMS, que es facturen a part; i una regla de cicle de vida que faci caducar els artefactes.

aws s3api put-bucket-versioning --bucket mercadofresco-artefactos \
  --versioning-configuration Status=Enabled --profile mercadofresco-dev

aws s3api put-bucket-lifecycle-configuration --bucket mercadofresco-artefactos \
  --lifecycle-configuration '{"Rules":[{
    "ID":"caducar-artefactos-antiguos","Status":"Enabled",
    "Filter":{"Prefix":"tienda/"},
    "Expiration":{"Days":90},
    "NoncurrentVersionExpiration":{"NoncurrentDays":30}}]}' \
  --profile mercadofresco-dev

Sense cicle de vida, vint artefactes diaris de 45 MB són 27 GB a l'any de ZIP que ningú no desplegarà mai; amb 90 dies en tens de sobres per tornar enrere i el cost es queda en cèntims.

Imatges de contenidor. Si en lloc d'un ZIP construeixes una imatge, necessites privilegedMode: true, un docker login contra ECR a pre_build amb aws ecr get-login-password, un docker build etiquetant amb ${VERSION_APP} i un docker push a post_build. Sobre això, només el just: ECR, les capes, l'escaneig d'imatges i el desplegament en contenidors són el mòdul 10. Aquí n'hi ha prou de saber que CodeBuild construeix imatges igual de bé que ZIP i que LOCAL_DOCKER_LAYER_CACHE reutilitza les capes.

Memòria cau de dependències i el seu efecte real

Instal·lar 87 paquets des de PyPI triga 45-70 segons a cada construcció: per 20 construccions diàries, 20 minuts al dia descarregant el mateix.

Tipus de memòria cau On viu Estalvi mesurat Limitació
Local (LOCAL_CUSTOM_CACHE) Amfitrió de la construcció 40-55 s Només si cau al mateix amfitrió
S3 Bucket que indiquis 25-40 s Es paga pujar i baixar
Capes de Docker Amfitrió de la construcció 1-3 min Només amb privilegedMode

Els números reals: sense memòria cau, 4 min 10 s; amb encert, 3 min 20 s; amb fallada, 4 min 12 s. L'estalvi és real però modest, i convé dir-ho perquè hi ha expectatives exagerades: la memòria cau local depèn que la construcció caigui en un amfitrió que la tingui, i amb 20 diàries l'encert ronda el 60 %.

Dos advertiments. Una memòria cau enverinada és pitjor que no tenir-ne: si deses site-packages en lloc de la memòria cau de pip, arrossegues versions antigues i depurar-ho porta hores —desa sempre ~/.cache/pip—. I si sospites de la memòria cau, invalida-la: aws codebuild invalidate-project-cache és la primera ordre a provar quan una construcció falla de manera inexplicable.

Construccions en lots

Quan la bateria de proves creix, el bloc batch del buildspec defineix un graf de construccions: diverses —pruebas_unitarias, pruebas_integracion, escaneos— corren alhora, i una etapa empaquetado amb depend-on espera les tres; fast-fail: true cancel·la les altres així que una falla. Una construcció seqüencial de 12 minuts pot baixar a 6, però el cost total en minuts no baixa —pagues els mateixos, només que en paral·lel—; el que compres és temps d'espera del desenvolupador, que sol valer molt més que 0,04 USD. Comença senzill: no paral·lelitzis una construcció de 4 minuts.

CodeBuild dins de la VPC, amb el seu avís de cost

Per defecte CodeBuild corre fora de la teva VPC, amb sortida a internet i sense accés a les teves subxarxes privades: no pot parlar amb aurora-mf-pruebas-luis, que és a snet-mercadofresco-datos-a.

aws codebuild update-project --name build-mercadofresco-tienda \
  --vpc-config '{"vpcId": "vpc-mercadofresco",
    "subnets": ["snet-mercadofresco-app-a", "snet-mercadofresco-app-b"],
    "securityGroupIds": ["sg-mercadofresco-construccion"]}' \
  --profile mercadofresco-dev --region eu-west-1

Tres coses que cal fer bé. Subxarxes privades, sempre: en una de pública sense IP pública la construcció no tindrà sortida a internet i pip install es penjarà fins al temps d'espera, i és la fallada més comuna i desconcertant. Sortida per NAT per arribar a PyPI, o VPC endpoints per a les API d'AWS. I un grup de seguretat sg-mercadofresco-construccion amb una regla d'entrada a sg-mercadofresco-basedatos que permeti el 5432 des d'ell: no obris mai la base de dades per CIDR.

Avís de cost important. Ficar CodeBuild a la VPC té dos costos que sorprenen a la factura. Les ENI: cada construcció crea i destrueix una interfície de xarxa, cosa que afegeix 30-60 segons d'arrencada a cada execució —amb 20 diàries, 20 minuts al dia facturats per no fer res—. I el NAT gateway: 0,048 USD/hora més 0,048 USD per GB; descarregar 300 MB de dependències 20 vegades al dia són uns 9 GB al mes només en trànsit. La recomanació pràctica és tenir dos projectes: build-mercadofresco-tienda fora de la VPC per al 90 % de les construccions amb serveis simulats, i build-mercadofresco-integracion dins, només a les PR cap a main o de manera nocturna. I VPC endpoints de tipus Gateway per a S3 i DynamoDB, gratuïts, que eviten que aquest trànsit passi pel NAT.

Depurar una construcció que falla

1. Els registres de CloudWatch, a /aws/codebuild/build-mercadofresco-tienda. Per anar al gra sense llegir 2.000 línies, aws codebuild batch-get-builds --ids <id> amb --query 'builds[0].phases[?phaseStatus==FAILED].[phaseType,contexts[0].message]' et dóna la fase que va fallar i el seu missatge.

2. Reproducció local amb la imatge oficial. La manera més ràpida d'iterar, i no costa res:

./codebuild_build.sh -i public.ecr.aws/codebuild/amazonlinux2-x86_64-standard:5.0 \
  -a /tmp/salida -s ~/proyectos/tienda -b buildspec.yml

L'script és al repositori aws/aws-codebuild-docker-images i executa el mateix buildspec en la mateixa imatge, a la teva màquina: si falla igual, tens un bucle de depuració de segons en lloc de minuts. Compte: els secrets no es resolen en local tret que li passis credencials, així que exporta valors de prova.

3. La sessió de depuració interactiva. Quan la fallada només passa a CodeBuild —i passa—, posa codebuild-breakpoint com a ordre just abans de la que falla: la construcció s'atura allà i espera. Llança-la amb --debug-session-enabled i connecta amb Session Manager des de la consola. Et trobes dins del contenidor, al punt exacte, amb el codi clonat i les variables resoltes; codebuild-resume continua. Requereix permisos d'SSM al rol de servei, i la construcció continua facturant mentre esperes: no deixis una sessió oberta a l'hora de dinar.

4. Les variables que CodeBuild et dóna, que solen resoldre el dubte abans que res: CODEBUILD_RESOLVED_SOURCE_VERSION (el SHA exacte construït), CODEBUILD_WEBHOOK_TRIGGER (què ho va disparar: branch/main, pr/42, tag/v1.5.0), CODEBUILD_BUILD_SUCCEEDING (imprescindible a post_build), CODEBUILD_BUILD_ID i CODEBUILD_SRC_DIR.

Mètriques, alarmes i cost real

CodeBuild publica mètriques a AWS/CodeBuild. Les tres que importen són FailedBuilds (alarma: ≥ 3 en 1 hora, o 1 de sola si és main), Duration (p90 > 8 min) i SucceededBuilds per a la taxa d'èxit.

aws cloudwatch put-metric-alarm --alarm-name mercadofresco-construcciones-fallidas \
  --namespace AWS/CodeBuild --metric-name FailedBuilds --statistic Sum \
  --dimensions Name=ProjectName,Value=build-mercadofresco-tienda \
  --period 3600 --evaluation-periods 1 --threshold 3 \
  --comparison-operator GreaterThanOrEqualToThreshold --treat-missing-data notBreaching \
  --alarm-actions arn:aws:sns:eu-west-1:111122223333:alertas-mercadofresco \
  --profile mercadofresco-dev --region eu-west-1

--treat-missing-data notBreaching és important: sense construccions no hi ha dades, i no voldràs una alarma sonant cada nit. És la mateixa lliçó de 05-01.

Cost real de MercadoFresco al mes:

Concepte Càlcul Cost
Construccions de PR i branques 20/dia × 4,2 min × 22 dies × 0,010 18,48 USD
Integració nocturna (a la VPC) + trànsit NAT 1/dia × 9 min × 30 × 0,010 + 9 GB 3,13 USD
Artefactes a S3 amb caducitat de 90 dies ~4 GB 0,09 USD
Registres de CloudWatch ~2 GB ingerits 1,15 USD
Total ≈ 22,85 USD/mes

Vint-i-tres dòlars al mes per eliminar «funciona al meu portàtil» del vocabulari de l'equip. Compara-ho amb un desplegament trencat un divendres a les 19:00 amb 900 comandes/hora en joc.

Neteja: delete-project, delete-report-group --delete-reports i delete-log-group. Els grups de registre no s'esborren en esborrar el projecte i continuen facturant emmagatzematge; posa'ls retenció amb aws logs put-retention-policy --retention-in-days 30 des del primer dia.

Errors Habituals i Consells

Publicar l'artefacte sense comprovar CODEBUILD_BUILD_SUCCEEDING. post_build s'executa encara que build falli, així que puges a S3 el paquet d'una construcció les proves de la qual van fallar. És l'error més perillós de la lliçó.

Posar secrets en variables PLAINTEXT, que queden a la definició del projecte i a CloudTrail; o oblidar :clau a la referència a Secrets Manager, amb què la variable rep el JSON sencer i l'aplicació falla amb un error que no apunta a la causa. I fer servir set -x amb secrets: l'emmascarament és coincidència de cadenes i així que transformes el valor surt en clar.

CodeBuild en una subxarxa pública. Sense IP pública no hi ha sortida a internet i pip install es penja fins al temps d'espera. Subxarxes privades amb NAT, sempre. I no fiquis totes les construccions a la VPC «per si de cas»: pagues 30-60 s d'ENI a cadascuna més el trànsit del NAT.

Baixar el llindar de cobertura per desbloquejar una PR. Es baixa una vegada i ja no torna a pujar. I reintentar una prova intermitent fins que passi ensenya l'equip que el vermell no significa res, així que el dia que sigui real també es reintentarà.

Desar site-packages a la memòria cau en lloc de ~/.cache/pip. Arrossegues versions antigues i depurar-ho porta hores. I no posar retenció als grups de registre: facturen per sempre, fins i tot després d'esborrar el projecte.

Consell: ordena les portes de més ràpida a més lenta. Una fallada de format ha de fallar en 2 segons, no després de 4 minuts de proves.

Consell: fes que el buildspec sigui executable en local amb codebuild_build.sh i la imatge oficial; si només funciona dins de CodeBuild, cada iteració de depuració costa minuts. Exporta la versió amb exported-variables perquè CodePipeline (08-04) la faci servir a les etapes següents, i posa un timeout-in-minutes ajustat: és el fre que evita pagar 60 minuts per una construcció penjada.

Exercicis

Exercici 1: l'artefacte que no hauria d'existir

El divendres a les 18:40, el Luis veu a mercadofresco-artefactos el fitxer tienda/1.5.2-c7a91f3/mercadofresco-tienda-1.5.2-c7a91f3.zip, publicat a les 18:32. Però a CodeBuild la construcció c7a91f3 apareix en vermell: van fallar 3 proves de tests/unitarias/test_pagos.py.

Respon: (a) com és possible que existeixi l'artefacte si la construcció va fallar; (b) què ho ha permès i com es corregeix; (c) per què és perillós més enllà d'aquest cas, tenint en compte el que farà CodePipeline a 08-04; (d) quina comprovació posaries perquè un artefacte així no es pugui desplegar; (e) quina alarma hauria avisat la Marta a les 18:35.

Exercici 2: la construcció de 22 minuts

La construcció triga 22 minuts: install 4 min (140 paquets i psycopg2 compilat des de les fonts), pre_build 3 min (pip-audit, bandit, ruff i git-secrets en sèrie), build 14 min (620 proves unitàries en sèrie, 40 d'integració contra el clon d'Aurora i l'empaquetatge), post_build 1 min. El projecte és a la VPC, en SMALL, sense memòria cau. El Luis ha començat a saltar-se la construcció local.

Proposa un pla que baixi el temps per sota dels 6 minuts. Per a cada mesura indica l'estalvi estimat, l'efecte en el cost i què es perd. Digues explícitament quina aplicaries primer i per què.

Exercici 3: el secret que va sortir als registres

La Sara, revisant els registres d'una construcció, troba aquesta línia a /aws/codebuild/build-mercadofresco-tienda:

[pre_build] Connectant a postgresql://mfadmin:V3rd3_Manzana_2026@aurora-mf-pruebas-luis...

El secret està declarat correctament a env.secrets-manager i CodeBuild l'emmascara a la sortida directa. A pre_build hi ha aquestes dues línies:

      - export CADENA_CONEXION="postgresql://mfadmin:${PASS_AURORA}@${HOST_AURORA_PRUEBAS}:5432/mf"
      - echo "Connectant a ${CADENA_CONEXION}"

Respon: (a) per què no ha funcionat l'emmascarament; (b) què fas els primers 30 minuts, en ordre; (c) com corregeixes el buildspec; (d) els registres fa 6 mesos que tenen retenció indefinida i aquesta línia apareix en 340 construccions: com ho abordes; (e) quin control automàtic afegiries per detectar-ho la propera vegada.

Solucions

Solució 1

(a) Perquè post_build s'executa encara que build falli. És deliberat —permet publicar informes de proves fallides— però significa que les ordres de publicació que hi posis s'executen igualment: les proves van fallar a build, la fase va avortar, i post_build va pujar el ZIP tan tranquil.

(b) Falta la guarda de CODEBUILD_BUILD_SUCCEEDING: el buildspec culpable té un aws s3 cp sense condició a post_build. La correcció és la que sí que apareix al buildspec de la lliçó:

  post_build:
    commands:
      - |
        if [ "${CODEBUILD_BUILD_SUCCEEDING}" != "1" ]; then
          echo "Construccio fallida: no es publica artefacte"; exit 1
        fi
      - aws s3 cp mercadofresco-tienda-*.zip s3://${BUCKET_ARTEFACTOS}/tienda/${VERSION_APP}/

(c) Perquè trenca la garantia de la qual depèn tota la resta: que un artefacte publicat és un artefacte que va passar les proves. A 08-04 el pipeline prendrà l'artefacte d'una etapa i el passarà a la següent; si a més algú desplega per nom de fitxer des de S3, es desplegaria codi amb tres proves de pagaments trencades. I seria silenciós: el ZIP existeix, té bon aspecte i el seu nom no diu res de la seva procedència. La confiança en el sistema es perd sencera amb un sol cas així.

(d) Dues capes barates. Metadades a l'objecte--metadata estado=exitosa,commit=...— i una comprovació al desplegament que rebutgi el que no les tingui. I, més robust, separar responsabilitats: que la construcció no publiqui res i sigui el mecanisme natiu (artifacts:) el que lliuri el paquet a CodePipeline, que només avança si l'etapa anterior va acabar bé. La regla general: si la publicació és un efecte secundari d'un script, algun dia s'executarà quan no tocava; si és una transició d'estat del pipeline, no pot passar fora d'ordre.

(e) L'alarma mercadofresco-construcciones-fallidas sobre FailedBuilds, amb llindar baix —1 en 5 minuts per a main— i destinació alertas-mercadofresco: el llindar de 3 en 1 hora serveix per detectar una tendència, però a main una sola fallada mereix avís immediat. Complementàriament, una regla d'EventBridge sobre CodeBuild Build State Change amb build-status: FAILED avisa en segons amb l'enllaç directe als registres.

Solució 2

# Mesura Estalvi Cost Què es perd
1 Treure el projecte de la VPC; build-mercadofresco-integracion a part, nocturn ~7 min Baixa: menys NAT i ENI Retroalimentació immediata contra Aurora real
2 pytest -n auto amb MEDIUM ~7 min Puja el preu/min, baixa el total Res, si les proves estan aïllades
3 Memòria cau de pip + psycopg2-binary en lloc de compilar ~3 min Cap La roda precompilada, acceptable
4 Escanejos alhora ~2 min Igual en minuts totals Registres més difícils de llegir
5 gitCloneDepth: 1 ~30 s Cap git describe per a la versió
6 pytest-split en 3 construccions en lots ~2 min Els mateixos minuts, en paral·lel Complexitat de configuració

Primer, la mesura 1, i la justificació és la clau de l'exercici: és la que més temps estalvia i l'única que a més redueix el cost. Les 40 proves contra el clon d'Aurora aporten valor, però no a cada push: l'aporten abans de fusionar cap a main i a l'execució nocturna. Amb el 90 % de les construccions fora de la VPC desapareixen els 30-60 s d'ENI, el trànsit del NAT i bona part de la lentitud de xarxa. És també la de menys risc: no canvia ni una prova.

Segon, la mesura 2, contraintuïtiva i molt rendible: passar de SMALL a MEDIUM duplica el preu per minut però redueix el total, perquè 620 proves amb -n auto sobre 4 vCPU gairebé divideixen per quatre el temps de la bateria. El requisit és que estiguin aïllades: si comparteixen una SQLite o un directori temporal fix, la paral·lelització les farà fallar de manera intermitent —justament el problema del qual parlàvem—, i llavors l'arranjament és aïllar-les, no tornar a la sèrie.

Resultat: install 4 → 1 min, pre_build 3 → 1, build 14 → 3, post_build 1. Uns 6 minuts, amb cost per construcció gairebé igual i menys factura de NAT. I la conseqüència que no és a la taula i és la més important: amb 6 minuts, el Luis deixa de saltar-se la construcció.

Solució 3

(a) Perquè l'emmascarament és una substitució literal de la cadena del secret a la sortida, no una anàlisi semàntica. El buildspec interpola ${PASS_AURORA} dins d'una cadena més gran; el resultat és un valor nou que CodeBuild no coneix, així que en fer echo no troba cap coincidència que emmascarar i l'imprimeix sencer. És el primer dels tres casos: transformar el valor trenca l'emmascarament.

(b) Els primers 30 minuts, en ordre. Rotar la contrasenya de mfadmin de proves, perquè sempre es comença per tallar la validesa del que s'ha filtrat. Determinar qui l'ha pogut llegir, amb CloudTrail buscant GetLogEvents i FilterLogEvents sobre aquest grup en els últims 6 mesos; l'abast depèn de quanta gent tingui lectura sobre CloudWatch Logs, que sol ser més de la que un es pensa. Comprovar si afecta producció —i aquí es veu el valor de la separació de prefixos del rol: CodeBuild no pot llegir mercadofresco/produccion/rds/mfadmin, així que l'incident queda acotat a proves—. I corregir el buildspec abans de la següent construcció, o el registre se seguirà escrivint.

(c) No imprimir mai la cadena completa: si necessites traçar, traça només el que no és sensible (echo "Connectant a ${HOST_AURORA_PRUEBAS}:5432/mf com a mfadmin"). La millora de fons és una altra: si l'aplicació llegeix el secret de Secrets Manager amb el seu propi rol, el valor no passa mai per una variable d'entorn del shell i desapareix tota aquesta classe de fuites. La variable d'entorn és còmoda, però és també la superfície per on s'escapen els secrets.

(d) Tracta els registres històrics com a dades compromeses: exporta el grup a S3 si cal conservar-lo per auditoria, esborra els fluxos afectats —no hi ha edició parcial a CloudWatch Logs— i posa retenció de 30 dies. Com que la contrasenya ja està rotada a (b), l'exposició residual no dóna accés a res: esborrar-los és higiene i compliment, no contenció. Si el secret hagués estat de producció, a més caldria valorar la notificació interna que vam veure a 08-01.

(e) Un filtre de mètrica de CloudWatch Logs sobre /aws/codebuild/* que compti coincidències de patrons com postgresql://*:*@, AKIA o sk_live_, amb alarma cap a alertas-mercadofresco. És millor que una comprovació dins del buildspec perquè funciona encara que ningú no se'n recordi de mantenir-la i cobreix tots els projectes, presents i futurs. És la idea de 05-01: si una dada no hauria d'aparèixer mai en un registre, posa una mètrica que la compti i alarma així que passi de zero.

Conclusió

«Funciona al meu portàtil» ja no significa res a MercadoFresco. Cada push arrenca un contenidor net que no sap res del psycopg2 que el Luis va instal·lar a mà el 2024: instal·la les dependències declarades, executa 214 proves, comprova que la cobertura no baixa del 75 %, escaneja les 87 dependències buscant CVE, busca credencials filtrades i produeix un artefacte versionat i immutable a mercadofresco-artefactos. El que es desplegui serà aquest ZIP, amb el seu commit i les seves metadades.

Coneixes l'anatomia d'un projecte —origen, entorn, rol de servei, buildspec, artefactes, memòria cau i registres— i saps que la mida de còmput cal mesurar-la i no suposar-la, perquè MEDIUM pot sortir més barat que SMALL quan la construcció sap fer servir els quatre nuclis. Saps que el rol de servei l'executa codi que canvia a cada commit, i que per això el seu abast es limita al prefix mercadofresco/pruebas/: una construcció no necessita mai credencials de producció. Domines el buildspec.yml, l'ordre de les fases i les dues trampes que enxampen tothom: que post_build s'executa encara que build falli —d'aquí la guarda de CODEBUILD_BUILD_SUCCEEDING, sense la qual publiques artefactes de construccions trencades— i que les portes s'ordenen de més ràpida a més lenta.

Saps injectar secrets amb la sintaxi secret:clau:etiqueta i —més important— per què l'emmascarament es trenca així que transformes el valor o l'interpoles en una cadena més gran. Tens proves que verifiquen el que de debò importa, com que la passarel·la es va cridar exactament una vegada davant d'un missatge duplicat, i els reports que converteixen un XML de JUnit en un històric consultable. I tens la disciplina que sosté tot això: una prova intermitent s'investiga o s'esborra, mai no es reintenta; el llindar de cobertura només puja; i una comprovació que no estàs disposat que aturi un desplegament no és una porta, és decoració.

Saps quan n'hi ha prou amb moto —el 90 % dels casos, en un segon i sense cost— i quan cal el clon aurora-mf-pruebas-luis, amb l'advertiment que comporta: CodeBuild a la VPC costa 30-60 segons d'ENI per construcció i el trànsit del NAT, i per això MercadoFresco té dos projectes, un de ràpid a fora i un d'integració a dins. I saps depurar sense endevinar: els registres, la reproducció local amb la imatge oficial i codebuild-breakpoint per entrar al contenidor al punt exacte. Tot per uns 23 dòlars al mes.

Però hi ha una cosa que aquesta lliçó no ha canviat. L'artefacte és allà, verificat, esperant en un bucket. I per portar-lo a les instàncies de l'ASG asg-mercadofresco-tienda, el Luis continua fent el mateix que el primer dia: entrar per SSH, copiar el ZIP, descomprimir-lo, reiniciar el servei i mirar el web amb els dits creuats. Durant els quaranta segons que triga, la instància serveix errors; si n'hi ha dues i les fa en sèrie, la meitat del trànsit veu una versió i l'altra meitat una altra; i si el ZIP resulta estar trencat, la tornada enrere consisteix a buscar l'anterior i repetir el ritual amb la botiga caiguda. L'artefacte és bo; la manera de posar-lo en producció continua sent un ritual manual sense xarxa de seguretat.

A 08-03, «AWS CodeDeploy», això es resol. Veurem les tres destinacions —EC2, Lambda i ECS— i quines estratègies admet cadascuna; els conceptes d'aplicació, grup de desplegament, revisió i configuració de desplegament, amb l'agent instal·lat a les instàncies de l'ASG; l'appspec.yml i els seus ganxos del cicle de vida un a un, amb els scripts reals de MercadoFresco per aturar el servei, escalfar la memòria cau i comprovar /salud; les estratègies al lloc amb AllAtOnce, HalfAtATime i OneAtATime, el blue/green amb els grups de destinació de l'ALB, i el canari i lineal per desplegar la Lambda mercadofresco-cobrar-pago; l'advertiment sobre migracions d'esquema i per què mai no han d'anar al mateix pas que el codi; i sobretot la peça que tanca el quart problema del curs: la reversió automàtica quan salta mercadofresco-alb-latencia-alta o falla un ganxo, sense que ningú estigui mirant.

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