A la lliçó anterior vam recórrer la consola i vam crear el nostre primer bucket amb el ratolí. Va funcionar, però vam deixar una pregunta oberta: com repeteixes això mateix cent vegades, o com demostres d'aquí a sis mesos què vas fer exactament? La resposta és deixar de fer clic i començar a escriure comandes i codi.
Aquesta lliçó és la porta d'entrada a tota la feina seriosa a AWS. L'AWS CLI és l' eina que faràs servir cada dia per consultar, crear i diagnosticar; els SDK són les biblioteques amb les quals la teva aplicació parla amb AWS des de dins. Tots dos fan servir les mateixes APIs que la consola, així que tot el que aprenguis aquí et serveix per a qualsevol servei de la resta del curs.
Contingut
- Per què automatitzar: el problema de la consola
- Instal·lar AWS CLI v2 a Linux, macOS i Windows
- Anatomia d'una comanda
- Configurar credencials:
aws configure, fitxers i perfils - Ordre de precedència de les credencials
- Seguretat de les claus d'accés
- Formats de sortida i filtratge amb
--query - Paginació,
--dry-runi altres opcions útils - Comandes d'exploració imprescindibles
- SDK: què són i quins llenguatges hi ha
- boto3: l'SDK de Python pas a pas
- Una ullada equivalent en JavaScript
- CloudShell com a alternativa sense instal·lació
Per què automatitzar: el problema de la consola
La Marta va crear el bucket de proves a la consola. Ara en Luis necessita crear tres buckets iguals (un per entorn) amb les mateixes etiquetes i la mateixa configuració. Amb la consola hauria de repetir uns quinze clics tres vegades, i qualsevol descuit produiria una diferència silenciosa entre entorns.
Els quatre problemes estructurals de la consola:
| Problema | Conseqüència real a MercadoFresco |
|---|---|
| No és reproduïble | L'entorn de desenvolupament mai no acaba sent idèntic al de producció, i els errors "només passen en producció" |
| No és documentable | Ningú no pot revisar a Git el que es va fer amb el ratolí, ni saber per què |
| No és componible | No pots encadenar "llista totes les instàncies aturades i etiqueta-les" |
| No escala | Etiquetar 200 recursos a mà és inviable |
La CLI resol els quatre: una comanda és text, i el text es desa, es versiona, es revisa, es repeteix i s'encadena. I és el pas previ natural cap a la infraestructura com a codi del mòdul 9, on ja ni tan sols escriurem comandes sinó declaracions de l'estat desitjat.
Instal·lar AWS CLI v2 a Linux, macOS i Windows
Fes servir sempre la versió 2. La v1 està en manteniment, s'instal·lava amb pip (cosa que causava
conflictes de dependències) i li falten funcions importants com l'inici de sessió amb IAM
Identity Center.
Linux (x86_64)
# 1. Descarrega l'instal·lador oficial en un fitxer zip
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
# 2. Descomprimeix el paquet al directori actual
unzip awscliv2.zip
# 3. Executa l'instal·lador amb permisos d'administrador
sudo ./aws/install
# 4. Neteja els fitxers temporals
rm -rf awscliv2.zip aws/Què fa cada línia:
curl ... -o "awscliv2.zip": descarrega el paquet i el desa amb aquest nom. L'URL és l'oficial d'AWS; desconfia dels instal·ladors de tercers.unzip: extreu una carpetaaws/amb l'instal·lador.sudo ./aws/install: copia els binaris a/usr/local/aws-clii crea l'enllaç/usr/local/bin/aws. Necessitasudoperquè escriu fora del teu directori personal.rm -rf: esborra el que s'ha descarregat, que ja no fa falta.
Si la teva màquina és ARM (per exemple, una instància Graviton), canvia x86_64 per aarch64.
Per actualitzar una instal·lació existent, afegeix els paràmetres d'actualització:
macOS
# Descarrega el paquet .pkg oficial
curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
# Instal·la per a tots els usuaris de l'equip
sudo installer -pkg AWSCLIV2.pkg -target /Alternativa amb Homebrew, si ja el fas servir: brew install awscli.
Windows
Descarrega i executa l'instal·lador MSI oficial:
O des de PowerShell com a administrador:
Després tanca i torna a obrir el terminal perquè es recarregui la variable PATH.
Verificació
En qualsevol sistema:
Sortida esperada (els números variaran):
Es llegeix així: versió de la CLI, versió de Python incrustada (no fa servir el teu Python, va inclosa), sistema
operatiu i tipus de compilació. Si veus aws-cli/1.x, tens la v1 i l'hauries de desinstal·lar abans
de continuar.
Anatomia d'una comanda
Totes les comandes segueixen la mateixa estructura:
Un exemple real, línia a línia:
aws ec2 describe-instances \
--filters "Name=instance-state-name,Values=running" \
--region eu-west-1 \
--output table| Part | Què és | Detall |
|---|---|---|
aws |
El programa | — |
ec2 |
Servei | Sol coincidir amb el nom del servei: s3, iam, lambda, rds |
describe-instances |
Operació | L'API s'anomena DescribeInstances; la CLI fa servir minúscules i guions |
--filters "..." |
Paràmetre específic | Filtra al servidor: només instàncies en execució |
--region |
Opció global | Sobreescriu la regió del perfil per a aquesta comanda |
--output table |
Opció global | Format de sortida |
Els verbs segueixen convencions molt previsibles, i reconèixer-les accelera molt l'aprenentatge:
| Prefix | Què fa | Exemples |
|---|---|---|
describe- |
Retorna informació detallada | describe-instances, describe-vpcs |
list- |
Retorna una llista d'identificadors | list-buckets, list-functions |
get- |
Obté un element concret | get-caller-identity, get-bucket-tagging |
create- |
Crea un recurs | create-bucket, create-tags |
delete- / terminate- |
Elimina | delete-bucket, terminate-instances |
put- |
Escriu o sobreescriu una configuració | put-bucket-tagging, put-metric-alarm |
L'ajuda integrada
És la millor documentació que tens i funciona sense connexió:
aws help # llista tots els serveis disponibles
aws s3api help # llista totes les operacions de s3api
aws s3api create-bucket help # tots els paràmetres d'aquesta operació, amb exemplesS'obre en un paginador: navega amb les fletxes i surt amb q.
Configurar credencials: aws configure, fitxers i perfils
La CLI necessita saber qui ets. Crearem unes claus d'accés per a l'usuari
mercadofresco-admin que vam crear a la lliçó 01-02.
Pas 1: crear les claus d'accés
A la consola: IAM → Users → mercadofresco-admin → Security credentials → Create access key. Tria el cas d'ús Command Line Interface (CLI), confirma l'avís i crea-la.
N'obtindràs dos valors:
- Access key ID: una cosa com
AKIAIOSFODNN7EXAMPLE. És més aviat públic, identifica la clau. - Secret access key: una cosa com
wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY. Només es mostra una vegada. Si la perds, cal crear una clau nova.
Advertiment: no creïs mai claus d'accés per a l'usuari root (lliçó 01-02). I si no vols manejar claus permanents en absolut, l'alternativa moderna és
aws configure ssoamb IAM Identity Center, que emet credencials temporals.
Pas 2: aws configure
Et farà quatre preguntes:
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY Default region name [None]: eu-west-1 Default output format [None]: json
- Regió per defecte:
eu-west-1, la que vam decidir a la lliçó 01-03. T'evita escriure--regiona cada comanda. - Format de sortida:
jsonés un bon valor per defecte perquè és el que consumeixen altres eines.
Els fitxers de configuració
aws configure no fa màgia: escriu dos fitxers de text al teu directori personal
(~/.aws/ a Linux i macOS, %USERPROFILE%\.aws\ a Windows).
~/.aws/credentials — conté els secrets:
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY~/.aws/config — conté els ajustos no secrets:
Els pots editar a mà perfectament. Comprova a més que els permisos siguin restrictius:
Això deixa el fitxer llegible i escrivible només pel teu usuari. En un equip compartit és imprescindible.
Perfils amb nom
Gairebé mai treballaràs amb una sola identitat. MercadoFresco tindrà aviat un entorn de desenvolupament i un altre de producció, i convé que no es puguin confondre.
Crea un perfil nou:
Els fitxers queden així:
# ~/.aws/credentials
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
[mercadofresco-dev]
aws_access_key_id = AKIAI44QH8DHBEXAMPLE
aws_secret_access_key = je7MtGbClwBF/2Zp9Utk/h3yCoEXAMPLEKEY# ~/.aws/config
[default]
region = eu-west-1
output = json
[profile mercadofresco-dev]
region = eu-west-1
output = jsonAtenció al detall: a credentials la secció és [mercadofresco-dev], però a config és
[profile mercadofresco-dev], amb la paraula profile al davant. És una inconsistència històrica que
provoca errors constants. Si un perfil "no es troba", revisa això primer.
Per fer servir un perfil:
# Opció 1: per paràmetre, en una comanda concreta
aws s3 ls --profile mercadofresco-dev
# Opció 2: per variable d'entorn, per a tota la sessió de terminal
export AWS_PROFILE=mercadofresco-dev
aws s3 lsI per saber sempre amb qui estàs actuant:
Adquireix l'hàbit d'executar aquesta comanda abans de qualsevol operació destructiva. És la diferència entre esborrar la base de dades de desenvolupament i esborrar la de producció.
Ordre de precedència de les credencials
Quan executes una comanda, la CLI busca credencials en un ordre fix i es queda amb la primera font que trobi. Conèixer aquest ordre explica el 90 % dels "però si jo vaig configurar això":
| # | Font | Com s'indica | Quan es fa servir |
|---|---|---|---|
| 1 | Opcions de línia de comandes | --profile, --region |
Sobreescriu tota la resta |
| 2 | Variables d'entorn | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, AWS_PROFILE, AWS_DEFAULT_REGION |
CI/CD, contenidors, sessions temporals |
| 3 | Fitxer ~/.aws/credentials |
Perfil [default] o l'indicat |
Feina diària al teu portàtil |
| 4 | Fitxer ~/.aws/config |
Secció [profile ...] |
Configuració i rols |
| 5 | Credencials de contenidor | Variable injectada per ECS/EKS | Contenidors a AWS (mòdul 10) |
| 6 | Rol d'instància (IMDS) | Metadades de la mateixa EC2 | La manera correcta dins d'AWS |
Els dos últims són els importants conceptualment. Quan el teu codi s'executa dins d'AWS —en una instància EC2, en una funció Lambda, en un contenidor— no necessita claus en absolut: se li assigna un rol IAM i l'SDK obté automàticament credencials temporals que es roten soles cada poques hores.
flowchart TB
A["Comanda o SDK necessita credencials"] --> B{"--profile a la linia?"}
B -->|si| USA1["Fes servir aquest perfil"]
B -->|no| C{"Variables d'entorn?"}
C -->|si| USA2["Fes servir les variables"]
C -->|no| D{"Fitxer ~/.aws/credentials?"}
D -->|si| USA3["Fes servir el perfil default"]
D -->|no| E{"S'executa dins d'AWS?"}
E -->|si| USA4["Rol de la instancia - credencials temporals - L'IDEAL"]
E -->|no| F["Error: Unable to locate credentials"]
Els rols IAM s'estudien a fons a la lliçó 04-01. Queda't amb la idea: claus permanents només al teu portàtil; dins d'AWS, sempre rols.
Seguretat de les claus d'accés
Una clau d'accés de mercadofresco-admin és, literalment, el control total del compte. Aquestes
regles no són opcionals.
Mai al codi ni a Git
Aquest és l'error que arruïna comptes cada dia. Hi ha bots que escanegen GitHub de manera contínua
buscant cadenes que comencin per AKIA; una clau publicada s'explota en minuts, típicament
llançant desenes d'instàncies grans per minar criptomonedes. La factura resultant pot ser de
milers d'euros.
Protecció mínima en qualsevol repositori:
I una barrera automàtica, molt recomanable:
# git-secrets escaneja cada commit buscant patrons de credencials d'AWS
git secrets --install
git secrets --register-awsSi alguna vegada publiques una clau per error: desactiva-la i esborra-la immediatament a IAM, revisa CloudTrail (lliçó 05-03) per veure què s'hi va fer, i crea'n una de nova. Esborrar el commit no serveix de res: ja està indexat.
Altres regles
| Regla | Per què |
|---|---|
| Rotar cada 90 dies | Redueix la finestra d'explotació d'una clau filtrada |
| Una clau per persona i ús | Permet revocar-ne una sense afectar les altres |
| Eliminar les claus inactives | IAM mostra la data d'últim ús; el que no es fa servir, s'esborra |
| Mai claus al root | Ja vist a 01-02 |
| Dins d'AWS, rols en lloc de claus | Credencials temporals, rotades automàticament |
| MFA per a operacions sensibles | Es pot exigir a les polítiques IAM (lliçó 04-01) |
El procediment de rotació sense talls és senzill: crea una segona clau, actualitza on es faci servir, comprova que tot funciona, desactiva l'antiga, espera uns dies i esborra-la. IAM permet dues claus actives per usuari precisament per això.
Formats de sortida i filtratge amb --query
Les comandes d'AWS retornen molta informació. Aprendre a retallar-la és el que converteix la CLI en una eina còmoda.
Formats de sortida
| Format | Quan fer-lo servir |
|---|---|
json |
Per defecte. Ideal per encadenar amb jq o per processar en scripts |
table |
Per llegir amb els ulls: vores ASCII i columnes |
text |
Per processar amb grep, awk o cut; separat per tabuladors |
yaml |
Més llegible que JSON per a configuracions llargues |
--query amb JMESPath
--query aplica una expressió JMESPath sobre la resposta, al client. Anem de menys a
més.
Nivell 1 — extreure una llista:
Nivell 2 — un camp de cada element:
# De cada regió, només el seu nom. Els claudàtors [] recorren la llista
aws ec2 describe-regions --query 'Regions[].RegionName' --output textSortida:
Nivell 3 — reanomenar camps en un objecte:
aws ec2 describe-regions \
--query 'Regions[].{Region:RegionName, Endpoint:Endpoint}' \
--output tableLes claus {...} construeixen un objecte nou; a l'esquerra dels : va el nom que vols veure,
a la dreta el camp original.
Nivell 4 — filtrar amb una condició:
# Només les regions europees: ? introdueix el filtre, contains() és una funció JMESPath
aws ec2 describe-regions \
--query 'Regions[?contains(RegionName, `eu-`)].RegionName' \
--output tableFixa't en les cometes invertides al voltant d'eu-: a JMESPath, els literals van entre
backticks, no entre cometes normals. És una font freqüent d'errors.
Nivell 5 — un cas real de MercadoFresco:
aws ec2 describe-instances \
--query 'Reservations[].Instances[].{
Id:InstanceId,
Tipus:InstanceType,
Estat:State.Name,
IP:PrivateIpAddress,
Zona:Placement.AvailabilityZone,
Nom:Tags[?Key==`Name`]|[0].Value
}' \
--output tableDesglossament:
Reservations[].Instances[]: aplana l'estructura imbricada d'EC2 (les instàncies vénen agrupades per reserva) en una sola llista.State.Name: navega dins d'un objecte imbricat amb el punt.Tags[?Key==\Name`]|[0].Value: filtra les etiquetes quedant-se amb la de clauName, i el|[0]` pren el primer resultat d'aquella llista per extreure'n el valor.
--query enfront de --filters
--filters |
--query |
|
|---|---|---|
| On s'aplica | Al servidor d'AWS | Al teu equip, després de rebre la resposta |
| Efecte | Redueix el que es transfereix | Només redueix el que es mostra |
| Disponibilitat | Només en alguns serveis i camps | En qualsevol comanda |
| Recomanació | Fes-lo servir sempre que existeixi | Per donar forma al resultat |
L'ideal és combinar-los: --filters per portar poc, --query per presentar-ho bé.
Paginació, --dry-run i altres opcions útils
Paginació
Quan hi ha molts resultats, la CLI v2 els pagina automàticament i obre un paginador. Opcions per controlar-ho:
# Retorna com a màxim 5 elements
aws s3api list-buckets --max-items 5
# Desactiva el paginador interactiu (útil en scripts)
aws ec2 describe-instances --no-cli-pager
# Desactivar-lo de manera permanent
export AWS_PAGER=""Si limites amb --max-items i hi ha més resultats, la resposta inclou un NextToken que pots
passar amb --starting-token per demanar la pàgina següent.
--dry-run
Moltes operacions d'EC2 accepten --dry-run: comproven si tindries permisos per fer l'
operació, però no l'executen.
Si tens permís, veuràs:
An error occurred (DryRunOperation) when calling the RunInstances operation: Request would have succeeded, but DryRun flag is set
Aquest missatge, encara que digui "error", és la confirmació d'èxit. Si no en tinguessis permís, l'error
seria UnauthorizedOperation. És una manera segura de verificar permisos sense crear res ni gastar
res.
Altres opcions que es fan servir molt
| Opció | Per a què |
|---|---|
--no-cli-pager |
Sortida directa sense paginador |
--debug |
Traça completa de la petició HTTP; imprescindible per diagnosticar |
--cli-input-json file://params.json |
Passar tots els paràmetres des d'un fitxer |
--generate-cli-skeleton |
Generar la plantilla JSON de paràmetres d'una operació |
--endpoint-url |
Apuntar a un endpoint alternatiu (p. ex. un emulador local) |
Comandes d'exploració imprescindibles
Aquestes són les comandes que executaràs centenars de vegades. Desa-les.
# 2. Quines regions existeixen i estan habilitades al meu compte?
aws ec2 describe-regions --query 'Regions[].RegionName' --output text# 3. Quines zones de disponibilitat té la meva regió, amb el seu ID físic?
aws ec2 describe-availability-zones \
--query 'AvailabilityZones[].{AZ:ZoneName, Id:ZoneId, Estat:State}' \
--output table# 5. Quines instàncies EC2 tinc i en quin estat?
aws ec2 describe-instances \
--query 'Reservations[].Instances[].{Id:InstanceId, Estat:State.Name}' \
--output tableLa sortida de l'última és especialment útil perquè indica l'origen de cada valor:
Name Value Type Location
---- ----- ---- --------
profile mercadofresco-dev env AWS_PROFILE
access_key ****************MPLE shared-credentials-file
region eu-west-1 config-file ~/.aws/configQuan alguna cosa no funcioni com esperes, aquesta comanda et dirà exactament quina credencial i quina regió està fent servir la CLI i per què.
SDK: què són i quins llenguatges hi ha
Un SDK (Software Development Kit) és una biblioteca que permet a la teva aplicació cridar les APIs d'AWS des del llenguatge en què està escrita, sense construir peticions HTTP signades a mà.
La diferència amb la CLI:
| CLI | SDK | |
|---|---|---|
| Qui el fa servir | Una persona en un terminal, o un script | La teva aplicació, en temps d'execució |
| Cas típic | "Llista els buckets", "atura aquesta instància" | "Quan el client puja una foto, desa-la a S3" |
| Format | Comandes de text | Codi en el teu llenguatge |
Llenguatges amb SDK oficial:
| Llenguatge | Nom de l'SDK | Nota |
|---|---|---|
| Python | boto3 | El més usat en scripting i automatització |
| JavaScript / TypeScript | AWS SDK for JavaScript v3 | Modular: instal·les només el client que fas servir |
| Java | AWS SDK for Java 2.x | Molt comú a l'empresa |
| .NET (C#) | AWS SDK for .NET | — |
| Go | AWS SDK for Go v2 | Habitual en eines d'infraestructura |
| PHP | AWS SDK for PHP | Rellevant per al monòlit actual de MercadoFresco |
| Rust, Ruby, C++, Kotlin, Swift | — | Disponibles |
Tots comparteixen la mateixa lògica: cadena de proveïdors de credencials (el mateix ordre de precedència que hem vist), reintents automàtics amb retrocés exponencial, i noms d'operació equivalents als de l'API.
boto3: l'SDK de Python pas a pas
En Luis farà servir Python per als scripts de MercadoFresco, així que vegem boto3 en detall.
Instal·lació
# Crear un entorn virtual aïllat (bona pràctica: no instal·lar al Python del sistema)
python3 -m venv venv
# Activar-lo (a Windows: venv\Scripts\activate)
source venv/bin/activate
# Instal·lar boto3
pip install boto3Client enfront de recurs
boto3 ofereix dues interfícies diferents per al mateix:
| Client | Resource | |
|---|---|---|
| Nivell | Baix: reflecteix l'API 1:1 | Alt: orientat a objectes |
| Cobertura | Tots els serveis i operacions | Només alguns serveis; en manteniment |
| Estil | s3.list_buckets() retorna un diccionari |
for b in s3.buckets.all() |
| Recomanació | Fes-lo servir per defecte | Només si te'l trobes en codi heretat |
Exemple del mateix objectiu amb totes dues:
import boto3
# --- Interfície Client (recomanada) ---
s3_client = boto3.client("s3")
resposta = s3_client.list_buckets() # retorna un diccionari tal com el dona l'API
for bucket in resposta["Buckets"]:
print(bucket["Name"], bucket["CreationDate"])
# --- Interfície Resource (més antiga) ---
s3_recurs = boto3.resource("s3")
for bucket in s3_recurs.buckets.all(): # objectes amb atributs
print(bucket.name, bucket.creation_date)Credencials i sessions
boto3 fa servir exactament el mateix ordre de precedència que la CLI, així que si aws s3 ls funciona,
el teu codi Python funcionarà sense configurar res.
Per triar perfil o regió explícitament es fa servir una sessió:
import boto3
# Una sessió encapsula credencials + regió
sessio = boto3.Session(profile_name="mercadofresco-dev", region_name="eu-west-1")
s3 = sessio.client("s3")
print(sessio.client("sts").get_caller_identity()["Arn"])Gestió d'errors amb ClientError
Tot error retornat per un servei d'AWS arriba com a botocore.exceptions.ClientError. Ignorar-lo
és l'error més comú dels scripts de principiant.
import boto3
from botocore.exceptions import ClientError
s3 = boto3.client("s3", region_name="eu-west-1")
def existeix_bucket(nom: str) -> bool:
"""Comprova si un bucket existeix i és accessible per a les nostres credencials."""
try:
s3.head_bucket(Bucket=nom) # petició lleugera: només capçaleres
return True
except ClientError as error:
# El codi concret és sempre a error.response["Error"]["Code"]
codi = error.response["Error"]["Code"]
if codi == "404":
print(f"El bucket '{nom}' no existeix.")
elif codi == "403":
print(f"El bucket '{nom}' existeix però no tens permís per veure'l.")
else:
raise # qualsevol altre error, que es propagui
return False
print(existeix_bucket("mercadofresco-fotos-producto"))Punts clau del fragment:
head_bucketés la manera barata de comprovar l'existència: no descarrega contingut.error.response["Error"]["Code"]és la ruta estàndard per llegir el codi d'error. Memoritza-la.- Distingir 404 de 403 importa: "no existeix" i "existeix però no el pots veure" exigeixen accions diferents.
- El
raisefinal evita l'antipatró d'empassar-se errors desconeguts, que amaga problemes reals.
Paginació a boto3
Les APIs retornen com a molt uns centenars d'elements per crida. Si itères només la primera resposta, perdràs dades en silenci. Els paginadors ho resolen:
import boto3
s3 = boto3.client("s3", region_name="eu-west-1")
paginador = s3.get_paginator("list_objects_v2")
pagines = paginador.paginate(Bucket="mercadofresco-fotos-producto", Prefix="2026/")
total = 0
for pagina in pagines: # cada iteració és una crida a l'API
for objecte in pagina.get("Contents", []): # .get() evita KeyError si la pàgina ve buida
total += 1
print(f"Objectes trobats: {total}")Una ullada equivalent en JavaScript
Perquè vegis que els conceptes es traslladen, el mateix llistat de buckets amb l'AWS SDK for JavaScript v3:
# L'SDK v3 és modular: només s'instal·la el client del servei que necessites
npm install @aws-sdk/client-s3// Importa només el client de S3 i la comanda concreta que farem servir
import { S3Client, ListBucketsCommand } from "@aws-sdk/client-s3";
// El client llegeix credencials amb el mateix ordre de precedència que la CLI
const client = new S3Client({ region: "eu-west-1" });
async function llistarBuckets() {
try {
// Al v3, cada operació és un objecte Command que s'envia amb send()
const resposta = await client.send(new ListBucketsCommand({}));
resposta.Buckets.forEach((b) => console.log(b.Name, b.CreationDate));
} catch (error) {
// L'equivalent a ClientError: el codi és a error.name
console.error("Error d'AWS:", error.name, "-", error.message);
}
}
llistarBuckets();Diferències respecte a boto3: el v3 és modular (menys pes a Lambda) i fa servir el patró
comanda: crees un objecte XxxCommand i l'envies amb send(). La lògica de credencials,
reintents i errors és equivalent.
CloudShell com a alternativa sense instal·lació
Com vam veure a la lliçó 01-04, AWS CloudShell et dona un terminal al navegador amb la CLI v2, Python i boto3 ja instal·lats, i autenticada automàticament amb l'usuari de la consola.
| CLI local | CloudShell | |
|---|---|---|
| Instal·lació | Sí | No |
| Credencials | Configures claus | Heretades, temporals |
| Rendiment i fitxers locals | Total | Limitat (1 GB persistent) |
| Sessió | Permanent | Caduca per inactivitat |
| Ideal per a | Feina diària, scripts, CI | Proves ràpides, emergències, formació |
CloudShell és especialment útil per a l'escenari "sóc en un ordinador que no és el meu i necessito diagnosticar alguna cosa ja". No substitueix la CLI local per a la feina diària, però és una xarxa de seguretat excel·lent.
Errors Habituals i Consells
Unable to locate credentials. No has configurat el perfil, o has fet servir un nom de perfil inexistent. Diagnostica-ho ambaws configure list.ProfileNotFoundamb el perfil ben escrit. Gairebé sempre és la secció de~/.aws/configsense el prefixprofile: ha de ser[profile mercadofresco-dev], no[mercadofresco-dev].You must specify a region. Ni el perfil ni la variable d'entorn ni la comanda indiquen regió. Afegeix--regiono configura-la al perfil.AccessDeniedinesperat. Comprova primer amb quina identitat estàs actuant ambaws sts get-caller-identity; molt sovint és el perfil equivocat, no un problema de permisos.- Pujar claus a Git. El desastre més car i més freqüent.
.gitignore,git secretsi, millor encara, credencials temporals. - Fer servir claus permanents dins d'una instància EC2. Mai. Es fa servir un rol d'instància (lliçó 04-01), que a més rota les credencials sol.
- Oblidar la paginació. El teu script diu "hi ha 1.000 objectes" quan n'hi ha 50.000. Fes servir paginadors
a boto3 i
--max-items/NextTokena la CLI. - Confondre
aws s3ambaws s3api. El primer és d'alt nivell (ls,cp,sync); el segon exposa l'API completa (get-bucket-tagging,put-bucket-policy). Si una opció no existeix as3, busca-la as3api. - Ignorar
ClientError. Un script que falla en silenci és pitjor que un que es trenca. - Consell: defineix àlies al teu terminal per al que repeteixis molt, per exemple
alias qui='aws sts get-caller-identity'. - Consell: quan una comanda no funcioni i no entenguis per què, afegeix-hi
--debug. Veuràs la petició signada completa i la resposta del servei.
Exercicis
Exercici 1: instal·lació i exploració
- Instal·la AWS CLI v2 al teu sistema i verifica'n la versió.
- Configura un perfil anomenat
mercadofresco-adminamb regióeu-west-1i sortidajson. - Executa
aws sts get-caller-identityi anota el teu ARN complet. - Escriu una sola comanda que mostri, en format taula, totes les regions el nom de les quals comenci
per
eu-, amb una única columna anomenadaRegion.
Exercici 2: script bash d'inventari
Escriu un script inventario-mercadofresco.sh que:
- Comprovi amb quina identitat i en quin compte s'està executant, i ho mostri.
- Llisti tots els buckets de S3 del compte.
- Llisti les zones de disponibilitat d'
eu-west-1amb el seu ID físic. - Llisti les instàncies EC2 amb el seu ID, tipus, estat i zona (si no n'hi ha cap, ho ha d'indicar sense fallar).
- Tot amb sortida en taula i sense obrir el paginador interactiu.
Exercici 3: script boto3 que crea i etiqueta un bucket
Escriu un script Python crear_bucket_mercadofresco.py que:
- Rebi el nom del bucket com a argument de línia de comandes.
- Comprovi si ja existeix (distingint "no existeix" de "sense permisos").
- Si no existeix, el creï a
eu-west-1amb el bloqueig d'accés públic activat. - Li apliqui les etiquetes
Proyecto=mercadofresco,Entorno=pruebas,Componente=formacion. - Mostri les etiquetes resultants.
- Gestioni els errors amb
ClientErrori retorni un codi de sortida diferent de zero si falla.
Cost: un bucket buit no genera cost apreciable i la capa gratuïta cobreix 5 GB. Tot i així, esborra'l en acabar amb
aws s3 rb s3://<nom-del-bucket>.
Solucions
Solució 1
# 1. Instal·lació a Linux i verificació
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip && sudo ./aws/install
aws --version
# 2. Perfil
aws configure --profile mercadofresco-admin
# Regió: eu-west-1 ; Sortida: json
# 3. Identitat
aws sts get-caller-identity --profile mercadofresco-admin
# 4. Regions europees en taula, columna única anomenada Region
aws ec2 describe-regions \
--query 'Regions[?starts_with(RegionName, `eu-`)].{Region:RegionName}' \
--output tableEs pot fer servir starts_with() o contains(); starts_with és més precís perquè contains
també acceptaria un nom que portés eu- al mig.
Solució 2
#!/usr/bin/env bash
# inventario-mercadofresco.sh - inventari ràpid del compte d'AWS
set -euo pipefail # avorta davant d'error, variable no definida o fallada en una canonada
PERFIL="${1:-mercadofresco-admin}" # primer argument o valor per defecte
REGIO="eu-west-1"
export AWS_PAGER="" # desactiva el paginador interactiu
echo "===== IDENTITAT ====="
aws sts get-caller-identity \
--profile "$PERFIL" \
--query '{Compte:Account, Identitat:Arn}' \
--output table
echo "===== BUCKETS S3 ====="
aws s3api list-buckets \
--profile "$PERFIL" \
--query 'Buckets[].{Nom:Name, Creat:CreationDate}' \
--output table
echo "===== ZONES DE DISPONIBILITAT DE $REGIO ====="
aws ec2 describe-availability-zones \
--profile "$PERFIL" --region "$REGIO" \
--query 'AvailabilityZones[].{AZ:ZoneName, IdFisic:ZoneId, Estat:State}' \
--output table
echo "===== INSTÀNCIES EC2 ====="
INSTANCIES=$(aws ec2 describe-instances \
--profile "$PERFIL" --region "$REGIO" \
--query 'Reservations[].Instances[].{Id:InstanceId, Tipus:InstanceType, Estat:State.Name, Zona:Placement.AvailabilityZone}' \
--output table)
if [ -z "$INSTANCIES" ]; then
echo "(no hi ha instàncies EC2 a $REGIO)"
else
echo "$INSTANCIES"
fi
echo "===== FI DE L'INVENTARI ====="Detalls importants:
set -euo pipefailevita que l'script continuï alegrement després d'una fallada.export AWS_PAGER=""és imprescindible en scripts: sense això, la CLI obriria un paginador i l' script es quedaria bloquejat esperant que algú premésq.- Desar la sortida en una variable permet comprovar si és buida i donar un missatge clar en lloc d'imprimir una taula buida.
S'executa amb:
Solució 3
#!/usr/bin/env python3
"""crear_bucket_mercadofresco.py - crea i etiqueta un bucket de S3 per a MercadoFresco."""
import sys
import boto3
from botocore.exceptions import ClientError
REGIO = "eu-west-1"
ETIQUETES = [
{"Key": "Proyecto", "Value": "mercadofresco"},
{"Key": "Entorno", "Value": "pruebas"},
{"Key": "Componente", "Value": "formacion"},
]
def existeix_bucket(s3, nom: str) -> bool:
"""True si el bucket existeix i és accessible; False si no existeix."""
try:
s3.head_bucket(Bucket=nom)
return True
except ClientError as error:
codi = error.response["Error"]["Code"]
if codi in ("404", "NoSuchBucket"):
return False
if codi == "403":
print(f"El bucket '{nom}' existeix però pertany a un altre compte.")
sys.exit(1)
raise
def crear_bucket(s3, nom: str) -> None:
"""Crea el bucket a REGIO amb l'accés públic bloquejat."""
# Fora d'us-east-1 cal indicar LocationConstraint explícitament
s3.create_bucket(
Bucket=nom,
CreateBucketConfiguration={"LocationConstraint": REGIO},
)
print(f"Bucket '{nom}' creat a {REGIO}.")
# Bloqueig total d'accés públic: les quatre opcions a True
s3.put_public_access_block(
Bucket=nom,
PublicAccessBlockConfiguration={
"BlockPublicAcls": True,
"IgnorePublicAcls": True,
"BlockPublicPolicy": True,
"RestrictPublicBuckets": True,
},
)
print("Accés públic bloquejat.")
def etiquetar(s3, nom: str) -> None:
"""Aplica el conjunt d'etiquetes (sobreescriu les existents)."""
s3.put_bucket_tagging(Bucket=nom, Tagging={"TagSet": ETIQUETES})
print("Etiquetes aplicades.")
def main() -> int:
if len(sys.argv) != 2:
print("Ús: python crear_bucket_mercadofresco.py <nom-del-bucket>")
return 1
nom = sys.argv[1]
s3 = boto3.client("s3", region_name=REGIO)
try:
if existeix_bucket(s3, nom):
print(f"El bucket '{nom}' ja existeix al teu compte; no es torna a crear.")
else:
crear_bucket(s3, nom)
etiquetar(s3, nom)
actuals = s3.get_bucket_tagging(Bucket=nom)["TagSet"]
print("\nEtiquetes actuals del bucket:")
for etiqueta in actuals:
print(f" {etiqueta['Key']} = {etiqueta['Value']}")
except ClientError as error:
print(f"Error d'AWS: {error.response['Error']['Code']} - "
f"{error.response['Error']['Message']}", file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
sys.exit(main())Claus de la solució:
LocationConstraint: si crees un bucket en qualsevol regió que no siguius-east-1i omets aquest paràmetre, S3 el crea aus-east-1. És una de les raresses històriques de l'API.put_public_access_blockamb les quatre opcions aTrueés la protecció que evita la fuita de dades més habitual a AWS.put_bucket_taggingsobreescriu el conjunt complet d'etiquetes: si en volguessis afegir una sense esborrar les altres, hauries de llegir-les primer ambget_bucket_taggingi fusionar-les.- Codis de sortida:
0si tot va bé,1si falla, per poder encadenar l'script en un pipeline.
Execució i neteja:
python crear_bucket_mercadofresco.py mercadofresco-pruebas-cli-jc-2741
# Neteja obligatòria en acabar (rb = remove bucket; ha d'estar buit)
aws s3 rb s3://mercadofresco-pruebas-cli-jc-2741Conclusió
Amb aquesta lliçó tanques el mòdul d'introducció i, sobretot, fas el salt d'"usuari d'AWS" a
"operador d'AWS". Has instal·lat l'AWS CLI v2, has entès l'anatomia d'una comanda
(aws <servei> <operació> --paràmetres) i les convencions de noms que et permeten endevinar
comandes que encara no coneixes. Has configurat credencials amb aws configure, has vist què hi ha
realment dins de ~/.aws/credentials i ~/.aws/config, i saps treballar amb perfils
amb nom per no confondre mai desenvolupament amb producció. Coneixes l'ordre de precedència de
les credencials, que explica gairebé tots els comportaments estranys, i les regles de seguretat
innegociables: mai claus a Git, rotació periòdica i, dins d'AWS, rols en lloc de claus.
Has après a domar la sortida de les comandes amb --output i amb --query i JMESPath, a evitar
el parany silenciós de la paginació, a verificar permisos sense gastar res amb --dry-run, i
tens a la mà el grapat de comandes d'exploració que faràs servir cada dia. I has fet els teus primers
passos amb els SDK: boto3 en Python, amb la distinció entre client i resource, la gestió
correcta d'errors mitjançant ClientError i els paginadors, més l'equivalent en JavaScript per
veure que els conceptes són universals.
MercadoFresco ja té tot el que necessita per començar de debò: un compte segur i vigilat, una regió triada amb criteri, una consola que saps manejar i unes eines de línia de comandes i programació que fan la feina repetible.
Al mòdul 2, «Serveis principals d'AWS», començant per la lliçó 02-01 «Amazon EC2», aixecarem el primer servidor real de MercadoFresco al núvol i començarem la migració que resoldrà, un a un, els quatre problemes que vam descobrir a la primera lliçó.
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
