A la lliçó 02-03 vam fer un càlcul que va deixar la Marta en silenci: de la factura mensual d'S3 del catàleg de fotos, el 97 % no era emmagatzematge, era transferència de sortida. Cada vegada que un client de Sevilla obre la fitxa del tomàquet de branca, la foto viatja sencera des d'un centre de dades d'Irlanda fins al seu mòbil, i MercadoFresco paga per cada byte. Si el client recarrega la pàgina, es paga un altre cop. Si deu mil clients miren la mateixa foto, es paga deu mil vegades pel mateix fitxer.
I ara, després de muntar el balancejador a 03-03, hi ha un segon cobrament per GB: l'ALB també factura pel trànsit que processa.
Amazon CloudFront és la xarxa de distribució de contingut (CDN) d'AWS: uns 700 punts de presència repartits pel món que guarden una còpia del teu contingut a prop de qui la demana. El client de Sevilla rep la foto des de Madrid en comptes de des de Dublín; la petició no arriba ni a S3 ni a l'ALB; i la transferència de sortida de CloudFront té una capa gratuïta permanent d'1 TB al mes que cobreix sencera la demanda actual de MercadoFresco.
En aquesta lliçó la Marta posa CloudFront davant de tot i ataca directament el problema del cost, sense perdre de vista l'altra cosa que aporta una CDN i que sovint importa més: latència.
Contingut
- Què és una CDN i com funciona el repartiment des de la vora
- Encerts i fallades de memòria cau
- Distribucions i orígens
- Grups d'origen i commutació per error
- Comportaments de memòria cau i patrons de ruta
- La clau de memòria cau: polítiques de memòria cau i de sol·licitud d'origen
- TTL: mínim, màxim i per defecte
- Compressió, HTTP/2 i HTTP/3
- Origin Access Control: tancar el bucket al món
- Invalidacions davant del versionat de noms de fitxer
- Dominis propis i el parany del certificat a
us-east-1 - Contingut dinàmic a través de CloudFront cap a l'ALB
- CloudFront Functions i Lambda@Edge
- Registres, mètriques i taxa d'encerts
- Classes de preu i el càlcul d'estalvi de MercadoFresco
- Creació per CLI, invalidació i neteja
Què és una CDN i com funciona el repartiment des de la vora
Una CDN (Content Delivery Network) és una xarxa de servidors de memòria cau distribuïts geogràficament que se situen entre l'usuari i el servidor d'origen. CloudFront té tres nivells:
| Nivell | Quants | Què fa |
|---|---|---|
| Edge locations | ~700 en més de 100 ciutats | Atenen l'usuari i guarden el contingut més popular |
| Regional edge caches | ~13, més grans | Segon nivell de memòria cau: si falla l'edge, es pregunta aquí abans que a l'origen |
| Origen | El teu bucket S3, el teu ALB, o qualsevol servidor HTTP | La font de la veritat |
Les edge locations més properes als clients de MercadoFresco són Madrid i Marsella, amb sortida també per Londres i París. Un client de Sevilla que avui espera que la foto travessi 2.000 km fins a Dublín passarà a rebre-la des de Madrid, a 400 km.
El guany de latència és la meitat de l'argument i no s'ha de subestimar: una botiga que carrega mig segon més lenta perd conversions mesurables. L'altra meitat són els diners, i la veiem amb números al final de la lliçó.
Encerts i fallades de memòria cau
Tot el funcionament de CloudFront es redueix a aquest diagrama:
sequenceDiagram
participant C as Client<br/>(Sevilla)
participant E as Edge location<br/>(Madrid)
participant R as Regional edge cache<br/>(Frankfurt)
participant O as Origen<br/>mercadofresco-catalogo-fotos
Note over C,O: FALLADA DE MEMORIA CAU (primera peticio)
C->>E: GET /productos/tomate-rama.jpg
E->>E: El tinc? No (Miss)
E->>R: GET al segon nivell
R->>R: El tinc? No (Miss)
R->>O: GET a l'origen
O-->>R: 200 + imatge (transferencia GRATIS a CloudFront)
R-->>E: imatge (es desa)
E-->>C: imatge (es desa) · ~350 ms
Note over C,O: ENCERT DE MEMORIA CAU (peticions seguents)
C->>E: GET /productos/tomate-rama.jpg
E->>E: El tinc? Si (Hit)
E-->>C: imatge des de Madrid · ~25 ms
Tres coses que aquest diagrama ensenya i que convé fixar:
- Només el primer usuari paga l'espera llarga. Els següents reben la resposta des de la vora.
- La transferència de l'origen a CloudFront és gratuïta quan l'origen és S3 (i també des d'un ALB o EC2 al mateix compte). Aquesta és la clau econòmica de tota la lliçó.
- Existeix un segon nivell. Encara que l'edge de Madrid no el tingui, potser el té la regional edge cache, i l'origen s'estalvia la petició igualment. Això millora molt la taxa d'encerts real respecte del que es calcularia a ull.
Cada resposta porta la capçalera X-Cache, que diu exactament què ha passat:
Valor de X-Cache |
Significat |
|---|---|
Hit from cloudfront |
Servit des de l'edge, sense tocar l'origen |
Miss from cloudfront |
No hi era: s'ha demanat a l'origen |
RefreshHit from cloudfront |
Havia caducat, l'origen ha respost 304 Not Modified |
Error from cloudfront |
L'origen ha fallat |
Distribucions i orígens
Una distribució és la unitat de configuració de CloudFront. En crear-la, AWS assigna un nom de
domini propi, del tipus d111111abcdef8.cloudfront.net, i desplega la configuració a totes les
edge locations en uns minuts.
Dins d'una distribució es declaren un o diversos orígens. MercadoFresco en necessita dos:
Origen (Id) |
Tipus | Domini | Què serveix |
|---|---|---|---|
origen-fotos-s3 |
S3 amb OAC | mercadofresco-catalogo-fotos.s3.eu-west-1.amazonaws.com |
Fotos de productes i miniatures |
origen-tienda-alb |
Personalitzat | alb-mercadofresco-tienda-1234567890.eu-west-1.elb.amazonaws.com |
HTML, API, tot el dinàmic |
La diferència entre els dos tipus d'origen no és cosmètica:
| Origen S3 | Origen personalitzat (ALB, EC2, servidor extern) | |
|---|---|---|
| Protocol cap a l'origen | Intern d'AWS | HTTP o HTTPS, configurable |
| Accés restringit | Origin Access Control (OAC) | Capçalera secreta + grup de seguretat |
| Reenviament de capçaleres | Limitat | Complet |
| Mètodes permesos | Només GET, HEAD, OPTIONS |
Tots, inclosos POST i PUT |
| Temps d'espera | Fixos | Ajustables (OriginReadTimeout) |
Un matís que confon: si configures un bucket d'S3 com a lloc web estàtic (el mode que vam veure
a 02-03, amb el seu propi domini .s3-website-), CloudFront el tracta com a origen personalitzat,
no com a origen S3, i llavors no pots fer servir OAC. Per a MercadoFresco fem servir el punt d'enllaç REST
d'S3 amb OAC, que és el correcte.
Grups d'origen i commutació per error
Un grup d'origen aparella dos orígens: un de primari i un de secundari. Si el primari retorna un dels codis d'error configurats, CloudFront reintenta automàticament contra el secundari, de manera transparent per al client.
{
"Quantity": 1,
"Items": [
{
"Id": "grupo-fotos-con-respaldo",
"FailoverCriteria": {
"StatusCodes": { "Quantity": 4, "Items": [500, 502, 503, 504] }
},
"Members": {
"Quantity": 2,
"Items": [
{ "OriginId": "origen-fotos-s3" },
{ "OriginId": "origen-fotos-s3-respaldo" }
]
}
}
]
}Només funciona amb GET, HEAD i OPTIONS, i els criteris poden incloure a més 403 i 404. Per a
MercadoFresco té sentit el dia que es repliqui el catàleg a un bucket d'una altra regió; avui és
una configuració preparada, no activa. La commutació per error a nivell de DNS, que és un
mecanisme diferent i complementari, s'estudia a la lliçó 03-05.
Comportaments de memòria cau i patrons de ruta
Un comportament de memòria cau (cache behavior) associa un patró de ruta amb un origen i amb un conjunt de regles. És l'equivalent a les regles de l'ALB, però a la vora.
MercadoFresco en defineix quatre:
| Prec. | Patró | Origen | Mètodes | Política de memòria cau | Per què |
|---|---|---|---|---|---|
| 0 | /productos/* |
origen-fotos-s3 |
GET, HEAD | Memòria cau llarga (1 any) | Les fotos no canvien: el nom porta versió |
| 1 | /miniaturas/* |
origen-fotos-s3 |
GET, HEAD | Memòria cau llarga (1 any) | Generades per Lambda, immutables |
| 2 | /api/* |
origen-tienda-alb |
Tots | CachingDisabled |
Dades de comandes: mai no es desen a la memòria cau |
| (defecte) | * |
origen-tienda-alb |
GET, HEAD, OPTIONS | Memòria cau curta (60 s) | HTML del catàleg |
Regles d'avaluació, molt semblants a les de l'ALB:
- Els comportaments s'avaluen per ordre de precedència i guanya el primer que coincideix.
- El comportament per defecte (
*) s'avalua sempre l'últim, sense excepció. - Els patrons admeten
*i?, i distingeixen majúscules de minúscules.
El comportament de /api/* mereix atenció: cal permetre tots els mètodes HTTP
(GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE) perquè, si no, un client que confirmi una comanda amb
POST rebria un 403 de CloudFront. I cal desactivar la memòria cau explícitament: desar a la memòria cau una
resposta de /api/pedidos/4711 i servir-la a un altre client seria una fuita de dades greu.
La clau de memòria cau: polítiques de memòria cau i de sol·licitud d'origen
Aquesta secció és la que separa una CDN que estalvia diners d'una que no serveix de res.
La clau de memòria cau és el conjunt de dades amb què CloudFront identifica un objecte desat. Per defecte és només la ruta de l'URL. Però s'hi poden afegir capçaleres, galetes i cadenes de consulta. I aquí hi ha el parany:
Cada valor diferent de qualsevol element de la clau de memòria cau crea una entrada diferent a la memòria cau.
Un exemple aritmètic que ho deixa clar. Suposa que inclous a la clau de memòria cau la capçalera
User-Agent, que té milers de valors diferents:
| Elements a la clau de memòria cau | Entrades per a UNA foto | Taxa d'encerts |
|---|---|---|
| Només la ruta | 1 | ~95 % |
Ruta + Accept-Encoding |
2 (gzip, br) | ~93 % |
Ruta + CloudFront-Viewer-Country |
~30 | ~70 % |
Ruta + User-Agent |
milers | ~5 % |
| Ruta + totes les galetes | Pràcticament una per usuari | ~0 % |
Amb User-Agent a la clau, CloudFront guarda una còpia diferent de la mateixa foto per a cada versió
de cada navegador. Gairebé totes les peticions són fallades, totes van a l'origen, i has pagat per una
CDN que no desa res a la memòria cau. És l'error més car i més freqüent de CloudFront.
Per distingir-ho bé, AWS separa dues polítiques:
| Política de memòria cau | Política de sol·licitud d'origen | |
|---|---|---|
| Què controla | Què forma la clau de memòria cau | Què es reenvia a l'origen |
| Efecte a la memòria cau | Cada valor crea una entrada nova | Cap |
| Quan fer-la servir | Només si el contingut canvia segons aquell valor | Si l'origen necessita aquella dada per funcionar |
El cas que aclareix la diferència: l'origen vol registrar el país del visitant als seus registres. Si
poses CloudFront-Viewer-Country a la política de memòria cau, multipliques les entrades per 30. Si el
poses a la política de sol·licitud d'origen, l'origen rep la dada a cada fallada de memòria cau i la
memòria cau continua tenint una sola entrada. La segona és la correcta.
Les polítiques gestionades per AWS cobreixen gairebé tot:
| Política gestionada | Clau de memòria cau | Quan |
|---|---|---|
CachingOptimized |
Només la ruta | Contingut estàtic: les fotos de MercadoFresco |
CachingOptimizedForUncompressedObjects |
Només la ruta, sense compressió | Fitxers ja comprimits (JPEG, vídeo) |
CachingDisabled |
No es desa res a la memòria cau | /api/* |
Elemental-MediaPackage |
Específica de vídeo | Streaming |
I una política pròpia, quan de debò cal variar per idioma:
{
"Name": "pol-cache-catalogo-mercadofresco",
"Comment": "HTML del cataleg: varia per idioma i per pagina",
"DefaultTTL": 60,
"MinTTL": 0,
"MaxTTL": 300,
"ParametersInCacheKeyAndForwardedToOrigin": {
"EnableAcceptEncodingGzip": true,
"EnableAcceptEncodingBrotli": true,
"HeadersConfig": {
"HeaderBehavior": "whitelist",
"Headers": { "Quantity": 1, "Items": ["Accept-Language"] }
},
"CookiesConfig": { "CookieBehavior": "none" },
"QueryStringsConfig": {
"QueryStringBehavior": "whitelist",
"QueryStrings": { "Quantity": 2, "Items": ["pagina", "categoria"] }
}
}
}Decisions d'aquesta política, una a una:
Accept-Languagea la llista blanca: el catàleg se serveix en castellà i en català, així que sí que canvia el contingut. Multiplica les entrades per 2, no per milers.CookieBehavior: none: les galetes de sessió no canvien l'HTML del catàleg. Incloure-les destruiria la memòria cau del tot.- Només dos paràmetres de consulta a la llista blanca:
paginaicategoriasí que canvien el contingut. Els paràmetres de campanyes de màrqueting (utm_source,utm_medium…) no, i si s'hi incloguessin, cada enllaç de cada campanya seria una entrada de memòria cau diferent del mateix HTML. EnableAcceptEncodingGzipiBrotli: CloudFront normalitza la capçalera i guarda les variants comprimides de manera intel·ligent, sense que comptin com a valors arbitraris.
TTL: mínim, màxim i per defecte
El TTL (Time To Live) és quant de temps guarda CloudFront un objecte abans de tornar a preguntar. Hi ha tres valors i la seva interacció amb les capçaleres de l'origen despista:
| Paràmetre | Què fa |
|---|---|
MinTTL |
Temps mínim que es guarda, encara que l'origen en demani menys |
DefaultTTL |
Temps que es fa servir si l'origen no envia Cache-Control |
MaxTTL |
Temps màxim, encara que l'origen en demani més |
La lògica completa:
- Si l'origen no envia
Cache-ControlniExpires→ s'aplicaDefaultTTL. - Si l'origen envia
Cache-Control: max-age=N→ es fa servirN, acotat entreMinTTLiMaxTTL. Cache-Control: no-storeoprivate→ no es desa a la memòria cau (llevat queMinTTLsigui més gran que 0, cas en què es desa igualment: una font clàssica de sorpreses).
Els valors de MercadoFresco:
| Contingut | MinTTL | DefaultTTL | MaxTTL | Cache-Control de l'origen |
|---|---|---|---|---|
Fotos /productos/* |
0 | 31.536.000 (1 any) | 31.536.000 | public, max-age=31536000, immutable |
Miniatures /miniaturas/* |
0 | 31.536.000 | 31.536.000 | public, max-age=31536000, immutable |
| HTML del catàleg | 0 | 60 | 300 | public, max-age=60 |
/api/* |
0 | 0 | 0 | no-store |
Un any de memòria cau per a les fotos sona temerari fins que s'entén la tècnica del versionat de noms, que veiem d'aquí a dos apartats. El correcte és posar la capçalera a l'objecte d'S3 en pujar-lo, perquè allà també l'aprofiten els navegadors:
aws s3 cp foto-nueva.jpg s3://mercadofresco-catalogo-fotos/productos/tomate-rama-v3.jpg \
--profile mercadofresco-dev --region eu-west-1 \
--cache-control "public, max-age=31536000, immutable" \
--content-type "image/jpeg"immutable és una directiva que diu al navegador que ni tan sols pregunti si ha canviat.
Elimina fins i tot les peticions de revalidació 304.
Compressió, HTTP/2 i HTTP/3
Tres ajustos que s'activen amb una casella i redueixen bytes i latència:
Compressió automàtica. Amb Compress: true, CloudFront comprimeix amb Gzip o Brotli les
respostes de tipus de contingut comprimibles (HTML, CSS, JavaScript, JSON, SVG) quan el client ho
admet, sempre que l'objecte pesi entre 1 KB i 10 MB. Brotli redueix un 15-20 % més que Gzip.
Advertència: no comprimeix JPEG, PNG ni MP4, que ja estan comprimits; intentar-ho només gastaria CPU.
HTTP/2 i HTTP/3. S'activen per distribució:
| Protocol | Avantatge | Estat |
|---|---|---|
| HTTP/1.1 | Universal | Compatibilitat |
| HTTP/2 | Multiplexat: moltes peticions en una connexió | Per defecte |
| HTTP/3 (QUIC) | Sobre UDP; sobreviu al canvi de xarxa i arrenca més ràpid | Cal activar-lo |
HTTP/3 importa especialment per a MercadoFresco: bona part dels seus clients naveguen des del mòbil, i al mòbil les connexions canvien d'antena i de wifi constantment. QUIC manté la sessió quan això passa; TCP ha de reconnectar.
Origin Access Control: tancar el bucket al món
Avui mercadofresco-catalogo-fotos té una política que permet s3:GetObject públic sota
productos/. Això vol dir que qualsevol pot saltar-se CloudFront i descarregar directament des
d'S3, i MercadoFresco paga la transferència cara. A més, fa possible el hotlinking: que una altra web
enllaci les fotos de MercadoFresco i li carregui la factura.
Origin Access Control (OAC) resol les dues coses: fa que només CloudFront pugui llegir del bucket, signant cada petició a l'origen amb SigV4.
OAC substitueix l'antic OAI (Origin Access Identity). Si trobes documentació amb OAI, està desactualitzada: OAI no admet el xifratge amb KMS (la nostra clau
alias/mercadofresco-datos), no funciona a totes les regions i no acceptaPOST/PUT. Per a tot el que sigui nou, OAC.
Creació del control d'accés:
OAC_ID=$(aws cloudfront create-origin-access-control \
--profile mercadofresco-dev \
--origin-access-control-config '{
"Name": "oac-mercadofresco-catalogo",
"Description": "Acces de CloudFront al bucket de fotos de MercadoFresco",
"SigningProtocol": "sigv4",
"SigningBehavior": "always",
"OriginAccessControlOriginType": "s3"
}' \
--query 'OriginAccessControl.Id' --output text)I la política del bucket, que és la peça essencial:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SoloCloudFrontPuedeLeerLasFotos",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::mercadofresco-catalogo-fotos/productos/*",
"arn:aws:s3:::mercadofresco-catalogo-fotos/miniaturas/*"
],
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/E2QWERTY123ABC"
}
}
},
{
"Sid": "DenegarTodoLoQueNoVayaCifrado",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::mercadofresco-catalogo-fotos",
"arn:aws:s3:::mercadofresco-catalogo-fotos/*"
],
"Condition": {
"Bool": { "aws:SecureTransport": "false" }
}
}
]
}El més important d'aquesta política, clàusula a clàusula:
- El principal és el servei
cloudfront.amazonaws.com, no una identitat d'usuari. - La condició
AWS:SourceArnés la part crítica: sense ella, qualsevol distribució de CloudFront de qualsevol compte d'AWS podria llegir el bucket. Restringeix el permís a la distribució concretaE2QWERTY123ABCdel compte111122223333. - Només es concedeix
s3:GetObject, i només sota els dos prefixos del catàleg. CloudFront no pot llistar el bucket ni escriure-hi res. - La segona clàusula, amb
Denyiaws:SecureTransport: false, rebutja qualsevol accés per HTTP sense xifrar. És una bona pràctica que convé tenir a tots els buckets.
El resultat, comparant l'abans i el després:
flowchart LR
subgraph ABANS["ABANS: bucket amb lectura publica"]
C1["Client"] -->|"paga transferencia cara"| S1[("mercadofresco-catalogo-fotos")]
C2["Web aliena<br/>(hotlinking)"] -->|"i tambe paga MercadoFresco"| S1
end
subgraph DESPRES["DESPRES: bucket tancat amb OAC"]
C3["Client"] --> CF["CloudFront<br/>E2QWERTY123ABC"]
CF -->|"signa SigV4<br/>transferencia gratuita"| S2[("mercadofresco-catalogo-fotos")]
C4["Acces directe a S3"] -.->|"403 Forbidden"| S2
end
Després cal treure l'antiga política pública i comprovar que el bloqueig d'accés públic (vist a 02-03) continua actiu:
aws s3api put-bucket-policy --profile mercadofresco-dev --region eu-west-1 \
--bucket mercadofresco-catalogo-fotos \
--policy file://politica-oac-catalogo.json
# Verificacio: l'acces directe ha de fallar ara amb 403
curl -s -o /dev/null -w "S3 directe: %{http_code}\n" \
https://mercadofresco-catalogo-fotos.s3.eu-west-1.amazonaws.com/productos/tomate-rama-v3.jpg
curl -s -o /dev/null -w "Per CloudFront: %{http_code}\n" \
https://d111111abcdef8.cloudfront.net/productos/tomate-rama-v3.jpgEl resultat esperat és 403 al primer i 200 al segon. Aquell parell d'ordres és la
verificació completa que OAC està ben muntat.
Un detall pràctic: les fotos estan xifrades amb la clau KMS alias/mercadofresco-datos (02-03).
La política d'aquella clau ha de permetre kms:Decrypt al servei de CloudFront; si no, totes les
peticions retornaran 403 i el missatge no serà gaire clar. KMS i les seves polítiques de clau
s'estudien a 04-02.
Invalidacions davant del versionat de noms de fitxer
El Luis substitueix la foto del tomàquet per una de millor i la puja amb el mateix nom. CloudFront continua servint l'antiga durant un any, perquè així ho diu el TTL. Hi ha dues maneres de resoldre-ho, i una és clarament millor.
Opció A: invalidació. Es diu a CloudFront que oblidi un objecte a totes les edge locations.
aws cloudfront create-invalidation --profile mercadofresco-dev \
--distribution-id E2QWERTY123ABC \
--paths "/productos/tomate-rama.jpg"
# Invalidar-ho tot (lent i car; nomes per a emergencies)
aws cloudfront create-invalidation --profile mercadofresco-dev \
--distribution-id E2QWERTY123ABC --paths "/*"Opció B: versionat del nom. Cada versió de la foto es puja amb un nom diferent:
tomate-rama-v1.jpg, tomate-rama-v2.jpg, tomate-rama-v3.jpg. L'HTML apunta a l'última, i com que
l'URL és nova, és una fallada de memòria cau neta. L'antiga caduca sola.
| Invalidació | Versionat del nom | |
|---|---|---|
| Temps fins a veure el canvi | 1-5 minuts (propagar a 700 edges) | Immediat |
| Cost | 1.000 rutes gratis al mes; després 0,005 USD per ruta | Zero |
| Tornada enrere | Impossible: el vell s'ha esborrat | Canviar l'HTML a v2 |
| Objectes ja descarregats pels navegadors | Continuen sent els vells | Es demanen de nou, URL diferent |
| Risc en un desplegament | Finestra d'inconsistència | Cap |
| Escalabilitat | Se satura amb desplegaments freqüents | Il·limitada |
La quarta fila és la decisiva i gairebé ningú no la veu venir: la invalidació neteja la memòria cau de
CloudFront, però no la del navegador del client. Si el navegador ha desat la foto amb
max-age=31536000, continuarà mostrant la vella durant un any passi el que passi. El versionat del
nom resol també això, perquè l'URL és diferent.
Per això MercadoFresco adopta el versionat, i les invalidacions queden reservades per a emergències —una foto pujada per error, un preu equivocat a l'HTML desat a la memòria cau.
Dominis propis i el parany del certificat a us-east-1
Per defecte la distribució respon a d111111abcdef8.cloudfront.net. Per fer servir
cdn.mercadofresco.example calen dues coses: declarar-lo com a nom de domini alternatiu
(CNAME) i aportar un certificat TLS que el cobreixi.
⚠️ El parany clàssic de CloudFront
El certificat d'ACM per a CloudFront ha d'estar SEMPRE a la regió
us-east-1(Nord de Virgínia), sigui quina sigui la regió on visquin els teus recursos.Això és així perquè CloudFront és un servei global i el seu pla de control és a
us-east-1(ho vam veure en parlar de serveis globals, regionals i zonals a 01-03). Un certificat emès aeu-west-1és perfectament vàlid per a l'ALB, però CloudFront ni tan sols el veurà a la llista desplegable, i el missatge d'error no explica per què.Conseqüència pràctica per a MercadoFresco: cal demanar dos certificats per al mateix domini.
# Certificat per a l'ALB: a la regio de l'ALB
aws acm request-certificate --profile mercadofresco-dev --region eu-west-1 \
--domain-name mercadofresco.example \
--subject-alternative-names "*.mercadofresco.example" \
--validation-method DNS
# Certificat per a CloudFront: OBLIGATORIAMENT a us-east-1
aws acm request-certificate --profile mercadofresco-dev --region us-east-1 \
--domain-name mercadofresco.example \
--subject-alternative-names "*.mercadofresco.example" \
--validation-method DNSTots dos són gratuïts i tots dos es renoven sols. Tots dos queden en PENDING_VALIDATION fins que es
creïn els registres CNAME de validació, cosa que farem a la lliçó 03-05.
A més, tota distribució hauria de forçar HTTPS:
| Ajust | Valor | Efecte |
|---|---|---|
ViewerProtocolPolicy |
redirect-to-https |
Qui entri per HTTP rep un 301 a HTTPS |
MinimumProtocolVersion |
TLSv1.2_2021 |
No s'accepten versions antigues de TLS |
OriginProtocolPolicy (ALB) |
https-only |
El tram CloudFront→ALB també va xifrat |
Contingut dinàmic a través de CloudFront cap a l'ALB
Una CDN serveix per a més que fitxers estàtics. Passar també l'HTML i l'API per CloudFront aporta coses fins i tot quan no es desa res a la memòria cau:
| Avantatge | Per què passa |
|---|---|
| Connexió TLS més propera | La salutació TLS es completa a Madrid, no a Dublín: s'estalvien diversos viatges d'anada i tornada |
| Connexions persistents a l'origen | CloudFront manté connexions obertes amb l'ALB i les reutilitza |
| Xarxa troncal d'AWS | De l'edge a l'origen es viatja per la xarxa privada d'AWS, més estable que internet |
| Un únic punt per a WAF i Shield | La protecció s'aplica a la vora, abans d'arribar a la VPC — 04-04 i 04-05 |
| Compressió i HTTP/3 de franc | Encara que l'origen no els admeti |
| Menys trànsit processat per l'ALB | Tot el que es pot desar a la memòria cau deixa de comptar com a LCU |
Quan no compensa: si l'aplicació és interna i tots els usuaris són a la mateixa regió que l'origen, CloudFront afegeix un salt sense guany. Per a MercadoFresco, amb clients per tot Espanya i plans d'obrir a Portugal, compensa clarament.
L'única precaució: per al comportament /api/* cal permetre tots els mètodes i reenviar a
l'origen les capçaleres que l'aplicació necessita (Authorization, Host, Content-Type) mitjançant
la política de sol·licitud d'origen AllViewerExceptHostHeader, sense ficar-les a la clau de memòria cau.
CloudFront Functions i Lambda@Edge
De vegades cal executar lògica a la vora: reescriure un URL, afegir capçaleres de seguretat, redirigir per país. CloudFront ofereix dos mecanismes molt diferents.
| CloudFront Functions | Lambda@Edge | |
|---|---|---|
| On s'executa | A l'edge location (les ~700) | A les regional edge caches (~13) |
| Llenguatge | JavaScript (ECMAScript 5.1 estricte) | Node.js o Python |
| Temps màxim | < 1 ms | 5 s (viewer) / 30 s (origin) |
| Memòria | 2 MB | 128-10.240 MB |
| Accés a la xarxa | No | Sí |
| Accés al cos de la petició | No | Sí |
| Pot cridar altres serveis d'AWS | No | Sí |
| Esdeveniments | Sol·licitud/resposta de visor | Sol·licitud/resposta de visor i d'origen |
| Cost | 0,10 USD per milió | 0,60 USD per milió + temps de còmput |
| Cas típic | Reescriptura d'URL, capçaleres, redireccions simples | Autenticació, crides a bases de dades, transformació d'imatges |
La regla: si cap a CloudFront Functions, va a CloudFront Functions. És sis vegades més barat, s'executa a més llocs i és ordres de magnitud més ràpid.
Exemple real de MercadoFresco: afegir capçaleres de seguretat a totes les respostes i normalitzar els URL del catàleg.
// funcio-capcaleres-seguretat.js
// Esdeveniment: viewer-response (s'executa just abans de retornar la resposta al client)
function handler(event) {
var resposta = event.response;
var capcaleres = resposta.headers;
// Forca HTTPS durant un any a tots els subdominis
capcaleres['strict-transport-security'] = {
value: 'max-age=31536000; includeSubDomains; preload'
};
// Impedeix que el navegador endevini el tipus de contingut
capcaleres['x-content-type-options'] = { value: 'nosniff' };
// Impedeix que la botiga es carregui dins d'un iframe alie (clickjacking)
capcaleres['x-frame-options'] = { value: 'DENY' };
// No envia l'URL completa com a referent a llocs externs
capcaleres['referrer-policy'] = { value: 'strict-origin-when-cross-origin' };
// Desactiva API del navegador que la botiga no fa servir
capcaleres['permissions-policy'] = {
value: 'geolocation=(), microphone=(), camera=()'
};
return resposta;
}I la reescriptura d'URL, a l'esdeveniment de sol·licitud de visor:
// funcio-normalitzar-url.js
// Esdeveniment: viewer-request (abans de mirar la memoria cau)
function handler(event) {
var peticio = event.request;
var uri = peticio.uri;
// /categoria/verduras -> /categoria/verduras/index.html
if (uri.endsWith('/')) {
peticio.uri = uri + 'index.html';
} else if (!uri.includes('.')) {
peticio.uri = uri + '/index.html';
}
// Elimina els parametres de campanya de la clau de memoria cau.
// Sense aixo, cada enllac de cada campanya de marqueting seria una entrada diferent
// de la MATEIXA pagina, i la taxa d'encerts s'enfonsaria.
var qs = peticio.querystring;
['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'fbclid', 'gclid']
.forEach(function (p) { delete qs[p]; });
return peticio;
}Aquest segon exemple té efecte econòmic directe: és una funció de quatre línies útils que recupera la taxa d'encerts que les campanyes de la Sara estaven destruint sense que ningú ho sabés.
Detall important sobre el moment d'execució: a viewer-request la funció s'executa abans
de consultar la memòria cau, així que la modificació de l'URI afecta la clau de memòria cau. Si s'executés
a origin-request, només es llançaria a les fallades de memòria cau i no canviaria res.
# Publicar i associar la funcio
aws cloudfront create-function --profile mercadofresco-dev \
--name mercadofresco-normalizar-url \
--function-config '{"Comment":"Normalitza URL i neteja parametres de campanya","Runtime":"cloudfront-js-2.0"}' \
--function-code fileb://funcio-normalitzar-url.js
aws cloudfront publish-function --profile mercadofresco-dev \
--name mercadofresco-normalizar-url --if-match "$ETAG"Registres, mètriques i taxa d'encerts
Registres estàndard. CloudFront aboca a S3 una línia per petició, amb el resultat de memòria cau inclòs:
# Es configuren dins de la distribucio
"Logging": {
"Enabled": true,
"IncludeCookies": false,
"Bucket": "mercadofresco-registros-web.s3.amazonaws.com",
"Prefix": "cloudfront/"
}Mètriques a CloudWatch (sempre a us-east-1, per ser un servei global):
| Mètrica | Què mesura | Objectiu a MercadoFresco |
|---|---|---|
Requests |
Peticions totals | — |
CacheHitRate |
% servit des de la memòria cau | > 90 % en fotos |
OriginLatency |
Temps de resposta de l'origen | < 300 ms |
4xxErrorRate |
Errors de client | < 1 % |
5xxErrorRate |
Errors de servidor | < 0,1 % |
TotalErrorRate |
Suma de tots dos | < 1 % |
BytesDownloaded |
Bytes servits | Base del càlcul de cost |
CacheHitRate és la mètrica que cal vigilar: si baixa, l'estalvi desapareix i l'origen es
carrega. Les causes més freqüents d'una taxa baixa són les que ja hem vist: massa elements a
la clau de memòria cau, TTL massa curt o Cache-Control mal posat a l'origen.
aws cloudwatch get-metric-statistics --profile mercadofresco-dev --region us-east-1 \
--namespace AWS/CloudFront --metric-name CacheHitRate \
--dimensions Name=DistributionId,Value=E2QWERTY123ABC Name=Region,Value=Global \
--start-time "$(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%SZ)" \
--end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--period 86400 --statistics Average \
--query 'sort_by(Datapoints,&Timestamp)[].{Dia:Timestamp,Encerts:Average}' --output tableEls taulers i les alarmes sobre aquestes mètriques es construeixen a la lliçó 05-01.
Classes de preu i el càlcul d'estalvi de MercadoFresco
Les classes de preu limiten des de quines edge locations se serveix, a canvi d'un preu menor:
| Classe | Regions incloses | Cost relatiu | Per a MercadoFresco |
|---|---|---|---|
PriceClass_All |
Totes, incloses Sud-amèrica, Austràlia, Índia | Més car | Innecessari avui |
PriceClass_200 |
Totes menys Sud-amèrica, Austràlia i Nova Zelanda | Intermedi | Innecessari avui |
PriceClass_100 |
Nord-amèrica, Europa i Israel | Més barat | L'elecció correcta |
Els clients de MercadoFresco són a Espanya i, properament, a Portugal: tots dos a Europa. Amb
PriceClass_100 es paga menys i l'experiència dels clients reals és idèntica. Qui sigui fora
continuarà sent atès, només que des d'una edge més llunyana.
El càlcul, amb els números de 02-03
Dades de partida del catàleg de MercadoFresco:
- 40 GB de fotos i miniatures a S3.
- 1.200.000 visualitzacions de foto al mes.
- Pes mitjà per foto servida: 250 KB → 300 GB de transferència mensual.
Situació actual, servint directament des d'S3:
| Concepte | Càlcul | Cost |
|---|---|---|
| Emmagatzematge | 40 GB × 0,023 USD/GB | 0,92 USD |
| Peticions GET | 1.200.000 × 0,0004 USD/1.000 | 0,48 USD |
| Transferència de sortida | 300 GB × 0,09 USD/GB | 27,00 USD |
| Total | 28,40 USD |
I aquí hi ha el 97 % de 02-03: 27,00 ÷ 28,40 = 95 %, que amb el trànsit dels mesos de campanya supera el 97 %.
Amb CloudFront al davant, suposant un 90 % d'encerts de memòria cau:
| Concepte | Càlcul | Cost |
|---|---|---|
| Emmagatzematge a S3 | 40 GB × 0,023 USD/GB | 0,92 USD |
| Transferència S3 → CloudFront | Gratuïta sempre | 0,00 USD |
| Peticions GET a S3 (només el 10 % de fallades) | 120.000 × 0,0004/1.000 | 0,05 USD |
| Transferència de sortida de CloudFront | 300 GB, dins de l'1 TB gratuït permanent | 0,00 USD |
| Peticions HTTPS de CloudFront | 1.200.000, dins dels 10 M gratuïts | 0,00 USD |
| Total | 0,97 USD |
Estalvi: 27,43 USD al mes, un 96,6 %. I a més les fotos se serveixen en uns 25 ms en comptes de 350 ms.
La capa gratuïta permanent de CloudFront (1 TB de sortida i 10 milions de peticions al mes, sense caducitat, no confondre amb la capa gratuïta de 12 mesos de 01-01) és el que fa que el resultat sigui tan rotund. Convé veure també què passa quan MercadoFresco creixi deu vegades:
| Escenari | Només S3 | Amb CloudFront | Estalvi |
|---|---|---|---|
| Avui: 300 GB, 1,2 M peticions | 28,40 USD | 0,97 USD | 96,6 % |
| ×10: 3 TB, 12 M peticions | 277 USD | 176 USD | 36,5 % |
| ×50: 15 TB, 60 M peticions | 1.383 USD | ~880 USD | 36 % |
L'estalvi percentual baixa en créixer, perquè la capa gratuïta deixa de ser significativa, però l'estalvi absolut puja. I a aquesta xifra cal sumar-hi el que es deixa de pagar en LCU de l'ALB pel trànsit que ja no el travessa, més la conversió que es guanya per servir cinc vegades més ràpid.
Creació per CLI, invalidació i neteja
La configuració d'una distribució és un JSON llarg. L'escrivim en un fitxer:
{
"CallerReference": "mercadofresco-catalogo-2026-08-02",
"Comment": "CDN del cataleg i la botiga de MercadoFresco",
"Enabled": true,
"PriceClass": "PriceClass_100",
"HttpVersion": "http2and3",
"IsIPV6Enabled": true,
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 2,
"Items": [
{
"Id": "origen-fotos-s3",
"DomainName": "mercadofresco-catalogo-fotos.s3.eu-west-1.amazonaws.com",
"OriginAccessControlId": "E1OACMERCADOFRESCO",
"S3OriginConfig": { "OriginAccessIdentity": "" }
},
{
"Id": "origen-tienda-alb",
"DomainName": "alb-mercadofresco-tienda-1234567890.eu-west-1.elb.amazonaws.com",
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "https-only",
"OriginSslProtocols": { "Quantity": 1, "Items": ["TLSv1.2"] },
"OriginReadTimeout": 30,
"OriginKeepaliveTimeout": 5
}
}
]
},
"DefaultCacheBehavior": {
"TargetOriginId": "origen-tienda-alb",
"ViewerProtocolPolicy": "redirect-to-https",
"AllowedMethods": {
"Quantity": 3,
"Items": ["GET", "HEAD", "OPTIONS"],
"CachedMethods": { "Quantity": 2, "Items": ["GET", "HEAD"] }
},
"Compress": true,
"CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6",
"OriginRequestPolicyId": "b689b0a8-53d0-40ab-baf2-68738e2966ac"
},
"CacheBehaviors": {
"Quantity": 2,
"Items": [
{
"PathPattern": "/productos/*",
"TargetOriginId": "origen-fotos-s3",
"ViewerProtocolPolicy": "redirect-to-https",
"AllowedMethods": {
"Quantity": 2,
"Items": ["GET", "HEAD"],
"CachedMethods": { "Quantity": 2, "Items": ["GET", "HEAD"] }
},
"Compress": false,
"CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6"
},
{
"PathPattern": "/api/*",
"TargetOriginId": "origen-tienda-alb",
"ViewerProtocolPolicy": "https-only",
"AllowedMethods": {
"Quantity": 7,
"Items": ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"],
"CachedMethods": { "Quantity": 2, "Items": ["GET", "HEAD"] }
},
"Compress": true,
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
}
]
},
"Logging": {
"Enabled": true,
"IncludeCookies": false,
"Bucket": "mercadofresco-registros-web.s3.amazonaws.com",
"Prefix": "cloudfront/"
}
}Els identificadors llargs són polítiques gestionades per AWS, iguals a tots els comptes:
658327ea-... és CachingOptimized, 4135ea2d-... és CachingDisabled i b689b0a8-... és la
política de sol·licitud d'origen AllViewer.
# Crear la distribucio
DIST_ID=$(aws cloudfront create-distribution --profile mercadofresco-dev \
--distribution-config file://distribucion-mercadofresco.json \
--query 'Distribution.Id' --output text)
# Etiquetar-la (CloudFront fa servir una ordre a part, amb ARN)
aws cloudfront tag-resource --profile mercadofresco-dev \
--resource "arn:aws:cloudfront::111122223333:distribution/$DIST_ID" \
--tags 'Items=[{Key=Proyecto,Value=mercadofresco},{Key=Entorno,Value=produccion},
{Key=Componente,Value=catalogo},{Key=Propietario,Value=marta},
{Key=CentroCoste,Value=marketing}]'
# El desplegament a les edge locations triga uns minuts
aws cloudfront wait distribution-deployed --profile mercadofresco-dev --id "$DIST_ID"
aws cloudfront get-distribution --profile mercadofresco-dev --id "$DIST_ID" \
--query 'Distribution.DomainName' --output textNota sobre el perfil: CloudFront és global, així que les seves ordres no porten --region; la CLI
fa servir us-east-1 internament.
Invalidació i seguiment:
INV_ID=$(aws cloudfront create-invalidation --profile mercadofresco-dev \
--distribution-id "$DIST_ID" --paths "/productos/tomate-rama.jpg" \
--query 'Invalidation.Id' --output text)
aws cloudfront get-invalidation --profile mercadofresco-dev \
--distribution-id "$DIST_ID" --id "$INV_ID" --query 'Invalidation.Status'⚠️ Cost i neteja
CloudFront no cobra per tenir una distribució: només per transferència i peticions, i els primers 1 TB i 10 M al mes són gratuïts de manera permanent. És, amb diferència, el servei més barat d'aquest mòdul, i una distribució de pràctiques amb trànsit de laboratori costa zero.
L'única cosa que pot sorprendre són les invalidacions: 1.000 rutes gratis al mes i 0,005 USD per ruta després. Invalidar
/*compta com una sola ruta, així que ni això és car; el dolent és invalidar 5.000 fitxers un a un a cada desplegament.Per esborrar-la cal desactivar-la primer i esperar que es desplegui el canvi:
ETAG=$(aws cloudfront get-distribution-config --profile mercadofresco-dev \\ --id "$DIST_ID" --query 'ETag' --output text) # Editar el JSON posant "Enabled": false i tornar a aplicar-lo aws cloudfront update-distribution --profile mercadofresco-dev --id "$DIST_ID" \\ --distribution-config file://distribucion-desactivada.json --if-match "$ETAG" aws cloudfront wait distribution-deployed --profile mercadofresco-dev --id "$DIST_ID" aws cloudfront delete-distribution --profile mercadofresco-dev --id "$DIST_ID" --if-match "$ETAG_NUEVO"I si esborres la distribució, recorda't de restaurar l'accés al bucket, o les fotos deixaran de servir-se del tot.
Una menció final: davant de CloudFront s'hi poden col·locar AWS Shield, que protegeix davant d'atacs de denegació de servei (lliçó 04-04), i AWS WAF, que filtra peticions malicioses per regles i per taxa (lliçó 04-05). Tots dos s'apliquen a la vora, abans que el trànsit arribi a la VPC, i aquest és precisament el motiu pel qual convé que tot el trànsit de MercadoFresco, estàtic i dinàmic, passi per CloudFront.
Errors Habituals i Consells
Ficar massa coses a la clau de memòria cau. És l'error car. User-Agent o totes les galetes enfonsen
la taxa d'encerts a gairebé zero i pagues una CDN que no desa res. Si l'origen necessita una dada però el
contingut no canvia amb ella, va a la política de sol·licitud d'origen, no a la de memòria cau.
Demanar el certificat de CloudFront a eu-west-1. Ha d'estar a us-east-1. Ni tan sols
apareixerà a la llista i perdràs mitja hora buscant-ne el motiu.
Invalidar a cada desplegament en comptes de versionar els noms. És més lent, costa diners, no neteja la memòria cau dels navegadors i no permet tornar enrere. Versiona el nom del fitxer.
Oblidar AWS:SourceArn a la política de l'OAC. Sense aquesta condició, qualsevol distribució de
CloudFront del món pot llegir el teu bucket. És una fallada de seguretat real i silenciosa.
Desar /api/* a la memòria cau. Servir a un client la resposta desada de la comanda d'un altre és una fuita de
dades. Fes servir CachingDisabled i permet tots els mètodes HTTP.
Posar TTL llargs sense Cache-Control a l'origen. El TTL de CloudFront no arriba al navegador. Si
vols que el client també ho desi, la capçalera ha d'estar a l'objecte d'S3.
No revisar CacheHitRate. Una distribució amb un 20 % d'encerts està mal configurada i ningú
se n'assabenta fins que arriba la factura. Mira-ho cada setmana.
Deixar els paràmetres de campanya a la clau de memòria cau. Cada utm_source diferent crea una entrada
nova del mateix HTML. Neteja'ls amb una CloudFront Function a viewer-request.
Fer servir Lambda@Edge per a alguna cosa que resol una CloudFront Function. Sis vegades més car, menys punts d'execució i molta més latència, per a res.
Consell d'or: després de cada canvi de configuració, comprova la capçalera X-Cache amb
curl -I dues vegades seguides. La primera ha de dir Miss; la segona, Hit. Si la segona continua
dient Miss, hi ha alguna cosa a la clau de memòria cau que no hi hauria de ser.
Exercicis
Exercici 1: dissenyar els comportaments de memòria cau d'una botiga completa
MercadoFresco afegeix tres tipus de contingut nous: /static/* (CSS i JavaScript amb nom
versionat), /pedidos/* (pàgines HTML personalitzades per usuari autenticat) i /buscar (cerca
amb paràmetre q, els resultats de la qual són iguals per a tots els usuaris). Dissenya el comportament de
memòria cau de cadascun: patró, origen, mètodes, política de memòria cau, TTL i justificació.
Exercici 2: diagnosticar una taxa d'encerts del 12 %
MercadoFresco porta un mes amb CloudFront i CacheHitRate està al 12 %. La factura d'S3 no ha
baixat. Enumera com a mínim cinc causes possibles, l'ordre o la comprovació que confirma cadascuna, i
la correcció.
Exercici 3: calcular el punt d'equilibri
La Sara vol saber a partir de quin volum de trànsit CloudFront deixa de sortir «de franc» i quant estalviaria si MercadoFresco obrís a Portugal i França i el trànsit es dupliqués. Calcula el cost mensual de servir 2 TB amb 4 milions de peticions, amb i sense CloudFront, i explica què canvia quan se supera la capa gratuïta.
Solucions
Solució 1
| Patró | Origen | Mètodes | Política de memòria cau | TTL | Justificació |
|---|---|---|---|---|---|
/static/* |
origen-fotos-s3 o l'ALB |
GET, HEAD | CachingOptimized + Compress: true |
Min 0 / Def 1 any / Max 1 any | El nom porta versió (app.a3f9c1.js), així que el contingut és immutable. La compressió és clau: CSS i JS es redueixen un 70-80 % amb Brotli |
/pedidos/* |
origen-tienda-alb |
Tots | CachingDisabled |
0 / 0 / 0 | Contingut personalitzat per usuari autenticat. Desar-lo a la memòria cau mostraria la comanda d'un client a un altre. A més cal reenviar Authorization i les galetes de sessió amb la política de sol·licitud d'origen AllViewer, sense ficar-les a la clau de memòria cau (que aquí no existeix) |
/buscar |
origen-tienda-alb |
GET, HEAD | Política pròpia: clau = ruta + paràmetre q únicament |
Min 0 / Def 300 / Max 3600 | El resultat sí que és igual per a tothom, així que es pot desar a la memòria cau: la cerca de «tomàquet» la fan centenars de clients. Només q a la clau; ni galetes ni utm_*. Cinc minuts són suficients per absorbir el pic sense mostrar preus obsolets |
El cas més instructiu és /buscar: és contingut dinàmic que es pot desar a la memòria cau perquè no
depèn de l'usuari. La distinció correcta no és «estàtic davant de dinàmic», sinó «igual per a
tothom davant de personalitzat». Una cerca popular servida des de la memòria cau estalvia una consulta a RDS
per cada encert, cosa que descarrega la base de dades a més de la xarxa.
Precedència: /static/*, /pedidos/* i /buscar abans que el comportament per defecte *. L'ordre
entre ells és indiferent perquè els patrons no se solapen.
Solució 2
Causa 1: elements innecessaris a la clau de memòria cau. La més probable amb diferència.
aws cloudfront get-cache-policy --profile mercadofresco-dev --id "$POLICY_ID" \
--query 'CachePolicy.CachePolicyConfig.ParametersInCacheKeyAndForwardedToOrigin'Cal buscar HeaderBehavior: whitelist amb capçaleres molt variables, CookieBehavior: all o
QueryStringBehavior: all. Correcció: passar tot el que l'origen necessiti però que no canviï el
contingut a la política de sol·licitud d'origen.
Causa 2: paràmetres de campanya. La Sara ha llançat una campanya i cada correu porta un utm_content
diferent. Es veu als registres d'accés, amb milers d'URL gairebé idèntics. Correcció: la
CloudFront Function de neteja de paràmetres.
Causa 3: l'origen envia Cache-Control: no-cache o max-age=0.
curl -I https://mercadofresco-catalogo-fotos.s3.eu-west-1.amazonaws.com/productos/tomate-rama-v3.jpgSi no apareix Cache-Control, l'objecte es va pujar sense la capçalera. Correcció: tornar a pujar amb
--cache-control, o aws s3 cp sobre si mateix amb --metadata-directive REPLACE.
Causa 4: TTL massa curt. Un DefaultTTL de 60 s a les fotos fa que la memòria cau caduqui
constantment. Es veu a get-cache-policy. Correcció: 1 any per a contingut versionat.
Causa 5: trànsit molt repartit geogràficament amb contingut poc popular. Cada edge location
té la seva pròpia memòria cau; si un objecte es demana un cop al mes des de cada ciutat, sempre serà una fallada.
Es confirma creuant els registres d'accés per x-edge-location. Correcció: PriceClass_100
concentra el trànsit en menys edges i millora la taxa d'encerts a més d'abaratir.
Causa 6, menys evident: el comportament per defecte * està capturant les fotos perquè el
patró /productos/* està mal escrit (per exemple, productos/* sense la barra inicial). Es
comprova amb X-Cache i amb l'x-edge-result-type dels registres.
Solució 3
Sense CloudFront, 2 TB (2.048 GB) i 4 M de peticions des d'S3:
| Concepte | Càlcul | Cost |
|---|---|---|
| Transferència de sortida | 2.048 GB × 0,09 USD/GB | 184,32 USD |
| Peticions GET | 4.000.000 × 0,0004/1.000 | 1,60 USD |
| Emmagatzematge | 40 GB × 0,023 | 0,92 USD |
| Total | 186,84 USD |
Amb CloudFront (PriceClass_100, 90 % d'encerts):
| Concepte | Càlcul | Cost |
|---|---|---|
| Transferència de CloudFront | El primer 1 TB de franc; els altres 1.024 GB × 0,085 | 87,04 USD |
| Peticions HTTPS | 4 M, dins dels 10 M gratuïts | 0,00 USD |
| Transferència S3 → CloudFront | Gratuïta | 0,00 USD |
| Peticions GET a S3 (10 % de fallades) | 400.000 × 0,0004/1.000 | 0,16 USD |
| Emmagatzematge | 40 GB × 0,023 | 0,92 USD |
| Total | 88,12 USD |
Estalvi: 98,72 USD al mes, un 53 %.
Què canvia en superar la capa gratuïta. Per sota d'1 TB, CloudFront és essencialment de franc i l'estalvi frega el 100 %. Per sobre, l'estalvi passa a dependre de dos factors estructurals que es mantenen sempre:
- La transferència de l'origen a CloudFront és gratuïta, així que S3 deixa de facturar sortida del tot, sigui quin sigui el volum.
- El preu per GB de CloudFront és menor que el d'S3 (0,085 davant de 0,09 USD/GB a Europa) i a més baixa per trams amb el volum: a partir de 10 TB, 50 TB i 150 TB el preu cau esglaonadament, mentre que el d'S3 és pràcticament pla.
El punt d'equilibri, per tant, no existeix: CloudFront és més barat que S3 directe en qualsevol volum, i l'única raó per no posar-lo seria que el contingut fos impossible de desar a la memòria cau i estigués consumit per un únic client a la mateixa regió. Aquest no és el cas d'una botiga.
Conclusió
MercadoFresco ha atacat el problema del cost per l'arrel. Saps què és una CDN, com funcionen
els tres nivells de CloudFront —edge locations, regional edge caches i origen— i què passa
exactament en un encert i en una fallada de memòria cau, inclosa la dada que ho canvia tot: la
transferència de l'origen a CloudFront és gratuïta. Saps llegir la capçalera X-Cache per saber en
quina situació estàs.
Has configurat una distribució amb dos orígens —el bucket mercadofresco-catalogo-fotos i
l'alb-mercadofresco-tienda de la lliçó anterior—, coneixes els grups d'origen per commutar
per error, i has repartit el trànsit en comportaments de memòria cau per patró de ruta, amb la
regla que guanya el primer que coincideix i el * va sempre l'últim. Sobretot, domines el
concepte que decideix si una CDN serveix d'alguna cosa: la clau de memòria cau. Saps que cada valor diferent
de cada element crea una entrada nova, que ficar-hi User-Agent o totes les galetes enfonsa la taxa
d'encerts al 5 %, i que la distinció correcta és entre la política de memòria cau (el que forma la
clau) i la política de sol·licitud d'origen (el que l'origen necessita rebre sense fragmentar la
memòria cau). Saps com interactuen MinTTL, DefaultTTL i MaxTTL amb el Cache-Control de l'origen, i
per què la capçalera s'ha de posar a l'objecte d'S3.
Has tancat el bucket amb Origin Access Control, amb una política que autoritza el servei
cloudfront.amazonaws.com únicament des de la distribució concreta gràcies a la condició
AWS:SourceArn —sense la qual qualsevol distribució del món podria llegir-lo—, i saps que OAC
substitueix l'antic OAI. Has comprovat amb dos curl que l'accés directe retorna 403 i el de
CloudFront 200. Saps per què el versionat de noms de fitxer és millor que les
invalidacions: és immediat, gratuït, reversible i neteja també la memòria cau del navegador. Coneixes
el parany del certificat a us-east-1 i saps que calen dos certificats, un per
regió. Has vist quan compensa passar també el contingut dinàmic per CloudFront, i has
distingit CloudFront Functions de Lambda@Edge, escrivint dues funcions reals: les
capçaleres de seguretat i la neteja de paràmetres de campanya que recupera la taxa d'encerts que
les campanyes de la Sara estaven destruint.
I els comptes: amb PriceClass_100, la capa gratuïta permanent d'1 TB i un 90 % d'encerts, el
cost mensual del catàleg passa de 28,40 USD a 0,97 USD, un 96,6 % menys, i les fotos se serveixen
en 25 ms en lloc de 350 ms. El problema del 97 % de transferència de sortida detectat a 02-03
està resolt, i l'ALB de 03-03 només processa ja el que de debò no es pot desar a la memòria cau.
Falta una sola cosa, i és la que fa que res d'això sigui visible per a un client real: el
domini. Ara mateix la botiga respon a d111111abcdef8.cloudfront.net i el balancejador a
alb-mercadofresco-tienda-1234567890.eu-west-1.elb.amazonaws.com. Ningú no teclejarà això. A més,
els dos certificats d'ACM que has demanat continuen en PENDING_VALIDATION esperant uns registres
DNS que encara no existeixen. A la lliçó 03-05, «Route 53», muntarem el DNS de MercadoFresco:
validarem els certificats, aprendrem què són els registres d'àlies i per què són l'única
manera d'apuntar el vèrtex mercadofresco.example a CloudFront, repassarem les polítiques
d'encaminament —ponderada per al canari del 10 %, geolocalització per obrir a Portugal, commutació
per error cap a una pàgina de manteniment— i tancarem el mòdul amb l'arquitectura de xarxa
completa.
Curs d'AWS
Mòdul 1: Introducció a AWS
- Què és AWS?
- Configuració del teu compte d'AWS
- Infraestructura global d'AWS
- Consola d'administració d'AWS
- AWS CLI i SDK
Mòdul 2: Serveis principals d'AWS
Mòdul 3: Xarxes i lliurament de contingut
- Amazon VPC
- Grups de seguretat i llistes de control d'accés
- Elastic Load Balancing
- Amazon CloudFront
- Route 53
Mòdul 4: Seguretat i identitat
- AWS Identity and Access Management (IAM)
- AWS Key Management Service (KMS)
- Secrets Manager i Parameter Store
- AWS Shield
- AWS WAF
Mòdul 5: Monitoratge i gestió
- Amazon CloudWatch
- AWS X-Ray i traçabilitat distribuïda
- AWS CloudTrail
- AWS Config
- AWS Trusted Advisor
Mòdul 6: Bases de dades
- Com triar la base de dades adequada
- Amazon DynamoDB
- Amazon Aurora
- Amazon Redshift
- Amazon ElastiCache
Mòdul 7: Integració d'aplicacions
- Amazon SQS
- Amazon SNS
- Amazon EventBridge
- AWS Step Functions
- Patrons d'integració: idempotència, reintents i cues de missatges fallits
