La lliçó anterior va acabar amb una pregunta implícita: si per tenir una API disponible i elàstica cal muntar un conjunt d'escalat, un balancejador, sondes, regles d'autoescalat, pedaços del sistema operatiu i certificats a mà… no hi haurà res que faci tot això per tu? Sí que n'hi ha, i es diu Azure App Service.
Contoso Airlines té dues aplicacions noves que no arrosseguen deute del passat: Contoso Reserves, la web pública on el client busca vols i compra el seu bitllet, i l'API de Disponibilitat, el servei intern que consulta places i preus. Totes dues són codi modern (Java per a l'API, Node.js per a la web) que en Diego Salas pot empaquetar i desplegar sense dependre del sistema operatiu. Per a elles, mantenir màquines virtuals seria feina regalada: pedaços, agents, certificats i desplegaments manuals que no aporten ni un cèntim al negoci.
En aquesta lliçó aprendràs què és App Service, com funcionen els seus plans i per què es factura el pla i no l'aplicació, com desplegar codi amb Azure CLI, com configurar l'aplicació amb ajustos i cadenes de connexió, com posar-hi el domini propi de Contoso amb certificat gestionat, i com publicar versions noves sense tallar el servei fent servir ranures de desplegament. Recorda que al mòdul 1 ja va quedar anunciada l'aplicació app-contoso-reservas-pro: aquí la creem de debò.
Avís de cost: el nivell Free (F1) és gratuït i serveix per a gairebé tots els exercicis. Els nivells Basic, Standard i Premium es facturen per hora mentre el pla existeixi, encara que l'aplicació no rebi ni una petició. Al final tens la neteja.
Contingut
- Què és App Service i per què Contoso el tria
- Plans d'App Service: nivells, Linux i Windows
- Piles de temps d'execució admeses
- Crear el pla i les aplicacions amb Azure CLI
- Desplegar codi: ZIP deploy i desplegament des de Git
- Configuració: ajustos d'aplicació i cadenes de connexió
- Dominis personalitzats i certificats TLS gestionats
- Ranures de desplegament i intercanvi amb escalfament
- Escalat vertical, horitzontal i automàtic
- Diagnòstic: registres, seqüència de registre i consola SSH
- Integració amb la xarxa virtual (introducció)
- Neteja
- Errors Comuns i Consells
- Exercicis
- Conclusió
- Què és App Service i per què Contoso el tria
Azure App Service és una plataforma com a servei (PaaS) per allotjar aplicacions web, API i aplicacions mòbils de back-end. Tu lliures el codi o l'artefacte; Azure s'ocupa del sistema operatiu, del servidor web, del temps d'execució, del balanceig entre instàncies i del certificat TLS.
Comparat amb el que vas muntar a la lliçó anterior:
| Tasca | Amb VM i VMSS | Amb App Service |
|---|---|---|
| Pedaçar el sistema operatiu | Teva | D'Azure |
| Instal·lar i actualitzar el temps d'execució (JDK, Node) | Teva | D'Azure (tries la versió) |
| Balancejar entre instàncies | Load Balancer que muntes i pagues | Inclòs |
| Escalat automàtic | Regles sobre el conjunt d'escalat | Regles sobre el pla (més simple) |
| Certificat TLS | Compra, instal·lació i renovació manuals | Gestionat i renovat per Azure |
| Desplegament sense caigudes | El dissenyes tu | Ranures amb intercanvi, incloses |
| Registres i consola | Agents que instal·les | Integrats al servei |
| Control del sistema operatiu | Total | Cap |
L'última fila és la contrapartida: a App Service no hi ha accés d'administrador al servidor, no pots instal·lar dimonis arbitraris ni dependre de rutes fora de l'espai de la teva aplicació. Per això el motor de disponibilitat heretat continua en una VM (lliçó 02-01) i les aplicacions noves van aquí.
Decisió registrada de Contoso Airlines:
app-contoso-reservas-pro: web pública de venda, Node.js sobre Linux.app-contoso-api-disponibilidad-pro: API interna de places i preus, Java sobre Linux.- Totes dues al mateix pla de producció al principi; l'API se separa al seu propi pla quan el pic de l'obertura de temporada ho justifiqui (ho veuràs a l'exercici 1).
- Plans d'App Service: nivells, Linux i Windows
El concepte més important i el que més factures sorpresa provoca: el pla d'App Service és el conjunt de màquines on s'executen les teves aplicacions. Es factura el pla, no l'aplicació.
Conseqüències directes:
- Deu aplicacions en un pla costen el mateix que una: el que pagues és el pla.
- Una aplicació aturada en un pla de pagament continua costant, perquè el pla continua existint. Per deixar de pagar cal esborrar el pla (o baixar-lo a Free).
- Les aplicacions d'un mateix pla comparteixen CPU, memòria i instàncies. Si una consumeix la CPU, les altres ho noten.
| Nivell | Ús previst | Instàncies | Ranures | Domini propi i TLS | Escalat automàtic | Notes |
|---|---|---|---|---|---|---|
| Free (F1) | Proves i aprenentatge | 1 compartida, quota diària de CPU | No | No | No | Gratis, sense SLA, s'adorm |
| Basic (B1–B3) | Desenvolupament i aplicacions petites | Fins a 3, dedicades | No | Sí | Manual | Sense ranures: no hi ha desplegament sense caigudes |
| Standard (S1–S3) | Producció general | Fins a 10 | 5 | Sí | Sí | El primer nivell realment apte per a producció |
| Premium v3 (P0v3–P5v3) | Producció exigent | Fins a 30 | 20 | Sí | Sí | Més CPU i memòria per instància, zones de disponibilitat, més entrades i sortides de xarxa |
| Isolated v2 | Aïllament i compliment estrictes | Fins a 100 | 20 | Sí | Sí | S'executa a la teva pròpia xarxa (App Service Environment). Car |
Què desbloqueja cada salt, dit sense embuts:
- De Free a Basic: instàncies dedicades, el teu propi domini i TLS, i que l'aplicació no s'adormi.
- De Basic a Standard: ranures de desplegament i escalat automàtic. És el salt que converteix una joguina en un servei de producció.
- De Standard a Premium v3: maquinari més ràpid, més instàncies, redundància de zona i millors límits de xarxa. És el nivell que exigeix la política de Contoso de tenir els components crítics en dues zones.
Linux davant de Windows
| Aspecte | Pla Linux | Pla Windows |
|---|---|---|
| Piles | Java, Node, Python, PHP, .NET, Go (contenidor) | .NET Framework, .NET, Java, Node, PHP |
| Preu | Lleugerament inferior en nivells equivalents | Lleugerament superior |
| .NET Framework clàssic (4.x) | No | Sí (és la seva raó de ser) |
| Contenidors propis | Sí (detall a 06-01) | Limitat |
| Barrejar Linux i Windows al mateix pla | No es pot: són plans diferents |
Contoso tria Linux per a les dues aplicacions: no hi ha res de .NET Framework clàssic, el preu és menor i les piles de Node i Java estan perfectament admeses.
- Piles de temps d'execució admeses
App Service executa el teu codi sobre una pila de temps d'execució que tries en crear l'aplicació i pots canviar després. Consulta les disponibles amb:
# Totes les piles disponibles per a aplicacions web a Linux.
az webapp list-runtimes --os-type linux --output tableSortida abreujada i la seva lectura:
[
"JAVA:21-java21",
"JAVA:17-java17",
"NODE:22-lts",
"NODE:20-lts",
"PYTHON:3.12",
"PHP:8.3",
"DOTNETCORE:8.0"
]El format és PILA:VERSIO. Dos avisos importants:
- Les versions tenen fi de suport: quan una versió de Node o Java surt del suport de la comunitat, Azure la retira de la llista i avisa abans. Planifica actualitzacions; no descobreixis el final de suport el dia que falla un desplegament.
- Si la teva pila o versió no és a la llista (per exemple, Go o una versió antiga molt concreta), la sortida és un contenidor propi, i això es tracta a la lliçó 06-01.
- Crear el pla i les aplicacions amb Azure CLI
Fem servir primer l'entorn de desenvolupament, amb nivell gratuït, perquè puguis seguir la lliçó sense cost.
#!/usr/bin/env bash
set -euo pipefail
GRUP="rg-contoso-reservas-dev"
REGIO="westeurope"
PLA="plan-contoso-reservas-dev"
APP_WEB="app-contoso-reservas-dev"
APP_API="app-contoso-api-disponibilidad-dev"
ETIQUETES=(entorno=desarrollo proyecto=contoso-reservas centro-coste=CC-1042
[email protected])
# 1. Pla d'App Service: Linux, nivell gratuit.
az appservice plan create \
--resource-group "${GRUP}" \
--name "${PLA}" \
--location "${REGIO}" \
--is-linux \
--sku F1 \
--tags "${ETIQUETES[@]}" \
--output table
# 2. Web de reserves sobre Node.js 22.
az webapp create \
--resource-group "${GRUP}" \
--plan "${PLA}" \
--name "${APP_WEB}" \
--runtime "NODE:22-lts" \
--tags "${ETIQUETES[@]}" \
--output table
# 3. API de Disponibilitat sobre Java 21, al mateix pla.
az webapp create \
--resource-group "${GRUP}" \
--plan "${PLA}" \
--name "${APP_API}" \
--runtime "JAVA:21-java21" \
--tags "${ETIQUETES[@]}" \
--output tableDetalls que importen:
--is-linuxdefineix el sistema operatiu del pla, no de l'aplicació. No es pot canviar després: si t'equivoques, cal crear un altre pla.- El nom de l'aplicació és globalment únic, perquè genera el nom d'amfitrió
app-contoso-reservas-dev.azurewebsites.net. Si algú al món l'ha pres, falla. Per això Contoso fa servir un prefix propi d'organització. - Les dues aplicacions comparteixen pla: el cost no canvia per afegir-hi la segona.
- Al nivell F1 no pots activar
--https-only… en realitat sí que pots, i has de fer-ho:
# Forcar HTTPS: qualsevol peticio HTTP es redirigeix a HTTPS.
az webapp update \
--resource-group "${GRUP}" \
--name "${APP_WEB}" \
--https-only true \
--output none
# Exigir TLS 1.2 com a minim (valor recomanat; 1.3 on estigui disponible).
az webapp config set \
--resource-group "${GRUP}" \
--name "${APP_WEB}" \
--min-tls-version 1.2 \
--output noneEl domini *.azurewebsites.net ja ve amb certificat TLS vàlid, així que la teva aplicació és accessible per HTTPS des del primer segon.
- Desplegar codi: ZIP deploy i desplegament des de Git
ZIP deploy: el mètode directe
És el més utilitzat en scripts i canalitzacions: empaquetes l'aplicació i la puges.
# Aplicacio Node minima que retorna l'estat de la web de reserves.
mkdir -p contoso-reservas && cd contoso-reservas
cat > index.js <<'EOF'
const http = require('http');
const port = process.env.PORT || 8080;
const versio = process.env.VERSION_APP || 'desconeguda';
http.createServer((req, res) => {
if (req.url === '/salud') {
res.writeHead(200, { 'Content-Type': 'application/json' });
return res.end(JSON.stringify({ servei: 'contoso-reserves', estat: 'ok', versio }));
}
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(`<h1>Contoso Reserves</h1><p>Versió ${versio}</p>`);
}).listen(port);
EOF
cat > package.json <<'EOF'
{
"name": "contoso-reservas",
"version": "1.0.0",
"main": "index.js",
"scripts": { "start": "node index.js" }
}
EOF
zip -r ../contoso-reservas.zip . && cd ..
# Desplegament del paquet.
az webapp deploy \
--resource-group rg-contoso-reservas-dev \
--name app-contoso-reservas-dev \
--src-path contoso-reservas.zip \
--type zipTres coses fonamentals d'aquest codi, perquè són les que fallen a tothom el primer cop:
- El port ve a
process.env.PORT. App Service injecta aquesta variable i espera que la teva aplicació hi escolti. Si escoltes en un port fix, veuràs l'error «Application Error» sense cap més pista. - L'aplicació ha d'escoltar a totes les interfícies, no només a
127.0.0.1. - App Service necessita saber com arrencar-la. Amb Node fa servir
npm startoindex.js; si el teu punt d'entrada és un altre, defineix-lo:
az webapp config set \
--resource-group rg-contoso-reservas-dev \
--name app-contoso-reservas-dev \
--startup-file "node index.js" \
--output nonePer a Java, l'artefacte és un .jar o .war:
az webapp deploy \
--resource-group rg-contoso-reservas-dev \
--name app-contoso-api-disponibilidad-dev \
--src-path api-disponibilidad.jar \
--type jarDesplegament des de Git
App Service inclou un repositori Git local al qual pots empènyer codi; cada git push dispara una compilació i un desplegament.
# 1. Habilitar el repositori Git local i obtenir l'URL de desti.
URL_GIT=$(az webapp deployment source config-local-git \
--resource-group rg-contoso-reservas-dev \
--name app-contoso-reservas-dev \
--query url --output tsv)
# 2. Credencials de publicacio d'ambit d'usuari (un cop per compte).
az webapp deployment user set --user-name contoso-despliegue
# 3. Afegir el remot i empenyer.
git remote add azure "${URL_GIT}"
git push azure main:masterTambé es pot connectar a GitHub per desplegar a cada confirmació d'una branca. És còmode per començar, però per a producció el camí correcte són les canalitzacions d'Azure Pipelines, amb els seus entorns i aprovacions: això és el mòdul 5, i no ho desenvolupem aquí.
Comprova el resultat:
- Configuració: ajustos d'aplicació i cadenes de connexió
Una aplicació ben feta no porta la configuració dins del codi. A App Service hi ha dos mecanismes, i tots dos arriben al teu procés com a variables d'entorn.
| Mecanisme | Per a què | Com ho veu l'aplicació |
|---|---|---|
| Ajustos d'aplicació (app settings) | Qualsevol paràmetre: URL, modes, temps d'espera, versions | Variable d'entorn amb el mateix nom |
| Cadenes de connexió (connection strings) | Connexions a bases de dades, amb tipus (SQLAzure, MySQL, PostgreSQL, Custom) | Variable amb prefix segons el tipus, per exemple SQLAZURECONNSTR_ |
# Ajustos d'aplicacio de la web de reserves.
az webapp config appsettings set \
--resource-group rg-contoso-reservas-dev \
--name app-contoso-reservas-dev \
--settings VERSION_APP=1.4.0 \
ENTORNO=desarrollo \
URL_API_DISPONIBILIDAD="https://app-contoso-api-disponibilidad-dev.azurewebsites.net" \
TIEMPO_ESPERA_MS=3000 \
--output table
# Cadena de connexio a la base de dades de reserves (modul 3).
az webapp config connection-string set \
--resource-group rg-contoso-reservas-dev \
--name app-contoso-reservas-dev \
--connection-string-type SQLAzure \
--settings ReservasDb="Server=tcp:sql-contoso-reservas-dev.database.windows.net;Database=db-reservas;Authentication=Active Directory Default;" \
--output nonePunts clau que has de recordar:
- Canviar un ajust reinicia l'aplicació. No és instantani ni transparent: agrupa'ls i aplica'ls junts.
- Els ajustos substitueixen els del fitxer de configuració de la teva aplicació amb el mateix nom. És el mecanisme per tenir el mateix artefacte en desenvolupament i producció.
- Cada ranura de desplegament pot tenir els seus propis ajustos; pots marcar-los com a «de ranura» perquè no viatgin en intercanviar (apartat 8).
Per què NO es posen secrets aquí en producció
Els ajustos d'aplicació estan xifrats en repòs i no apareixen al codi, cosa que ja és millor que l'alternativa habitual. Però:
- Qualsevol amb permís de Col·laborador sobre l'aplicació els pot llegir en clar des del portal o amb
az webapp config appsettings list. - Queden exposats a exportacions de plantilles i a bolcats de configuració.
- No hi ha rotació automàtica, ni caducitat, ni auditoria d'accés individual a cada secret.
La solució correcta a Azure és Azure Key Vault, amb referències des de l'aplicació que apunten al secret en lloc de contenir-lo:
# Bestreta de la llico 04-03: el valor es una referencia, no el secret.
az webapp config appsettings set \
--resource-group rg-contoso-reservas-pro \
--name app-contoso-reservas-pro \
--settings CLAVE_PASARELA_PAGO="@Microsoft.KeyVault(SecretUri=https://kv-contoso-seguridad.vault.azure.net/secrets/clave-pasarela-pago/)" \
--output nonePerquè això funcioni, l'aplicació necessita una identitat administrada amb permís de lectura sobre el magatzem. Identitats administrades i RBAC són la lliçó 04-02; Key Vault, la 04-03. Contoso hi guarda la clau de la passarel·la de pagament i la cadena de connexió de producció, a rg-contoso-seguridad-pro. Aquí només t'has de quedar amb la regla: en desenvolupament, ajustos; en producció, referències a Key Vault.
- Dominis personalitzats i certificats TLS gestionats
Ningú no ven bitllets a app-contoso-reservas-pro.azurewebsites.net. Contoso fa servir el domini contosoairlines.example i vol la web a www.contosoairlines.example.
El procés té tres passos:
Pas 1: demostrar que el domini és teu. Es creen dos registres DNS al teu proveïdor (Azure DNS es veu a la lliçó 02-06):
| Tipus | Nom | Valor | Per a què |
|---|---|---|---|
CNAME |
www |
app-contoso-reservas-pro.azurewebsites.net |
Encaminar el trànsit |
TXT |
asuid.www |
Identificador de verificació de l'aplicació | Provar la propietat |
# Identificador de verificacio de domini de l'aplicacio.
az webapp show \
--resource-group rg-contoso-reservas-pro \
--name app-contoso-reservas-pro \
--query customDomainVerificationId \
--output tsvPas 2: associar el domini a l'aplicació.
az webapp config hostname add \
--resource-group rg-contoso-reservas-pro \
--webapp-name app-contoso-reservas-pro \
--hostname www.contosoairlines.examplePas 3: certificat TLS gestionat, gratuït i amb renovació automàtica.
# 1. Crear el certificat gestionat per App Service per a aquest nom d'amfitrio.
az webapp config ssl create \
--resource-group rg-contoso-reservas-pro \
--name app-contoso-reservas-pro \
--hostname www.contosoairlines.example
# 2. Obtenir-ne l'empremta digital i enllacar-lo amb SNI.
EMPREMTA=$(az webapp config ssl list \
--resource-group rg-contoso-reservas-pro \
--query "[?subjectName=='www.contosoairlines.example'].thumbprint" \
--output tsv)
az webapp config ssl bind \
--resource-group rg-contoso-reservas-pro \
--name app-contoso-reservas-pro \
--certificate-thumbprint "${EMPREMTA}" \
--ssl-type SNIEl que has de saber del certificat gestionat: és gratuït, es renova sol, requereix nivell Basic o superior, i no cobreix alguns casos (comodins en certes configuracions, dominis sense verificació pública). Per a aquests casos es puja un certificat propi o se'n fa servir un d'App Service Certificate. L'avantatge operatiu és enorme: els talls per certificats caducats deixen d'existir.
- Ranures de desplegament i intercanvi amb escalfament
Aquí hi ha, probablement, la funcionalitat que més justifica pagar el nivell Standard.
Una ranura de desplegament és una instància addicional de l'aplicació, dins del mateix pla, amb el seu propi nom d'amfitrió i la seva pròpia configuració. L'intercanvi (swap) canvia de lloc el contingut de dues ranures… sense reiniciar el procés ni tallar el trànsit.
graph LR
subgraph ABANS["Abans de l'intercanvi"]
P1["Ranura produccio<br/>versio 1.4.0<br/>← transit real"]
S1["Ranura preproduccion<br/>versio 1.5.0<br/>← proves internes"]
end
subgraph DESPRES["Despres de l'intercanvi"]
P2["Ranura produccio<br/>versio 1.5.0<br/>← transit real"]
S2["Ranura preproduccion<br/>versio 1.4.0<br/>← llesta per revertir"]
end
ABANS -->|"az webapp deployment slot swap"| DESPRES
GRUP="rg-contoso-reservas-pro"
APP="app-contoso-reservas-pro"
# 1. Crear la ranura de preproduccio clonant la configuracio de produccio.
az webapp deployment slot create \
--resource-group "${GRUP}" \
--name "${APP}" \
--slot preproduccion \
--configuration-source "${APP}" \
--output none
# 2. Desplegar la versio nova NOMES a la ranura.
az webapp deploy \
--resource-group "${GRUP}" \
--name "${APP}" \
--slot preproduccion \
--src-path contoso-reservas-1.5.0.zip \
--type zip
# 3. Provar la ranura a la seva propia URL, sense afectar els clients.
curl -s "https://${APP}-preproduccion.azurewebsites.net/salud"
# 4. Intercanviar: la versio provada passa a produccio.
az webapp deployment slot swap \
--resource-group "${GRUP}" \
--name "${APP}" \
--slot preproduccion \
--target-slot productionQuè fa exactament l'intercanvi (i per què no hi ha caiguda)
L'intercanvi no copia fitxers: canvia l'encaminament entre dos conjunts de treballadors ja en marxa. Abans de commutar, Azure executa un escalfament:
- Aplica a la ranura d'origen els ajustos de la ranura de destinació (els que no estan marcats com a «de ranura»).
- Reinicia els treballadors de la ranura amb aquesta configuració i espera que responguin.
- Només quan responen correctament, commuta l'encaminament.
Això elimina l'arrencada en fred que patiria el primer client després d'un desplegament clàssic. Pots controlar l'escalfament amb ajustos específics:
az webapp config appsettings set \
--resource-group "${GRUP}" --name "${APP}" --slot preproduccion \
--settings WEBSITE_SWAP_WARMUP_PING_PATH="/salud" \
WEBSITE_SWAP_WARMUP_PING_STATUSES="200" \
WEBSITE_WARMUP_PATH="/salud" \
--output noneAjustos de ranura
Alguns valors no han de viatjar en l'intercanvi: la cadena de connexió de la base de dades de proves no pot acabar en producció. Es marquen com a «de ranura» (slot setting):
az webapp config appsettings set \
--resource-group "${GRUP}" --name "${APP}" --slot preproduccion \
--slot-settings ENTORNO=preproduccion \
--output noneReversió i desplegament progressiu
- Revertir és tornar a intercanviar: la versió anterior continua viva a l'altra ranura. És la volta enrere més ràpida que existeix.
- Desplegament progressiu (canary): pots enviar un percentatge del trànsit real a la ranura abans d'intercanviar.
# El 10 % del transit real va a la ranura de preproduccio.
az webapp traffic-routing set \
--resource-group "${GRUP}" --name "${APP}" \
--distribution preproduccion=10
# Treure el repartiment quan acabi la prova.
az webapp traffic-routing clear --resource-group "${GRUP}" --name "${APP}"Un avís important: les ranures comparteixen el pla, és a dir, comparteixen CPU i memòria amb producció. Una prova de càrrega contra la ranura afecta els clients reals. Per a proves de càrrega serioses, pla a part.
- Escalat vertical, horitzontal i automàtic
A App Service s'escala el pla, no l'aplicació.
# Escalat vertical: canviar de nivell (mes CPU i memoria per instancia).
az appservice plan update \
--resource-group rg-contoso-reservas-pro \
--name plan-contoso-reservas-pro \
--sku P1v3
# Escalat horitzontal manual: nombre d'instancies.
az appservice plan update \
--resource-group rg-contoso-reservas-pro \
--name plan-contoso-reservas-pro \
--number-of-workers 4Escalat automàtic, amb la mateixa mecànica de regles que vas veure a 02-02 però sense conjunt d'escalat per administrar:
PLAN_ID=$(az appservice plan show \
-g rg-contoso-reservas-pro -n plan-contoso-reservas-pro --query id -o tsv)
az monitor autoscale create \
--resource-group rg-contoso-reservas-pro \
--resource "${PLAN_ID}" \
--name autoescala-plan-reservas \
--min-count 2 --max-count 10 --count 2 --output none
az monitor autoscale rule create \
--resource-group rg-contoso-reservas-pro \
--autoscale-name autoescala-plan-reservas \
--condition "CpuPercentage > 70 avg 5m" --scale out 2 --cooldown 5 --output none
az monitor autoscale rule create \
--resource-group rg-contoso-reservas-pro \
--autoscale-name autoescala-plan-reservas \
--condition "CpuPercentage < 30 avg 10m" --scale in 1 --cooldown 10 --output noneS'hi apliquen les mateixes regles d'or: pujar ràpid, baixar a poc a poc, banda morta ampla i perfil programat per a l'obertura de temporada. I el mateix requisit: l'aplicació no pot tenir estat local. Com que totes les instàncies d'un pla comparteixen el sistema de fitxers de l'aplicació (muntat des d'emmagatzematge), escriure-hi en calent és lent i fràgil: les targetes d'embarcament van a Blob Storage (lliçó 02-04) i les dades a la base de dades (mòdul 3).
Altres dues característiques del pla que convé conèixer:
- Always On: manté l'aplicació desperta. A Free i Basic l'aplicació es descarrega després d'una estona sense trànsit i la petició següent pateix una arrencada en fred. Activa'l en producció (
--always-on true, requereix Basic o superior). - Redundància de zona: disponible a Premium v3, distribueix les instàncies entre zones de disponibilitat. És l'opció que compleix la política de Contoso per a components crítics.
- Diagnòstic: registres, seqüència de registre i consola SSH
GRUP="rg-contoso-reservas-dev"
APP="app-contoso-reservas-dev"
# 1. Activar el registre d'aplicacio i del servidor web al sistema de fitxers.
az webapp log config \
--resource-group "${GRUP}" --name "${APP}" \
--application-logging filesystem \
--web-server-logging filesystem \
--detailed-error-messages true \
--failed-request-tracing true \
--level information \
--output none
# 2. Veure la sequencia de registre en temps real (Ctrl+C per sortir).
az webapp log tail --resource-group "${GRUP}" --name "${APP}"
# 3. Descarregar els registres per analitzar-los.
az webapp log download --resource-group "${GRUP}" --name "${APP}" --log-file registres.zipaz webapp log tail és l'eina de diagnòstic més rendible d'App Service: mostra en directe el que escriu la teva aplicació a la sortida estàndard. Si la teva aplicació no arrenca, allà en veuràs el motiu real (falta una dependència, el port és incorrecte, la variable d'entorn no existeix).
Consola dins del contenidor de l'aplicació:
# Sessio SSH contra la instancia (nomes plans Linux).
az webapp ssh --resource-group "${GRUP}" --name "${APP}"A dins hi trobaràs el teu codi a /home/site/wwwroot. Recorda: el que escriguis fora de /home es perd en reiniciar o en moure l'aplicació d'instància; és l'equivalent al disc temporal d'una VM.
Altres eines del servei, perquè sàpigues que existeixen:
- Diagnosticar i solucionar problemes al portal: detectors automàtics de caigudes, reinicis, ús de memòria i errors HTTP.
- Kudu (
https://<app>.scm.azurewebsites.net): la consola avançada del servei, amb explorador de fitxers, processos i registres de desplegament. - Application Insights: la telemetria real de l'aplicació (peticions, dependències, excepcions, rendiment). És la lliçó 07-03 i és el que Contoso acaba fent servir cada dia.
- Integració amb la xarxa virtual (introducció)
Per defecte, una Web App viu fora de la teva xarxa virtual: rep trànsit d'internet i surt a internet. Contoso necessita el contrari en dues direccions:
- Sortida: la web i l'API han d'arribar a la base de dades
sql-contoso-reservas-prosense passar per internet. Això es resol amb la integració amb xarxa virtual, que connecta la sortida de l'aplicació a una subxarxa delegada (snet-app). - Entrada: l'API de Disponibilitat no hauria de ser accessible des d'internet, sinó només des de la xarxa. Això es resol amb restriccions d'accés o amb un punt de connexió privat.
# Integracio de sortida amb una subxarxa delegada a App Service.
az webapp vnet-integration add \
--resource-group rg-contoso-reservas-pro \
--name app-contoso-reservas-pro \
--vnet vnet-contoso-pro \
--subnet snet-appHo deixem aquí a propòsit: el disseny de vnet-contoso-pro, les seves subxarxes, la delegació, els grups de seguretat de xarxa i els punts de connexió privats són el contingut complet de la lliçó 02-05, que ve d'aquí a dues lliçons.
- Neteja
# Esborrar les aplicacions i el pla (el pla es el que factura).
az webapp delete --resource-group rg-contoso-reservas-dev --name app-contoso-reservas-dev
az webapp delete --resource-group rg-contoso-reservas-dev --name app-contoso-api-disponibilidad-dev
az appservice plan delete --resource-group rg-contoso-reservas-dev --name plan-contoso-reservas-dev --yes
# Comprovar que no queden plans facturant a la subscripcio.
az appservice plan list --query "[].{Pla:name, Nivell:sku.name, Instancies:sku.capacity, Grup:resourceGroup}" --output tableHi insistim perquè és l'error de cost típic: esborrar l'aplicació no esborra el pla. Un pla P1v3 oblidat costa més de cent euros al mes sense servir ni una sola petició.
Errors Comuns i Consells
- Creure que es factura l'aplicació. Es factura el pla. Aturar l'aplicació no estalvia res; esborrar el pla (o baixar-lo a Free), sí.
- Esborrar aplicacions i deixar el pla viu. És la factura fantasma més habitual d'App Service.
- No escoltar a
process.env.PORT. Provoca «Application Error» sense explicació. És l'errada número u en desplegar Node o Python per primer cop. - Triar malament el sistema operatiu del pla. Linux i Windows no es barregen i el pla no es converteix: cal crear-ne un altre.
- Ficar secrets als ajustos d'aplicació en producció. Qualsevol col·laborador els llegeix en clar. Fes servir referències a Key Vault (04-03) amb identitat administrada (04-02).
- Canviar ajustos un a un en producció. Cada canvi reinicia l'aplicació. Agrupa'ls.
- Intentar desplegament sense caigudes en nivell Basic. No hi ha ranures fins a Standard. És la raó principal per pujar de nivell.
- Oblidar marcar com a «de ranura» els ajustos específics de l'entorn. En intercanviar, la configuració de preproducció acaba en producció. Passa, i fa mal.
- Fer proves de càrrega contra una ranura del pla de producció. Comparteixen CPU: perjudiques els clients reals.
- Deixar Always On desactivat en producció. El primer client després d'una estona de calma paga l'arrencada en fred.
- Consell: activa
--https-only truei--min-tls-version 1.2a totes les aplicacions, incloses les de desenvolupament. Costa dues ordres i evita una observació a la revisió de seguretat del mòdul 4. - Consell: anomena les aplicacions amb prefix d'organització (
app-contoso-…). El nom és global i els genèrics ja estan agafats.
Exercicis
Exercici 1: decidir plans i nivells
Contoso té quatre aplicacions: la web Contoso Reserves (pública, trànsit alt i estacional), l'API de Disponibilitat (interna, trànsit alt al pic), el tauler d'operacions del personal de terra (intern, 40 usuaris, horari d'oficina) i un portal de proves que en Diego fa servir per a demostracions.
- Quants plans d'App Service crearies i quines aplicacions posaries a cadascun? Justifica-ho.
- Quin nivell assignaries a cada pla i què desbloqueja aquest nivell?
- Quina configuració afegiries al pla de producció per complir la política de Contoso sobre components crítics?
Exercici 2: desplegament sense caigudes
Escriu la seqüència completa d'ordres d'Azure CLI per publicar la versió 1.5.0 de Contoso Reserves sense que cap client vegi un error:
- Crear la ranura
preproduccionclonant la configuració de producció. - Marcar
ENTORNOcom a ajust que no viatja en l'intercanvi. - Configurar l'escalfament contra
/salud. - Desplegar el ZIP a la ranura i verificar-la.
- Enviar el 10 % del trànsit real a la ranura durant la validació.
- Intercanviar i explicar com revertiries si alguna cosa va malament.
Exercici 3: diagnosticar una aplicació que no arrenca
En Diego desplega l'API de Disponibilitat i https://app-contoso-api-disponibilidad-dev.azurewebsites.net retorna «Application Error». Enumera, en ordre, els passos i les ordres que faries servir per trobar-ne la causa, i esmenta almenys tres causes probables amb la seva solució.
Solucions
Solució 1:
- Tres plans:
plan-contoso-reservas-pro: web de reserves. Se separa perquè el seu trànsit és el més alt i estacional i no volem que el seu pic afecti res més.plan-contoso-api-pro: API de Disponibilitat. Escala amb un perfil diferent (el pic de l'API és més agut que el de la web) i convé aïllar-la perquè una prova de càrrega o una fallada de la web no la degradi.plan-contoso-interno-pro: tauler d'operacions i portal de proves. Trànsit baix i previsible; comparteixen pla perquè el cost és el del pla i així només se'n paga un.
- Nivells:
- Els dos plans públics, Premium v3 (P1v3): ranures de desplegament, escalat automàtic, redundància de zona i millor rendiment per instància.
- El pla intern, Standard (S1): suficient per a 40 usuaris i ja inclou ranures i escalat automàtic.
- Redundància de zona als plans de producció (disponible a Premium v3), amb almenys 2 instàncies, per complir la política de «components crítics en almenys dues zones de disponibilitat». A més,
always-onactivat ihttps-onlya totes.
Solució 2:
#!/usr/bin/env bash
set -euo pipefail
GRUP="rg-contoso-reservas-pro"
APP="app-contoso-reservas-pro"
# 1. Ranura clonant la configuracio de produccio.
az webapp deployment slot create -g "${GRUP}" -n "${APP}" \
--slot preproduccion --configuration-source "${APP}" --output none
# 2. Ajust que NO viatja en l'intercanvi.
az webapp config appsettings set -g "${GRUP}" -n "${APP}" --slot preproduccion \
--slot-settings ENTORNO=preproduccion --output none
# 3. Escalfament contra el punt de salut.
az webapp config appsettings set -g "${GRUP}" -n "${APP}" --slot preproduccion \
--settings WEBSITE_SWAP_WARMUP_PING_PATH="/salud" \
WEBSITE_SWAP_WARMUP_PING_STATUSES="200" --output none
# 4. Desplegar i verificar la ranura.
az webapp deploy -g "${GRUP}" -n "${APP}" --slot preproduccion \
--src-path contoso-reservas-1.5.0.zip --type zip
curl -s "https://${APP}-preproduccion.azurewebsites.net/salud"
# 5. Desplegament progressiu: 10 % del transit real.
az webapp traffic-routing set -g "${GRUP}" -n "${APP}" --distribution preproduccion=10
# ... vigilar errors i latencia ...
az webapp traffic-routing clear -g "${GRUP}" -n "${APP}"
# 6. Intercanvi.
az webapp deployment slot swap -g "${GRUP}" -n "${APP}" \
--slot preproduccion --target-slot productionReversió: repetir la mateixa ordre d'intercanvi. Després del primer swap, la versió 1.4.0 va quedar a preproduccion, viva i escalfada, així que tornar enrere costa segons i no requereix tornar a desplegar res.
Solució 3:
# 1. El primer de tot, sempre: la sequencia de registre en directe.
az webapp log config -g rg-contoso-reservas-dev -n app-contoso-api-disponibilidad-dev \
--application-logging filesystem --level information --output none
az webapp log tail -g rg-contoso-reservas-dev -n app-contoso-api-disponibilidad-dev
# 2. Comprovar la configuracio d'arrencada i la pila.
az webapp config show -g rg-contoso-reservas-dev -n app-contoso-api-disponibilidad-dev \
--query "{Inici:appCommandLine, Pila:linuxFxVersion, AlwaysOn:alwaysOn}" -o json
# 3. Verificar que l'artefacte es on ha de ser.
az webapp ssh -g rg-contoso-reservas-dev -n app-contoso-api-disponibilidad-dev
# a dins: ls -la /home/site/wwwroot
# 4. Revisar els ajustos (falta alguna variable que l'aplicacio exigeix?).
az webapp config appsettings list -g rg-contoso-reservas-dev \
-n app-contoso-api-disponibilidad-dev -o tableTres causes probables i la seva solució:
| Causa | Símptoma al registre | Solució |
|---|---|---|
| L'aplicació escolta en un port fix | El contenidor no respon i App Service el reinicia en bucle | Escoltar a process.env.PORT (o server.port=${PORT} a Java) |
| Falta l'ordre d'arrencada o el nom de l'artefacte no és l'esperat | «no s'ha trobat el punt d'entrada» | az webapp config set --startup-file "java -jar /home/site/wwwroot/app.jar" |
| Falta una variable d'entorn obligatòria (per exemple, la cadena de connexió) | Excepció en inicialitzar el context de l'aplicació | Afegir-la amb az webapp config appsettings set (o referència a Key Vault en producció) |
Conclusió
Ja saps publicar aplicacions a Azure sense administrar servidors. Entens què és App Service i per què Contoso hi posa Contoso Reserves i l'API de Disponibilitat mentre el motor heretat es queda en una VM. Domines el concepte que més diners costa ignorar: es factura el pla, no l'aplicació, amb la seva taula de nivells i el que desbloqueja cada salt —Basic per tenir domini propi i TLS, Standard per a ranures i escalat automàtic, Premium v3 per a redundància de zona—. Saps triar pila de temps d'execució, crear pla i aplicacions amb CLI, i desplegar codi amb ZIP deploy i Git, amb els tres paranys del primer desplegament resolts (port, interfície i ordre d'arrencada). Configures l'aplicació amb ajustos i cadenes de connexió com a variables d'entorn, i saps per què els secrets de producció van a Key Vault per referència. Has posat un domini propi amb certificat gestionat i renovació automàtica, has publicat sense caigudes amb ranures, escalfament, desplegament progressiu i reversió immediata, saps escalar el pla vertical, horitzontal i automàticament, i tens les eines de diagnòstic (registre en directe, descàrrega de registres, SSH i Kudu) per quan alguna cosa no arrenqui.
Queda un cap per lligar, i és un cap amb nom. La teva aplicació no pot desar res en local: ni la sessió, ni els fitxers, ni les targetes d'embarcament en PDF que Contoso genera cada cop que algú compra un bitllet. Al mòdul 1 vas crear sttarjetascontosodev i el seu contenidor tarjetas-embarque, i vas deixar una decisió ajornada: quina redundància fer servir en desenvolupament i quina en producció.
La lliçó següent, Azure Storage: blobs, fitxers, cues i taules, recull aquest cap solt i el resol del tot: els quatre serveis d'un compte d'emmagatzematge, els tipus de blob i els nivells d'accés Hot, Cool, Cold i Archive amb les seves regles de cicle de vida —aplicats a unes targetes d'embarcament que es descarreguen molt la primera setmana i gairebé mai després—, la taula completa de redundància LRS, ZRS, GRS, GZRS i RA-GRS amb la decisió definitiva de Contoso, i com donar accés segur a un fitxer mitjançant signatures d'accés compartit temporals en lloc de repartir la clau del compte.
Curs d'Azure
Mòdul 1: Introducció a Azure
- Què és Azure?
- Models de servei, regions i zones de disponibilitat
- Crear i configurar el teu compte d'Azure
- Recorregut pel portal d'Azure
- Azure Resource Manager: subscripcions, grups de recursos i etiquetes
- Azure CLI, PowerShell i Cloud Shell
Mòdul 2: Serveis principals d'Azure
- Màquines virtuals d'Azure
- Escalat i alta disponibilitat del còmput
- Azure App Service
- Azure Storage: blobs, fitxers, cues i taules
- Xarxes a Azure: xarxes virtuals, subxarxes i NSG
- Connectivitat híbrida i lliurament global
Mòdul 3: Bases de dades d'Azure
- Triar el servei de dades adequat
- Azure SQL Database
- Azure Cosmos DB
- Azure Database for MySQL
- Azure Database for PostgreSQL
- Analítica de dades: Data Lake, Data Factory i Synapse
Mòdul 4: Seguretat a Azure
- Microsoft Entra ID i gestió d'identitats
- RBAC i identitats administrades
- Azure Key Vault
- Protecció DDoS i tallafoc d'aplicacions web
- Microsoft Defender for Cloud
- Governança i compliment amb Azure Policy
Mòdul 5: Azure DevOps
- Introducció a Azure DevOps
- Azure Repos
- Azure Pipelines: integració contínua
- Desplegament continu amb entorns i aprovacions
- Azure Artifacts
- Infraestructura com a codi amb Bicep
Mòdul 6: Serveis avançats d'Azure
- Contenidors a Azure: Container Registry i Container Apps
- Azure Kubernetes Service (AKS)
- Azure Functions
- Azure Logic Apps
- Missatgeria i esdeveniments: Service Bus, Event Grid i Event Hubs
- Serveis d'IA d'Azure
Mòdul 7: Monitoratge i gestió
- Azure Monitor: mètriques, alertes i taulers
- Log Analytics i consultes KQL
- Application Insights
- Azure Automation i runbooks
- Còpies de seguretat i recuperació davant desastres
Mòdul 8: Gestió i optimització de costos
- Calculadora de preus i estimació de costos
- Azure Cost Management: anàlisi, pressupostos i alertes
- Reserves, plans d'estalvi i Azure Hybrid Benefit
- Azure Advisor
- Estratègies d'optimització i cultura FinOps
