Tema 2 · 9 · Ejercicio C: los tres almacenamientos sobre un dataset real (BiciMAD)
Presentación del Tema 2: «Ejercicio C» (los tres almacenamientos sobre un dataset real) y «Ejercicio C · paso a paso». Duración: 1,5 a 2 horas. Coste: céntimos si borras todo el mismo día (dos t3.small, un volumen de 10 GB, un EFS y un bucket). Las máquinas las crea un script desde CloudShell y se apagan solas a las 4 horas.
Esta carpeta trae el script que crea y borra las máquinas (gestionar-bicimad.sh, que se ejecuta en CloudShell y lleva dentro procesa-viajes.sh), el script que procesa el CSV mensual de BiciMAD (procesa-viajes.sh), la política mínima de permisos para publicar el resultado en S3 sin guardar claves en la máquina (politica-rol-s3.json) y la política de confianza para crear el rol por CLI (confianza-ec2.json). El enunciado está en la presentación del Tema 2; aquí está cómo se hace paso a paso, qué verás y qué hacer si falla.
¿Dudas con un script? Todos los scripts de esta carpeta traen su propia ayuda:
./gestionar-bicimad.sh --ayuda(en CloudShell) ybash ~/procesa-viajes.sh --ayuda(en la máquina; también vale--helpo-h) explican los pasos y las opciones. EsteREADME.mdes el paso a paso de la actividad: tenlo a mano y consúltalo antes de preguntar.
Etiquetas de lo que creas. Todo recurso que crees a mano (máquina, volumen, bucket, base de datos, tabla, función...) ponle estas etiquetas, al crearlo (apartado Tags / Etiquetas) o después desde su pestaña de etiquetas:
curso=G214,universidad=CUNEFyactividad=02.09-ejerciciocbicimad. Si algún día hay que borrar recursos a mano, se localizan todos de golpe conaws resourcegroupstaggingapi get-resources --region eu-north-1 --tag-filters Key=actividad,Values=02.09-ejerciciocbicimad. Más detalle (cómo etiquetar con la CLI, cómo buscar y qué hacer en una emergencia): README principal, sección «Etiquetas».
1. Qué se construye
- EBS (10 GB) en la VM de proceso: ficheros intermedios y resultados (
/mnt/ebs): un solo equipo, baja latencia. - EFS montado en las dos VM: el log de progreso (
~/efs/logs/proceso.log), que la VM 2 lee mientras la VM 1 escribe. - S3: el resumen final (
out/resumen.csv), compartido con una URL firmada. - Dos instancias
t3.small(Amazon Linux 2023), un volumen EBS de 10 GB en la misma zona que la VM de proceso, un EFS y un bucket. Un Security Group con SSH (22) y NFS (2049) con origen el propio grupo (no0.0.0.0/0)../gestionar-bicimad.sh crearcrea todo salvo el bucket y el rol de IAM (esas dos partes las haces tú, pasos 7 y siguientes) y dejaprocesa-viajes.shya copiado en la máquinaproceso.
2. Prerrequisitos
- Los laboratorios de archivos (EFS) y de bloques del Tema 2 hechos, y haber hecho
02.01-s3primerbucket(S3 y CloudShell),02.05-EFSCarpetaCompartida.mdy02.06-laboratoriocafeteria. - Conocer
lsblk,mkfs,mount,chown(anexo de comandos Linux del Tema 0). Nuevos aquí:curl -L -o,unzip,awk -F';',sort | uniq -c,tail -F,blkid. - CloudShell abierto con la región eu-north-1, con la carpeta
02.09-ejerciciocbicimadsubida (clic derecho > Comprimir en ZIP en tu PC, Actions > Upload file en CloudShell,unzip -o 02.09-ejerciciocbicimad.zip,cd 02.09-ejerciciocbicimadychmod -R u+rwX . && chmod +x gestionar-bicimad.sh). No hay que copiar ni pegar ningún script: las máquinas se conectan con el botón Connect de la consola (EC2 Instance Connect), sin par de claves.
3. Datos: BiciMAD (Madrid)
El portal de Madrid no ofrece un CSV mensual descargable con un solo wget: publica un ZIP anual (2017-2023) que contiene un ZIP por mes con el CSV dentro. Hay que descargar y descomprimir dos veces. Mira siempre el formato antes de procesar (file viajes.csv ; head -3 viajes.csv): el separador es ;, las líneas terminan en CRLF, hay filas vacías (;;;;;) intercaladas y la geolocalización es un texto con comas. Por eso awk -F, no sirve con este fichero.
Alternativa rápida y directa (Barcelona, Bicing, enero de 2019, 269 KB, separador coma; son bicis en uso cada 5 minutos, no viajes): curl -L -o viajes.csv https://opendata-ajuntament.barcelona.cat/data/dataset/4a469cf6-dbab-4aa1-b492-aa0af9af93c9/resource/453abff9-fb75-4f31-a699-23509bf0eca2/download. Con ese fichero procesa-viajes.sh no sirve (otras columnas): úsalo solo para ensayar el montaje.
4. Paso a paso
1. Crea las dos máquinas, el disco y el EFS (en CloudShell):
./gestionar-bicimad.sh crear
Si ya subiste
g214-materiales.zip(README principal), no necesitas este zip: entra concd ~/g214-materiales/tema2/02.09-ejerciciocbicimady, si algún fichero daPermission denied, ejecuta allíchmod -R u+rwX . && chmod +x *.sh.
Qué verás: el Security Group, el EFS (1-2 minutos hasta que están sus puntos de montaje), los ficheros subidos a un bucket temporal, proceso y observa lanzadas, el aviso Apagado automático: se apagará a las HH:MM UTC (dentro de 4 h 0 min) y un recuadro Tu laboratorio con los IDs, las IPs y el comando para montar el EFS. Tarda unos 4 minutos y es seguro repetirlo (lo que existe se reutiliza). ./gestionar-bicimad.sh estado te lo vuelve a mostrar en cualquier momento. El volumen de 10 GB llega en blanco a proceso: lo formateas tú en el paso 2. Si más adelante necesitas más tiempo: ./gestionar-bicimad.sh extender --horas 8. Después conéctate a cada máquina con EC2 → Instances → Connect → EC2 Instance Connect.
2. Disco de trabajo en proceso. Identifica el disco por su tamaño (10G) en lsblk, no por el nombre (nvme1n1 solo es seguro con un único disco extra). Comprueba que está vacío antes de formatear:
lsblk
sudo blkid /dev/nvme1n1 # no debe mostrar NADA (disco sin formato); si muestra TYPE="ext4", ya tiene datos: no hagas mkfs
sudo mkfs -t ext4 /dev/nvme1n1
sudo mkdir -p /mnt/ebs
sudo mount /dev/nvme1n1 /mnt/ebs
sudo chown ec2-user:ec2-user /mnt/ebs
mkfs se niega a formatear el disco del sistema (apparently in use by the system), pero sobre un disco que ya tiene ext4 formatea sin preguntar si no hay terminal (script, ssh host 'comando'): por eso el blkid previo. No interrumpas un mkfs a medias (Ctrl+C o una tubería cortada): el disco queda sin poder montarse.
3. EFS en las dos VM (desde cd ~; el script ya instaló amazon-efs-utils y unzip y creó la carpeta ~/efs):
sudo mount -t efs -o tls fs-XXXXXXXX:/ ~/efs # el comando que te dio «crear» (o «estado»)
sudo chown ec2-user:ec2-user ~/efs # solo hace falta en una VM: la raíz del EFS es compartida
mkdir -p ~/efs/logs
Si el mount se cuelga, es casi siempre el puerto 2049 del Security Group: el script lo deja bien, así que solo pasa si alguien lo cambió a mano. No insistas: ejecuta ./gestionar-bicimad.sh crear en CloudShell (recompone el grupo) y repite.
Si falla al instante con Failed to resolve "fs-...efs...", el EFS es reciente: aunque los mount targets ya estén Available, el nombre DNS puede tardar hasta 5-7 minutos en resolverse en una zona (en las pruebas, 6-7 minutos en proceso y a la primera en observa). Repite el comando cada minuto. No ejecutes chown ni mkdir -p ~/efs/logs hasta que df -h | grep efs muestre 127.0.0.1:/: tras un montaje fallido esos comandos crean las carpetas en el disco local (el montaje posterior las tapa).
4. Descarga y descomprime en proceso (en el disco EBS):
cd /mnt/ebs
curl -L -o bicimad_2023.zip https://media.emtmadrid.es/-9Nii5DXo4x # ZIP anual, 22,5 MB
unzip bicimad_2023.zip 'bicimad_2023/trips_23_02_February-csv.zip'
unzip bicimad_2023/trips_23_02_February-csv.zip # -> trips_23_02_February.csv (56,6 MB)
mv trips_23_02_February.csv viajes.csv
file viajes.csv ; head -3 viajes.csv | cut -c1-160 # mira el formato: ';' y CRLF
Qué verás: algo como Unicode text, UTF-8 text, with CRLF line terminators y una cabecera fecha;idBike;fleet;trip_minutes;...;lock_station_name (si file no existe, sudo dnf install -y file, o fíjate solo en head). Si file dice Zip archive data, el fichero sigue siendo un ZIP.
5. Observa desde observa, ANTES de lanzar el proceso. Primero crea el fichero del log en proceso: sin él, tail -F en la otra VM tarda hasta un minuto en darse cuenta de que existe (caché negativa de directorios de NFS) y verás todas las líneas de golpe al final.
touch ~/efs/logs/proceso.log # en proceso
tail -F ~/efs/logs/proceso.log # en observa (con -F espera a que el fichero exista; con -f falla si todavía no está)
6. Procesa en proceso (procesa-viajes.sh ya está en tu carpeta personal: no hay que copiarlo):
cd /mnt/ebs
bash ~/procesa-viajes.sh viajes.csv
Qué verás en las dos VM: líneas con la hora (HH:MM:SS inicio ..., viajes por hora listos: 24 horas, estaciones listas, fin). En la VM 2 llegan en ráfagas y con unos segundos de retraso (3-8 s en las pruebas, hasta unos 10 s; caché de atributos de NFS): es normal. Si no aparece nada durante un minuto y luego salen todas de golpe, falta el touch previo. El script hace pausas de 5 segundos (PAUSA=2 bash ~/procesa-viajes.sh viajes.csv para acortarlas). Antes de empezar comprueba el CSV (que exista, no esté vacío, no sea un ZIP, cabecera fecha;idBike;...), que puedas escribir el log en el EFS y que haya espacio, y si algo falla te dice qué hacer. Otros usos (probados en una VM real; sin argumentos extra funciona como antes): bash ~/procesa-viajes.sh ayuda; bash ~/procesa-viajes.sh estado (CSV, resultados, disco, EFS y últimas líneas del log; no modifica nada); bash ~/procesa-viajes.sh eliminar (borra resumen_hora.csv, resumen.csv y el log; no borra el CSV; --si no pregunta).
Resultados con el CSV de febrero de 2023: resumen_hora.csv con el pico a las 18 h (13.049 viajes) y a las 08 h (12.258), y resumen.csv con la estación de salida más usada, 39 - Plaza de la Cebada (2.189 viajes), seguida de 53 - Plaza de Lavapiés (1.789) y 45 - Puerta de Toledo (1.542).
7. Publica el resumen en S3 SIN guardar claves en la VM. aws configure con tus claves personales dentro de una VM es mala práctica (la clave queda en disco, en ~/.aws/credentials; si es de la cuenta raíz, es gravísimo). Sin credenciales, aws s3 cp da Unable to locate credentials. Dos formas correctas:
- A) A mano (el fichero es pequeño). Muestra el resumen en
proceso, cópialo y pégalo en un fichero de CloudShell, y publícalo desde allí:
cat /mnt/ebs/resumen.csv # en proceso: selecciona el texto y copia
cat > resumen.csv # en CloudShell: pega, Enter y Ctrl+D
aws s3 cp resumen.csv s3://g214-apellido-bici/out/
aws s3 presign s3://g214-apellido-bici/out/resumen.csv --expires-in 600
(Antes crea el bucket: aws s3 mb s3://g214-apellido-bici --region eu-north-1. Es la única parte que se copia a mano y solo son unas líneas.)
-
B) Con un rol de instancia (sin claves, lo recomendable). Hace falta permiso de IAM (en tu cuenta personal lo tienes; en una cuenta de curso restringida puede no estar: usa la opción A). Con esta opción el resumen se publica directamente desde
proceso. Un rol de instancia son credenciales temporales que EC2 entrega a la máquina; la políticapolitica-rol-s3.jsones la mínima:s3:PutObject(subir) ys3:GetObject(para que la URL firmada generada desde la VM abra el fichero) solo sobreout/*de tu bucket. Con el simulador de políticas de IAM se comprobó que permite esas dos acciones sobreout/*y deniega todo lo demás (otro prefijo,DeleteObject,ListBucket).B1. Por la consola (recomendado):
- IAM → Roles → Create role → Trusted entity type: AWS service → Use case: EC2 → Next.
- No marques ninguna política → Next → Role name
g214-bici-s3→ Create role. La consola crea además el perfil de instancia (instance profile) con el mismo nombre; es lo que se asocia a la instancia. - Abre el rol → Permissions → Add permissions → Create inline policy → pestaña JSON: pega
politica-rol-s3.jsoncambiandog214-apellido-bicipor tu bucket → Next → Policy namepublicar-resumen→ Create policy. (Para la práctica también valeAmazonS3FullAccess, pero es más permiso del necesario.) - EC2 → Instances →
proceso→ Actions → Security → Modify IAM role →g214-bici-s3→ Update IAM role.
B2. Por CLI (desde CloudShell o un PC con permisos de IAM; probada en AWS real el 8 de octubre de 2026: con el rol asociado,
aws s3 cpaout/ypresignfuncionan, ylsdel bucket, otro prefijo yrmdanAccessDenied). Con la CLI el perfil de instancia hay que crearlo y rellenarlo a mano:sed -i 's/g214-apellido-bici/MI-BUCKET/' politica-rol-s3.json # en CloudShell/Linux; en Mac: sed -i '' ... aws iam create-role --role-name g214-bici-s3 --assume-role-policy-document file://confianza-ec2.json aws iam put-role-policy --role-name g214-bici-s3 --policy-name publicar-resumen --policy-document file://politica-rol-s3.json aws iam create-instance-profile --instance-profile-name g214-bici-s3 aws iam add-role-to-instance-profile --instance-profile-name g214-bici-s3 --role-name g214-bici-s3 aws ec2 associate-iam-instance-profile --instance-id i-XXXXXXXX --iam-instance-profile Name=g214-bici-s3 --region eu-north-1B3. Comprueba, en la VM
proceso(espera ~30 segundos tras asociar el rol):aws sts get-caller-identitydebe mostrarassumed-role/g214-bici-s3/i-...; despuésaws s3 cp resumen.csv s3://g214-apellido-bici/out/yaws s3 presign s3://g214-apellido-bici/out/resumen.csv --expires-in 600. La URL firmada con un rol lleva un token y deja de valer cuando caduca la sesión del rol.
Qué verás: upload: ./resumen.csv to s3://g214-apellido-bici/out/resumen.csv y una URL que abre el CSV en el navegador sin credenciales (sin firmar da 403).
5. Errores frecuentes
| Qué ves | Causa | Solución |
|---|---|---|
viajes.csv es un ZIP (file lo dice) |
curl -o viajes.csv sobre el ZIP anual |
Usa bicimad_2023.zip y descomprime dos veces (paso 4) |
awk devuelve líneas con números y comas raras |
-F, en un CSV con ; |
-F';' y mira head -3 antes de agregar |
tail: cannot open ... No such file or directory |
tail -f antes de que exista el log |
tail -F, o touch ~/efs/logs/proceso.log antes |
En observa no aparece nada durante ~1 minuto y luego salen todas las líneas de golpe |
tail -F lanzado con el log sin crear (caché negativa de directorios de NFS) |
touch ~/efs/logs/proceso.log en proceso antes de lanzar tail -F |
Failed to resolve "fs-...efs..." al montar |
EFS recién creado: el DNS tarda hasta 5-7 minutos en una zona | Espera y repite el montaje; no sigas con chown/mkdir hasta ver 127.0.0.1:/ en df -h |
mount se queda colgado |
Puerto 2049 cerrado (alguien cambió el Security Group) | ./gestionar-bicimad.sh crear en CloudShell recompone el grupo |
| La máquina no responde | Se apagó sola (4 horas) | ./gestionar-bicimad.sh crear la arranca y renueva el plazo; la IP cambia y hay que montar el EFS de nuevo (y el disco: sudo mount /dev/nvme1n1 /mnt/ebs, sin mkfs) |
mkfs formatea sin preguntar |
No hay terminal (script) y el disco ya tenía datos | sudo blkid /dev/nvme1n1 vacío antes del mkfs |
Unable to locate credentials |
La VM no tiene credenciales (es lo correcto) | Opción A (a mano) u opción B (rol de instancia) del paso 7 |
unzip: command not found |
Amazon Linux mínimo | sudo dnf install -y unzip |
No space left on device |
Disco de 10 GB sin montar (escribes en el disco raíz de 8 GB) | df -h /mnt/ebs debe mostrar /dev/nvme1n1 |
6. Limpieza
- En CloudShell, carpeta del ejercicio:
./gestionar-bicimad.sh eliminar(pide confirmación;--sino la pide). Borra las dos máquinas, el volumen de 10 GB, el EFS con sus puntos de montaje, el Security Group y los ficheros temporales. Es repetible: si algo se resiste, vuelve a ejecutarlo. No hace falta desmontar nada antes. Si quieres borrar antes los resultados, enproceso:bash ~/procesa-viajes.sh eliminar. - Lo que creaste tú a mano no lo borra el script: vacía y borra el bucket (
aws s3 rb s3://g214-apellido-bici --force, sin versionado). - Si usaste la opción B del paso 7: desasocia el rol de la instancia (o ya la habrá terminado el script) y después IAM → Roles → borrar
g214-bici-s3. Por CLI:aws ec2 disassociate-iam-instance-profile --association-id ...(el id sale deaws ec2 describe-iam-instance-profile-associations),aws iam remove-role-from-instance-profile,aws iam delete-instance-profile,aws iam delete-role-policy --policy-name publicar-resumenyaws iam delete-role, todos con--role-name/--instance-profile-name g214-bici-s3. - Comprueba que no queda nada:
./gestionar-bicimad.sh estadoy, en la consola, EC2 → Volumes y EFS vacíos.
7. Cómo sabes que has terminado
- [ ] Has rellenado la tabla de decisión (dato → servicio → motivo) antes de crear nada.
- [ ]
tail -Fenobservamostró las líneas del log que escribíaproceso. - [ ]
resumen_hora.csvmuestra el pico a las 18 h (13.049 viajes) yresumen.csvla estación39 - Plaza de la Cebada(2.189 viajes). - [ ] El resumen está en S3 y se abre con una URL firmada, sin haber guardado claves en la VM.
- [ ] Has ejecutado
./gestionar-bicimad.sh eliminar, has borrado el bucket (y el rol, si lo creaste) y lo has comprobado en la consola.
Anterior: 02.08-ejerciciobdatosabiertos · Siguiente: Tema 3.