# Tema 2 · 7 · Ejercicio A: ciclo de vida y clases de almacenamiento (padrón del INE) Presentación del Tema 2: «Ejercicio A · Ciclo de vida y clases de almacenamiento» y «Ejercicio A · paso a paso». Duración: unos 30 minutos. Coste: céntimos (el padrón de tres años pesa 2,6 MB). > **¿Dudas con un script?** Todos los scripts de esta carpeta traen su propia ayuda: `./descargar-datos.sh --ayuda` · `./dividir-padron.sh --ayuda` · `./gestionar-ciclo-de-vida.sh --ayuda` · `python3 vaciar-bucket.py --ayuda` (también vale `--help` o `-h`) explica los pasos y las opciones. Este `README.md` es el paso a paso de la actividad: tenlo a mano y consúltalo antes de preguntar. > **Etiquetas de lo que creas.** `./gestionar-ciclo-de-vida.sh crear` etiqueta el bucket con `curso` = `G214`, `universidad` = `CUNEF`, `actividad` = `02.07-ejercicioaciclodevida` y `script` = `gestionar-ciclo-de-vida.sh`. Las verás en la consola (pestaña *Tags* del recurso) y, si hiciera falta borrar a mano, se localizan con `aws resourcegroupstaggingapi get-resources --region eu-north-1 --tag-filters Key=actividad,Values=02.07-ejercicioaciclodevida`. Más detalle (cómo etiquetar con la CLI, cómo buscar y qué hacer en una emergencia): [README principal](../../README.md), sección «Etiquetas». ## Qué vas a hacer **Contexto.** El área de estudios de un banco publica cada mes un informe con el padrón municipal. Los ficheros se consultan mucho el primer mes, poco el segundo y casi nunca a partir del tercero, pero hay que conservarlos cinco años. Vas a montarlo en S3 con una **regla de ciclo de vida** que mueve los objetos a clases más baratas con el tiempo, y a calcular cuánto se ahorra. ``` padron/anio=2023/padron_2023.csv ─┐ 0-30 días: Standard padron/anio=2024/padron_2024.csv ─┼─► 30 días: Standard-IA padron/anio=2025/padron_2025.csv ─┘ 90 días: Glacier Instant Retrieval → 1.825 días (5 años): caduca ``` ## Qué se crea en AWS Un bucket `g214--padron` con los tres CSV en `padron/anio=YYYY/` y una regla de ciclo de vida llamada `padron-ciclo-vida`. ## Qué contiene esta carpeta | Fichero | Para qué sirve | Se usa en | |---|---|---| | `gestionar-ciclo-de-vida.sh` | **Todo el ejercicio en un script**: `crear` (descarga, divide, crea el bucket, sube y aplica la regla), `estado`, `eliminar` (fuerza el borrado) y `extraer` (escribe `lifecycle-padron.json`). Ver «Camino rápido» | Todos los pasos | | `descargar-datos.sh` | Descarga el padrón del INE (`dataset.csv`, 26 MB; todos los años, 1996-2025) con reintentos y validación; también `estado` y `eliminar` | Paso 1 | | `dividir-padron.sh` | Parte `dataset.csv` en `padron_2023.csv`, `padron_2024.csv` y `padron_2025.csv` (24.414 filas cada uno). También `./dividir-padron.sh estado` (qué `padron_*.csv` hay) y `./dividir-padron.sh eliminar [--si]` (los borra) | Paso 2 | | `lifecycle-padron.json` | Regla de ciclo de vida: Standard-IA a los 30 días, Glacier Instant Retrieval a los 90, caduca a los 1.825 | Paso 4 (vía CLI) | | `vaciar-bucket.py` | Vacía un bucket con versiones (solo si activaste el versionado); `--si`, `--estado` y `--ayuda` | Limpieza | ## Antes de empezar - [ ] Has hecho [`02.01-s3primerbucket`](../02.01-s3primerbucket/README.md) (sabes crear un bucket y usar CloudShell). - [ ] CloudShell abierto en **eu-north-1**. Sube esta carpeta (zip de `02.07-ejercicioaciclodevida`, *Actions → Upload file*) y entra: ```bash unzip -o 02.07-ejercicioaciclodevida.zip cd 02.07-ejercicioaciclodevida chmod -R u+rwX . && chmod +x *.sh ``` > Si ya subiste `g214-materiales.zip` (README principal), no necesitas este zip: entra con `cd ~/g214-materiales/tema2/02.07-ejercicioaciclodevida` y, si algún fichero da `Permission denied`, ejecuta allí `chmod -R u+rwX . && chmod +x *.sh`. - [ ] Nombre de bucket único en todo el mundo: `g214--padron` (añade un sufijo si ya existe). ## Camino rápido: un solo script (`gestionar-ciclo-de-vida.sh`) Hace los pasos 1 a 4 por ti, con comprobaciones y mensajes en español, y se puede repetir sin riesgo. Los pasos «a mano» de abajo siguen valiendo y son los de las diapositivas; usa uno u otro camino. ```bash ./gestionar-ciclo-de-vida.sh # con terminal: menú numerado (sin terminal: muestra la ayuda) ./gestionar-ciclo-de-vida.sh crear # te pregunta tu apellido (propone un nombre) y recuerda el bucket en .gestionar-ciclo-de-vida.conf ./gestionar-ciclo-de-vida.sh crear --apellido garcia # sin preguntar: bucket g214-garcia-padron (o --bucket g214-garcia-padron) ./gestionar-ciclo-de-vida.sh estado # bucket, objetos con su StorageClass, regla de ciclo de vida y ficheros locales (no modifica nada) ./gestionar-ciclo-de-vida.sh eliminar # pide confirmación; con --si no pregunta. FUERZA el borrado (versiones incluidas) y limpia los ficheros locales ./gestionar-ciclo-de-vida.sh extraer # escribe lifecycle-padron.json (la regla que lleva embebida) ./gestionar-ciclo-de-vida.sh ayuda ``` **Qué hace `crear`** (6 pasos numerados): comprueba la CLI v2, tus credenciales y la región `eu-north-1`; descarga y valida `dataset.csv`; lo divide en `padron_2023.csv`, `padron_2024.csv` y `padron_2025.csv` (con `--anios 2022,2023` eliges otros); crea el bucket (si el nombre es de otra cuenta, te lo dice antes de descargar nada); sube cada CSV a `padron/anio=YYYY/` (salta los que ya están) y aplica la regla `padron-ciclo-vida`, que vuelve a leer para confirmarla. La división por año y la regla son las de los pasos 2 y 4 (misma salida: 24.414 filas por año). La parte de AWS de este script (probada en AWS real): si algo falla, te dice qué ha pasado y qué hacer. ## Paso a paso ### Paso 1 · Descarga el padrón El INE publica **una sola tabla** con todos los años; no hay un CSV por año. ```bash ./descargar-datos.sh padron # dataset.csv (26 MB, separador ";") ``` ### Paso 2 · Divídelo por año ```bash ./dividir-padron.sh dataset.csv # padron_2023.csv, padron_2024.csv y padron_2025.csv (24.414 filas cada uno) ``` Si hiciste el laboratorio de versionado y renombraste el CSV, usa `dataset_ine.csv` como argumento. ### Paso 3 · Crea el bucket y sube los CSV por año ```bash aws s3 mb s3://g214-apellido-padron --region eu-north-1 for a in 2023 2024 2025; do aws s3 cp padron_$a.csv s3://g214-apellido-padron/padron/anio=$a/; done ``` El prefijo `anio=YYYY` te servirá después en el Tema 4 para particionar en Athena. ### Paso 4 · Crea la regla de ciclo de vida **Por consola** (como en la diapositiva): S3 → tu bucket → **Management → Lifecycle rules → Create lifecycle rule**. Ámbito: prefijo `padron/`. Marca *Move current versions of objects between storage classes* y añade las dos transiciones (Standard-IA a 30 días, Glacier Instant Retrieval a 90); marca *Expire current versions of objects* con **1.825** días. **O por CLI**, con el JSON de esta carpeta: ```bash aws s3api put-bucket-lifecycle-configuration --bucket g214-apellido-padron --lifecycle-configuration file://lifecycle-padron.json aws s3api get-bucket-lifecycle-configuration --bucket g214-apellido-padron aws s3api head-object --bucket g214-apellido-padron --key padron/anio=2024/padron_2024.csv --query StorageClass ``` **Qué verás:** - `get-bucket-lifecycle-configuration` devuelve la regla `padron-ciclo-vida` con `STANDARD_IA` a 30 días, `GLACIER_IR` a 90 y `Expiration.Days: 1825` (la CLI reciente añade además `TransitionDefaultMinimumObjectSize`). - `head-object --query StorageClass` imprime `null` (o `None` con `--output text`) mientras el objeto sea STANDARD: es lo normal. Las transiciones se ejecutan **una vez al día** y la primera es a los 30 días: en clase se comprueba la regla, no el resultado. ### Paso 5 · Calcula el ahorro en calculator.aws En (región Europe (Stockholm)) estima el coste mensual de S3 **con y sin la regla**, suponiendo **200 GB hipotéticos** y 50.000 GET al mes. Precios de referencia de `eu-north-1` (verifícalos): Standard ≈ 0,023 USD/GB-mes · Standard-IA ≈ 0,0125 · Glacier IR ≈ 0,004. Con 200 GB repartidos en 60 entregas mensuales (1 en Standard, 2 en Standard-IA y 57 en Glacier IR): unos **4,60 USD/mes** sin regla frente a unos **0,92 USD/mes** con regla. Ahorro anual: (4,60 − 0,92) × 12 ≈ **44 USD**. ### Paso 6 · Responde por escrito **¿Qué penalización tiene recuperar un objeto en Glacier Instant Retrieval?** (cifras de lista de referencia: verifícalas en calculator.aws). Recuperar cuesta unos **0,03 USD/GB** (Standard-IA, unos 0,01 USD/GB; Standard no cobra recuperación). El acceso sigue siendo en milisegundos, pero hay una **permanencia mínima de 90 días** (Standard-IA: 30) y **128 KB mínimos facturables por objeto**: si borras el objeto o lo cambias de clase antes, pagas igualmente el resto del periodo. Con acceso frecuente, Standard sale más barato: la clase se elige por el patrón de acceso. **Entregable:** captura de la regla de ciclo de vida, PDF de la estimación (*Export → PDF*) y un párrafo con la conclusión. ## Errores frecuentes | Qué ves | Causa | Solución | |---|---|---| | `BucketAlreadyExists` | El nombre es global y ya existe | Cambia el nombre (sufijo propio) | | `dividir-padron.sh` no encuentra el CSV | Se llama `dataset_ine.csv` o está en otra carpeta | Pásalo como argumento: `./dividir-padron.sh dataset_ine.csv` | | `dataset.csv` pesa unos pocos KB | La descarga devolvió una página de error | `./descargar-datos.sh estado` dice el motivo; repite con `./descargar-datos.sh padron --forzar` | | `StorageClass` imprime `null` | Es lo normal mientras el objeto sea STANDARD | Las transiciones se ejecutan una vez al día; en clase se verifica la regla | ## Limpieza Lo más fácil: `./gestionar-ciclo-de-vida.sh eliminar` (vacía el bucket con todas sus versiones, lo borra y limpia los ficheros locales). A mano: sin versionado, `aws s3 rb s3://g214-apellido-padron --force`; si activaste el versionado, `python3 vaciar-bucket.py g214-apellido-padron --borrar`. Comprueba con `aws s3 ls | grep g214` que no queda ningún bucket tuyo. ## Cómo sabes que has terminado - [ ] Tres CSV en `padron/anio=2023|2024|2025/` y la regla `padron-ciclo-vida` visible con `get-bucket-lifecycle-configuration`. - [ ] Tienes la estimación en PDF y la respuesta sobre la penalización de Glacier IR. - [ ] Sabes por qué no ves el cambio de clase hoy. - [ ] Bucket borrado. Anterior: [`02.06-laboratoriocafeteria`](../02.06-laboratoriocafeteria/README.md) · Siguiente: [`02.08-ejerciciobdatosabiertos`](../02.08-ejerciciobdatosabiertos/README.md)