# Tema 3 · 2 · Desplegar Adminer y conectar con tu RDS Diapositivas del Tema 3: 39 y 40 (cliente SQL y formulario de entrada; la carga de la base, diapositivas 41 y 42, está en [03.03](../03.03-sqlestudiantes/README.md)). Duración: 2 a 5 minutos de despliegue (medido con la versión anterior de los scripts: 35 s el script A y 1 min la plantilla B hasta crear la instancia; Adminer responde ~1 min 20 s después) más unos 5 minutos de subida de ficheros. Coste: una EC2 `t3.small` por hora encendida; se apaga sola a las 4 horas (ampliable, ver «Apagado automático») y apagada solo factura su disco. **Sobre esta versión de los scripts.** Se han reescrito para que un alumno no tenga que depurar nada: cada script es **un solo fichero** (la plantilla de CloudFormation va dentro), tiene los mismos comandos (`crear`, `estado`, `extender`, `eliminar`, `arrancar`, `--grant-rds`, `extraer`, `ayuda`) y un menú numerado, y `eliminar` borra **todo** a la fuerza y se puede repetir. Se han probado de extremo a extremo en una cuenta real de AWS (los dos modos, `cli` y `cloudformation`, con todas sus opciones). > **¿Dudas con un script?** Todos los scripts de esta carpeta traen su propia ayuda: `./gestionar-adminer.sh --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-adminer.sh crear` etiqueta la instancia, su disco, el Security Group y el stack con `curso` = `G214`, `universidad` = `CUNEF`, `actividad` = `03.02-adminer` y `script` = `gestionar-adminer.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=03.02-adminer`. 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 Vas a levantar **Adminer**, un cliente web de bases de datos (una sola página PHP con la que entras a tu RDS, lanzas SQL, importas y exportas), en una EC2 propia, y vas a conectarlo con la RDS que creaste en [03.01](../03.01-RDSMariaDB.md). Hay tres formas; elige **UNA** de las dos primeras (A o B), y la C solo si quieres un Adminer en tu PC. ``` CloudShell ──(script A o B)──> EC2 Adminer (Apache + PHP, puerto 80) │ regla: Security Group Adminer ──> puerto 3306 ▼ tu RDS MariaDB ``` **Qué se crea en AWS:** | Pieza | Qué crea en AWS | |---|---| | Opción A (`gestionar-adminer.sh crear`) | 1 instancia EC2 `G214-Adminer` (t3.small, Amazon Linux 2023 con Apache, PHP y Adminer), 1 Security Group `g214-adminer-sg-` con el puerto 80 abierto y, solo si se lo pides (el script te pregunta a qué RDS), una regla de entrada (puerto 3306 o 5432) en el Security Group de **esa** RDS | | Opción B (`gestionar-adminer.sh crear --modo cloudformation`) | 1 stack de CloudFormation `cunef-adminer` con la instancia `G214-AdminerWebserver` y su Security Group, más, si se lo pides, la misma regla de entrada en la RDS que indiques (esa regla queda fuera del stack) | | Opción C (Docker en tu PC) | Nada en AWS | ## Qué contiene esta carpeta | Fichero | Para qué sirve | En qué paso se usa | |---|---|---| | `gestionar-adminer.sh` | Un solo script autónomo que gestiona Adminer: `crear` lo despliega con comandos de la AWS CLI (opción A, por defecto) o con CloudFormation si añades `--modo cloudformation` (opción B, stack `cunef-adminer`) | Pasos 2A y 2B | | `README.md` | Esta guía | Siempre | Cada script **lleva todo dentro**: la plantilla de CloudFormation y lo que se instala en la máquina van embebidos al final del fichero (entre las marcas `INICIO ARCHIVO EMBEBIDO` y `FIN ARCHIVO EMBEBIDO`). No hace falta subir nada más. Si necesitas la plantilla suelta (por ejemplo, para pegarla en la consola de CloudFormation, apartado «Opción B desde la consola»), el comando `extraer` la escribe en la carpeta actual: ```bash ./gestionar-adminer.sh extraer # escribe plantilla-adminer.yaml en la carpeta actual ./gestionar-adminer.sh extraer mi-carpeta # o en la carpeta que indiques ``` Hay **un solo script** con dos formas de desplegar: por defecto `cli` (opción A) y, con `--modo cloudformation`, un stack de CloudFormation (opción B). Para `estado`, `extender`, `eliminar`, `arrancar`, `crear` (si ya existe) y `--grant-rds` no hace falta indicar el modo: el script detecta con cuál lo creaste. Fichero que genera el script al crear: `informacion_adminer.txt` (con la IP y la URL, en la carpeta donde lo lances). Ya **no** hay fichero de estado oculto: los scripts encuentran lo que han creado consultando AWS (por la etiqueta `Name` de la instancia, el nombre del Security Group o el nombre del stack), así que puedes lanzarlos desde cualquier carpeta. ### Comandos | Comando | Alias antiguo | Qué hace | |---|---|---| | `crear [--horas N] [--permanente]` | `--create` | Despliega Adminer; se apaga sola a las 4 h (`--horas` admite 1-24). Si ya existe, **no crea otro**: arranca la instancia si está parada y renueva el plazo | | `estado` | `--status`, `--info` | Muestra qué hay creado, su estado, la URL actual y la línea «Apagado automático» | | `eliminar` | `--delete` | Borra **todo** lo creado, de forma forzada y repetible; pide confirmación (se omite con `--si`) | | `extender [--horas N\|--permanente]` | | Solo cambia el plazo de apagado automático (por defecto, otras 4 h desde ahora) | | `arrancar` | | Igual que `crear` sobre lo ya existente: arranca la instancia parada y renueva el plazo | | `--grant-rds [NOMBRE_RDS] [--yes]` | igual | Da acceso a UNA de tus RDS desde Adminer | | `extraer [CARPETA]` | | Escribe la plantilla de CloudFormation embebida | | `ayuda` | `--help`, `-h` | Muestra el uso | ### Apagado automático - Adminer se **apaga solo a las 4 horas** de crearlo (para que no se quede encendido y facturando si te olvidas). Al vencer **se apaga, no se borra**: la instancia queda `stopped` y solo `eliminar` la borra. - **Ampliar**: vuelve a ejecutar `./gestionar-adminer.sh crear` (arranca la instancia si estaba parada y concede otras 4 h; también vale `arrancar`) o `extender` (solo cambia el plazo). Con `--horas N` (1-24) eliges otro plazo. - **Permanente**: `./gestionar-adminer.sh crear --permanente` (o `extender --permanente`); `estado` avisará con «PERMANENTE (¡ojo con el coste!)». - `estado` muestra siempre la línea «Apagado automático: se apagará a las HH:MM UTC (dentro de N min)», `PERMANENTE` o «ya se apagó: ejecuta `crear`». - Cómo funciona: la instancia lleva la etiqueta `g214-apagar-tras` (hora de vencimiento o `permanente`) y un servicio interno la lee cada 30 s. Si la arrancas a mano con el plazo vencido, tiene 60 min de gracia. Opciones: `--si` (o `-y`, `--yes`) no pide confirmación; `--modo cli|cloudformation` elige la forma de desplegar; `--rds NOMBRE` (con `crear`) da acceso a esa RDS nada más crear. **Sin comando y con terminal interactiva se abre un menú numerado**; sin terminal (por ejemplo, desde otro script) imprime el uso y termina sin quedarse esperando. ## Antes de empezar - [ ] Tienes la RDS MariaDB creada y en estado `Available` ([03.01](../03.01-RDSMariaDB.md)). Sin ella, Adminer se despliega igual pero no podrás conectarte a nada, y los scripts solo ven las RDS que existen en ese momento. - [ ] Región de la consola `eu-north-1`, elegida ANTES de abrir CloudShell. - [ ] Sabes tu endpoint, el usuario `admin` y tu contraseña. - [ ] Un navegador desde el que puedas abrir `http:///adminer.php` (si tu red muestra `Web Filter Violation` o `Access Blocked`, es el filtro web de tu red: prueba con otra red, por ejemplo los datos del móvil). ## Cómo llevar los ficheros a donde toque Los ficheros los tienes en tu PC; CloudShell es otro ordenador. Para no subirlos uno a uno, súbelos en un solo zip. 1. En tu PC, **comprime esta carpeta** (la carpeta entera, no solo su contenido): clic derecho sobre `03.02-adminer` y *Comprimir en archivo ZIP* (Windows 11), *Enviar a > Carpeta comprimida en zip* (Windows 10) o *Comprimir* (Mac). Obtienes `03.02-adminer.zip`. 2. En la consola de AWS, comprueba que la región es `eu-north-1` y abre CloudShell. Espera a que aparezca el prompt. 3. Pulsa **Actions** > **Upload file**, elige `03.02-adminer.zip` y sube el fichero. 4. Descomprime, entra en la carpeta y deja los scripts listos: ```bash unzip -o 03.02-adminer.zip && cd 03.02-adminer sed -i 's/\r$//' *.sh chmod -R u+rwX . && chmod +x *.sh ls ``` > Si ya subiste `g214-materiales.zip` (README principal), no necesitas este zip: entra con `cd ~/g214-materiales/tema3/03.02-adminer` y, si algún fichero da `Permission denied`, ejecuta allí `chmod -R u+rwX . && chmod +x *.sh`. Qué hace cada línea: `unzip -o` descomprime (el `-o` sobrescribe sin preguntar si subes el zip otra vez) y `cd` entra en la carpeta; `sed -i 's/\r$//'` quita los finales de línea de Windows de los scripts (si no se quitan, bash falla con `bad interpreter: /bin/bash^M` o `$'\r': command not found`; si ya estaban bien, no cambia nada); `chmod +x` da permiso de ejecución (un zip creado en Windows no lo conserva; sin él, `./gestionar-adminer.sh` da `Permission denied`; también puedes lanzarlo con `bash gestionar-adminer.sh crear`). Qué verás: `ls` muestra `gestionar-adminer.sh` y `README.md`. Si no ves la carpeta, el zip se descomprimió en otro sitio: `ls` desde tu carpeta personal te dice dónde. Alternativa para subir solo un fichero: **Actions** > **Upload file** y elige el script (es autónomo), y luego `sed -i 's/\r$//' gestionar-adminer.sh && chmod +x gestionar-adminer.sh`. Si cierras CloudShell y vuelves más tarde, entra de nuevo con `cd 03.02-adminer` (tu carpeta personal normalmente se conserva entre sesiones de la misma región; si no la encuentras, vuelve a subir el zip). A diferencia de la versión anterior, **ya no importa desde qué carpeta lances el script**: lo que ha creado se averigua consultando AWS. ## Paso a paso **Paso 1. Comprobar CloudShell y elegir opción.** ```bash aws sts get-caller-identity echo "$AWS_REGION" ``` Qué verás: un JSON con tu cuenta y `eu-north-1`. El script trabaja **siempre en `eu-north-1`** (la región del curso); si tu terminal está en otra región, lo avisan en amarillo justo después de mostrar la región (cierra CloudShell, cambia la región de la consola a Estocolmo y vuelve a abrirlo, para que la consola web y el script vean lo mismo). Qué tienen en común las dos opciones: - La misma máquina: Amazon Linux 2023 (la AMI más reciente, resuelta por SSM) con Apache, PHP y Adminer, que se descarga de `adminer.org` (`latest-mysql.php`, la edición para MySQL/MariaDB) y queda en `/adminer-core.php`; `/adminer.php` es un envoltorio de siete líneas que activa el cifrado TLS hacia la RDS (necesario con MariaDB 11.x) y carga el anterior. Tú abres siempre `/adminer.php`. Tipo de instancia por defecto: `t3.small` (`INSTANCE_TYPE=t3.micro ./gestionar-adminer.sh crear` lo cambia; en el modo `cloudformation` solo se admiten `t3.micro`, `t3.small` y `t3.medium`; el cambio con la opción B). - Se lanzan en la VPC por defecto de la región, en una subred con IP pública. Si no hay VPC por defecto, el script se detiene con un mensaje que dice cómo crearla. - Su Security Group abre el puerto 80 (HTTP, sin cifrar) a cualquier IP. No abre nada más, salvo en la opción B desplegada desde la consola si indicas un `KeyName`: entonces abre también el 22 (SSH). - **Se apagan solas a las 4 horas** (se apagan, no se borran): ver «Apagado automático». - Admiten subir ficheros de hasta **100 MB** (límites de PHP ajustados y `php-fpm` reiniciado al instalar). - **Dan acceso de red a UNA de tus RDS, la que tú indiques**: al crearse, listan las RDS de la región, te preguntan a cuál das acceso (Enter = a ninguna), te enseñan la regla que van a añadir y piden confirmación (`s`). La regla (puerto 3306 o 5432, el de esa RDS) se añade solo en el Security Group de esa RDS, con la descripción `G214-Adminer` (así el script reconoce después lo que añadió él); las demás RDS de la cuenta no se tocan (salvo que compartan Security Group: el script lo avisa). Si creas la RDS después, o quieres dar acceso a otra, repítelo con `--grant-rds NOMBRE_DE_LA_RDS`. Si no hay entrada por teclado (por ejemplo, sin terminal), no se concede nada salvo que uses `crear --rds NOMBRE --si` o `--grant-rds NOMBRE --yes`. - Al eliminar, los dos quitan esa regla (solo las reglas cuyo origen es el Security Group de Adminer o llevan la descripción `G214-Adminer`; el resto del Security Group de tu RDS no se toca): AWS no deja borrar un Security Group mientras otro lo referencia. - Resilientes: comprueban la AWS CLI y las credenciales al empezar, reintentan solos si AWS responde «Throttling», esperan con un máximo y enseñan el progreso, y si algo falla dicen qué ha pasado y qué hacer, sin trazas. - Necesitan la AWS CLI con credenciales válidas (en CloudShell ya las tienes) y bash. No necesitan `jq` ni Python. Comparativa: | | A: `crear` (por defecto) | B: `crear --modo cloudformation` | |---|---|---| | Cómo despliega | Comandos sueltos `aws ec2` / `aws rds` | CloudFormation (stack `cunef-adminer`) | | Ficheros necesarios | Solo el script | Solo el script (la plantilla va dentro) | | Cómo se maneja | Menú numerado o comandos (`crear`, `estado`, `extender`, `eliminar`, `arrancar`, `--grant-rds`, `extraer`) | Igual: la misma interfaz | | Nombre de la instancia | `G214-Adminer` | `G214-AdminerWebserver` | | Dónde queda lo creado | En AWS (instancia y Security Group, que el script encuentra por su etiqueta o su nombre) | En AWS (stack visible en CloudFormation) | | Ver la IP tras reiniciar | `estado` consulta la IP actual | `estado` consulta la IP actual (los Outputs del stack pueden mostrar la anterior) | | Cambiar el tipo de instancia | `INSTANCE_TYPE=t3.micro ./gestionar-adminer.sh crear` | `INSTANCE_TYPE=t3.micro ./gestionar-adminer.sh crear --modo cloudformation` | | Borrar | `eliminar` (forzado) | `eliminar` (forzado, aunque el stack esté en `ROLLBACK_COMPLETE` o `DELETE_FAILED`) | Cuándo elegir: **B (CloudFormation)** si dudas: lo creado se ve y se borra como una unidad en la consola de CloudFormation y funciona igual que los scripts de los temas 4 y 5; es también tu plan B si la A no levanta Adminer. **A (script)** si no quieres pasar por CloudFormation. **No despliegues las dos a la vez**: tendrías dos máquinas y dos Security Groups facturando, y cada una añadiría sus propias reglas en tu RDS (el script avisa si detecta un Adminer del otro modo). ### Paso 2A. Opción A: `gestionar-adminer.sh` Solo te pregunta por teclado a qué RDS dar acceso (puedes pulsar Enter para no dar acceso a ninguna). ```bash ./gestionar-adminer.sh crear ``` Si lo lanzas sin nada (`./gestionar-adminer.sh`) se abre el menú numerado: elige `1) Crear`. Qué verás, en este orden (cada línea lleva un símbolo al principio; la secuencia exacta de mensajes de esta versión): ``` G214 - Instalación de Adminer Región: eu-north-1 Buscando VPC por defecto... VPC: vpc-... Buscando una subred pública... Subred: subnet-... Resolviendo la AMI más reciente de Amazon Linux 2023... AMI: ami-... Preparando Security Group... Security Group: sg-... Lanzando instancia EC2 (t3.small)... Instancia lanzada: i-... Buscando instancias RDS existentes en eu-north-1... RDS encontradas en eu-north-1: 1) nombre-base-datos (mariadb, puerto 3306, Security Group sg-...) ¿A cuál das acceso desde Adminer? (número o nombre; Enter = a ninguna): 1 Se va a añadir esta regla de entrada (solo en la RDS elegida): Security Group sg-... (el de nombre-base-datos): TCP 3306 <- Security Group de Adminer (sg-...) ¿Continuar? [s/N]: s Acceso concedido: sg-... puerto 3306 <- Adminer (sg-...) Adminer ya puede administrar la RDS nombre-base-datos. Esperando a que la instancia esté en marcha... Listo G214 - Adminer Instancia: i-... IP pública: URL: http:///adminer.php (más notas sobre el apagado automático y la nueva IP) Apagado automático: se apagará a las HH:MM UTC (dentro de 240 min). (...) Bórrala con 'eliminar' cuando ya no la necesites. ``` Tarda unos 35 segundos (medido con la versión anterior, sin contar lo que tardes en contestar a la pregunta de la RDS). La IP y la URL también quedan guardadas en `informacion_adminer.txt` (`cat informacion_adminer.txt`). Si no tienes ninguna RDS todavía, verás `No hay ninguna instancia RDS todavía en eu-north-1` y una línea que te dice que ejecutes `./gestionar-adminer.sh --grant-rds NOMBRE_DE_LA_RDS` cuando la crees. Si contestas con Enter, o el script no recibe entrada por teclado, no se concede acceso a nada (`No se ha concedido acceso a ninguna RDS`) y la creación continúa igual. Un número o un nombre que no está en la lista da `No se ha cambiado nada`. Si contestas `n` (o cualquier cosa distinta de `s`) a `¿Continuar?`, dice `No se ha cambiado nada`. Para saltarte las preguntas: `./gestionar-adminer.sh crear --rds nombre-base-datos --si`. El script termina cuando la instancia está en marcha, pero Apache, PHP y Adminer se instalan después, dentro de la máquina. El propio script avisa de que puede tardar «~1 minuto»; medido: respondió al cabo de 1 min 15 s. Dale unos minutos antes de dudar. Después, ve al **Paso 3**. **Las demás opciones de la A:** ```bash ./gestionar-adminer.sh estado # estado de la instancia y su URL actual ./gestionar-adminer.sh arrancar # arranca la instancia si está parada y renueva el plazo ./gestionar-adminer.sh extender --horas 6 # solo cambia el plazo (o --permanente) ./gestionar-adminer.sh --grant-rds # lista tus RDS y te pregunta a cuál dar acceso ./gestionar-adminer.sh --grant-rds NOMBRE_RDS # da acceso a esa RDS (pide confirmación; con --yes no pregunta) ./gestionar-adminer.sh eliminar # borra TODO (pide confirmación; con --si no pregunta) ./gestionar-adminer.sh extraer # escribe plantilla-adminer.yaml en la carpeta actual ./gestionar-adminer.sh ayuda # uso completo ``` - `estado` (antes `--info`) escribe `Estado de tu Adminer`, la instancia con su estado (`running`, `stopped`...) y, si está en marcha, `URL: http:///adminer.php` y si la aplicación ya responde. Termina con la línea «Apagado automático»: cuándo se apagará, `PERMANENTE`, o «ya se apagó: ejecuta `crear` para arrancarlo y ampliar el plazo» si está parada. - `arrancar` (igual que volver a ejecutar `crear`) arranca la instancia parada, renueva el plazo de apagado automático, espera a que esté en marcha y te enseña la **URL nueva** (la IP cambia en cada parada y arranque). - `--grant-rds` escribe `Concediendo acceso a RDS`, la lista de tus RDS (o usa la que le des por nombre), la regla que va a añadir y `¿Continuar? [s/N]`; después `Acceso concedido: ...`. Si esa regla ya existía dice `La RDS ya tenía concedido el acceso desde este Security Group.` Si el nombre no existe, termina con error (`No hay ninguna RDS llamada ...`) sin tocar nada. Solo cambia el Security Group de la RDS elegida: las reglas van en el Security Group, no en cada RDS, así que si dos RDS comparten el mismo Security Group (por ejemplo `BaseDeDatos`), dar acceso a una lo da también a la otra (el script lo avisa). `--yes` omite la confirmación (úsalo solo cuando ya sepas qué RDS es). - `eliminar` (antes `--delete`) enseña lo que va a borrar y pide confirmación (`--si` la omite). Después, **a la fuerza y en este orden**: quita de tu RDS las reglas de acceso que añadió, termina la instancia (si tuviera protección contra terminación, la desactiva), borra el Security Group reintentando hasta unos 3 minutos (AWS tarda en liberarlo) y limpia volúmenes sueltos. Al final hace una **comprobación** y escribe qué queda (`Instancias EC2: ninguna`, `Security Groups: ninguno`...) y `Limpieza completa`. Es idempotente: si lo repites, o si borraste algo a mano, no falla: borra lo que quede y confirma. Si algo no se pudo borrar, lo dice y sale con error: espera un minuto y repite `./gestionar-adminer.sh eliminar`. **Qué pasa si repites la A:** | Ejecutas | Resultado | |---|---| | `./gestionar-adminer.sh crear` con Adminer ya creado | No crea otra instancia: escribe `Ya tienes una instancia de Adminer creada; no creo otra.`, muestra su estado y te recuerda `eliminar` | | `crear` desde OTRA carpeta | Funciona igual (no hay fichero de estado): detecta la instancia existente en AWS | | `crear` con un Security Group suelto de un intento anterior | Lo reutiliza en vez de crear otro | | `--grant-rds` varias veces | No pasa nada: si la regla ya existe se salta sin error | | `--grant-rds NOMBRE_RDS` y no hay ninguna RDS en la región | Avisa (`No hay ninguna instancia RDS todavía en `) y termina con código de salida 1; sin nombre solo avisa y termina con 0 | | `estado`, `--grant-rds`, `arrancar` sin Adminer | Avisan de que no hay ninguna instancia de Adminer y de cómo crearla; `eliminar` dice que no hay nada que borrar | | Cualquier otro argumento | Muestra el error y el uso, y termina con código 2 | ### Paso 2B. Opción B: `gestionar-adminer.sh crear --modo cloudformation` (CloudFormation) Solo necesitas el script (la plantilla va dentro) y permiso de ejecución. Comprueba al empezar que la AWS CLI y las credenciales funcionan; si no, termina con un error que dice qué hacer. ```bash ./gestionar-adminer.sh --modo cloudformation ``` Qué verás: el encabezado `G214 - Adminer (cloudformation)`, `Región: eu-north-1 Modo: cloudformation` y un menú numerado, que se repite después de cada acción hasta que eliges `0) Salir`: | Opción | Qué hace | |---|---| | 1) Crear | Detecta tu VPC por defecto y una subred pública, crea el stack, espera a `CREATE_COMPLETE`, muestra la tabla de Outputs y te pregunta a qué RDS dar acceso (Enter = a ninguna). Si el stack ya existe, arranca la instancia si está parada y renueva el plazo (pregunta antes el plazo: Enter = 4 h, un número de horas o `p` = permanente) | | 2) Comprobar estado / ver URL | Muestra el estado del stack, la instancia, su URL actual y los Outputs | | 3) Conceder acceso a una de tus RDS | Lista tus RDS, te pregunta a cuál y, con confirmación, añade la regla de entrada en el Security Group de esa RDS | | 4) Eliminar TODO (borrado forzado) | Quita la regla de acceso de tu RDS y borra el stack y todo lo que dependa de él, aunque esté en `ROLLBACK_COMPLETE` o `DELETE_FAILED` | | 5) Arrancar la instancia parada (y renovar el plazo) | Arranca la instancia si el apagado automático la paró y renueva el plazo | | 6) Extraer la plantilla CloudFormation embebida | Escribe `plantilla-adminer.yaml` en la carpeta actual | | 7) Ayuda | Muestra el uso | | 8) Ampliar el plazo de apagado automático / hacerlo permanente | Pregunta el plazo (Enter = 4 h, horas 1-24 o `p` = permanente) y solo cambia el plazo | | 0) Salir | Sale | También admite modo directo, sin menú (los alias antiguos siguen funcionando): ```bash ./gestionar-adminer.sh crear --modo cloudformation # opción 1 (o --create) ./gestionar-adminer.sh estado # opción 2 (o --status) ./gestionar-adminer.sh --grant-rds # opción 3 (te pregunta la RDS) ./gestionar-adminer.sh --grant-rds NOMBRE_RDS [--yes] # sin preguntar la RDS ./gestionar-adminer.sh eliminar [--si] # opción 4 (o --delete) ./gestionar-adminer.sh arrancar # opción 5 ./gestionar-adminer.sh extender [--horas N|--permanente] # opción 8 ./gestionar-adminer.sh extraer # opción 6 ``` Para crear el stack, escribe `1` y Enter (o usa `crear`). Qué verás (medido con la versión anterior: 61 segundos): `Creando el stack de Adminer`, la VPC y la subred detectadas, `Creando stack 'cunef-adminer'...`, `Stack en creación. Esperando a CREATE_COMPLETE...`, `Stack creado correctamente` y una tabla con los Outputs: `InstanceId`, `PublicIP`, `AdminerURL` y `SecurityGroupId`. Después te pregunta a qué RDS dar acceso (como en la A: lista, regla que va a añadir y `¿Continuar? [s/N]`; Enter = a ninguna; `Acceso concedido: ...`, o `No hay ninguna instancia RDS todavía en eu-north-1`), escribe el resumen con la URL y termina con `Apagado automático: se apagará a las HH:MM UTC (dentro de 240 min).` (secuencia de mensajes de esta versión). Copia la URL (`http:///adminer.php`). Apache, PHP y Adminer se instalan después de `CREATE_COMPLETE`, dentro de la máquina: el propio stack avisa de que puede tardar «~1 minuto» en responder. Después, ve al **Paso 3**. **Qué pasa si repites la B:** - Con el stack ya creado, `crear` (o escribir `1` en el menú) no crea nada: avisa `El stack 'cunef-adminer' ya existe (estado: ...)` y muestra su estado. - Si el stack quedó a medias de un intento anterior (`ROLLBACK_COMPLETE`, `CREATE_FAILED`...), `crear` lo elimina por completo antes de crear uno nuevo, en vez de pedirte que lo hagas tú. Si la creación falla, el script enseña los motivos que informa CloudFormation. - `--grant-rds` se puede repetir sin problema: si la regla ya existe se salta. - Sin stack, `estado`, `--grant-rds` y `arrancar` avisan de que no hay nada y `eliminar` dice que no hay nada que borrar. - Un número que no está en el menú escribe `Opción no válida`; un argumento desconocido escribe el error y el uso. **Opción B desde la consola (sin el script).** Si prefieres hacerlo tú con la plantilla: 1. Escribe la plantilla en tu carpeta con `./gestionar-adminer.sh extraer` (en CloudShell; luego descarga `plantilla-adminer.yaml` con **Actions** > **Download file**), o ejecútalo en tu PC con Git Bash/WSL. Consola de AWS (región `eu-north-1`) > **CloudFormation** > **Create stack** > **With new resources (standard)** > **Upload a template file** > `plantilla-adminer.yaml` > **Next**. 2. Nombre del stack: `cunef-adminer`. Conviene usar exactamente ese nombre: el script lo busca por él para `eliminar` (si usaste otro, lánzalo con `G214_STACK=tu-nombre ./gestionar-adminer.sh eliminar`). 3. Parámetros: `VpcId` (la VPC por defecto, normalmente la única), `SubnetId` (una subred pública de esa VPC), `InstanceType` (`t3.small` por defecto), `LatestAmiId` (déjalo como está), `KeyName` (opcional: solo si quieres entrar por SSH; déjalo vacío) y `SSHLocation` (solo cuenta si rellenas `KeyName`). 4. **Next** > **Next** > **Create stack**. Esta plantilla no crea recursos de IAM, así que no hay casilla que marcar. Espera a `CREATE_COMPLETE`. 5. Pestaña **Outputs**: abre `AdminerURL`. Apunta también `SecurityGroupId`. 6. Desde la consola NO se da acceso a tu RDS automáticamente. Dos formas: (a) en CloudShell, `./gestionar-adminer.sh --grant-rds` (te pregunta la RDS; encuentra la instancia por su etiqueta `G214-AdminerWebserver`), o (b) a mano: EC2 > Security Groups > el de tu RDS (`BaseDeDatos`) > **Edit inbound rules** > **Add rule**, tipo `MySQL/Aurora`, origen el `SecurityGroupId` del punto 5. 7. Para borrar, usa `./gestionar-adminer.sh eliminar`, que primero quita esas reglas. Si pulsas **Delete stack** en la consola con la regla puesta, el Security Group de Adminer sigue referenciado desde el de tu RDS y el borrado falla (`DELETE_FAILED`). Si te pasa, ejecuta `./gestionar-adminer.sh eliminar`: lo resuelve él (quita la regla y vuelve a borrar, forzando si hace falta); o quita a mano de tu Security Group de RDS la regla de entrada cuyo origen es el de Adminer y vuelve a pulsar **Delete stack**. ### Paso 2C (alternativa). Adminer en tu PC con Docker No crea nada en AWS. Requiere Docker Desktop abierto: ```bash docker run -d -p 8080:8080 adminer ``` Abre `http://localhost:8080`. Para que llegue a tu RDS necesitas que la RDS tenga **Public access: yes** y que su Security Group permita el puerto 3306 desde tu IP (la diapositiva 35 lo abre a todo Internet). El servidor es el endpoint de tu RDS. Usa el puerto 8080 de tu PC: si también quieres la web `rdstest` (03.04) a la vez, arráncala en otro puerto. La imagen `adminer` admite subir ficheros de hasta 128 MB (límite medido en `adminer:latest`; puede variar según la versión). Este Adminer local no lleva el envoltorio de cifrado de los scripts: con una RDS MariaDB 11.x puede responder `Connections using insecure transport are prohibited`. Usa la 10.11 ([03.01](../03.01-RDSMariaDB.md)) o el Adminer de los scripts. Para pararlo: `docker ps` y `docker stop `. **Paso 3. Abrir Adminer y conectar con tu RDS (diapositiva 40).** 1. Espera ~1-2 minutos tras el despliegue y abre `http:///adminer.php` con `http://`, no `https://` (el Security Group solo abre el puerto 80). Y con `/adminer.php` al final: la raíz de la IP no muestra Adminer. 2. Rellena el formulario de entrada: - El formulario **no tiene selector de sistema** (la versión actual de Adminer solo conecta con MySQL/MariaDB): rellena Server, Username y Password y deja Database vacío. - **Server**: el endpoint de tu RDS, sin puerto y sin `http://`. Por ejemplo `..eu-north-1.rds.amazonaws.com`. - **Username**: `admin`. - **Password**: la contraseña que elegiste al crear la RDS. - **Database**: déjalo vacío. - «Permanent login» (la diapositiva 40 lo menciona) es opcional. Mejor no marcarlo: entre tu navegador y Adminer la conexión va por HTTP sin cifrar (el tramo de Adminer a la RDS sí va cifrado) y esa opción guarda la sesión en una cookie. 3. Pulsa **Login**. Qué verás: la pantalla principal de Adminer, con un menú a la izquierda (entre otras entradas, **SQL command**, **Import** y **Export**), el desplegable de bases de datos y la lista de bases que ya tiene tu RDS (al principio, solo las de sistema; si ya has hecho [03.03](../03.03-sqlestudiantes/README.md), aparecerá `universidad`). Si no entra: - Se queda cargando y acaba con un error de conexión o de tiempo agotado: la red no llega a la RDS. Mira «Errores frecuentes» (Adminer y tu RDS en la misma región, reglas del Security Group, RDS `Available`). - Dice `Access denied`: usuario o contraseña incorrectos. - Dice que no resuelve el nombre del servidor (`getaddrinfo` o `Name or service not known`): has escrito mal el endpoint. Seguridad: la página de Adminer es pública por HTTP. No uses contraseñas que uses en otros sitios, pulsa **Logout** al terminar y borra Adminer al acabar (apartado Limpieza). Subida de ficheros: un Adminer creado con los scripts de esta carpeta admite ficheros de hasta 100 MB (`upload_max_filesize = 100M` y `post_max_size = 100M`, en `/etc/php.d/99-g214-upload.ini` de la instancia; los scripts reinician `php-fpm` y `httpd` después de escribirlo). Los ficheros grandes de los ejercicios adicionales se tratan en [03.09](../03.09-ineaire/README.md). Si te sale `Maximum allowed file size is 2MB`, tu Adminer no tiene ese ajuste: o lo desplegaste con una versión anterior de los scripts (PHP, que en Amazon Linux 2023 corre en `php-fpm`, no se reiniciaba) o es otro Adminer. Con los scripts actuales no debería pasar; si te pasa, reinicia la instancia (`aws ec2 reboot-instances --instance-ids --region eu-north-1`; la IP no cambia con un reinicio) y espera un minuto, o bórrala (`eliminar`) y créala de nuevo. **Paso 4. Apagado automático, reinicio y nueva IP (para cuando vuelvas otro día).** - A las 4 horas de crearla (o del último `crear`/`extender`), la máquina se apaga sola: la página deja de responder y la instancia queda en estado `stopped`. No se pierde nada y no hay que volver a instalar. - **Para seguir trabajando, arráncala.** Sea cual sea el modo: `./gestionar-adminer.sh estado` te dice que está parada y `./gestionar-adminer.sh crear` (o `arrancar`) la arranca, renueva el plazo y te enseña la URL nueva. Por consola: EC2 > Instances > tu instancia (`G214-Adminer` o `G214-AdminerWebserver`) > **Instance state** > **Start instance** (si lo haces así con el plazo vencido, tendrá 60 min de gracia; ejecuta luego `crear` para ampliar). Por CLI: ```bash aws ec2 describe-instances --region eu-north-1 \ --filters "Name=tag:Name,Values=G214-Adminer,G214-AdminerWebserver" \ "Name=instance-state-name,Values=pending,running,stopping,stopped" \ --query "Reservations[].Instances[].[InstanceId,State.Name,PublicIpAddress]" \ --output table aws ec2 start-instances --instance-ids --region eu-north-1 ``` - Al arrancar, Apache (y Adminer con él) arranca solo. - **La IP pública cambia en cada parada y arranque.** La URL antigua, `informacion_adminer.txt` y, en la opción B, los Outputs del stack pueden mostrar la IP anterior. Mira la IP vigente con `estado` (que consulta la instancia) o en EC2, columna **Public IPv4 address**. - Con lo que se crea no puedes entrar en la máquina (no hay puerto 22 abierto ni rol para SSM; en la B, desde la consola, solo si indicaste un `KeyName`): el plazo se cambia siempre con el script (`crear` / `extender`), que modifica la etiqueta `g214-apagar-tras` de la instancia. - El vigilante del apagado automático se instala **al principio** del arranque de la máquina, así que, aunque la instalación de Adminer falle, la instancia se apagará igualmente. Aun así, si Adminer no responde pasados unos minutos, bórrala (`eliminar`) y reinténtalo. ## Errores frecuentes **Scripts y CloudShell** | Síntoma | Causa | Solución | |---|---|---| | `Permission denied` al lanzar `./script.sh` | El script no tiene permiso de ejecución | `chmod +x script.sh` (o lánzalo con `bash script.sh`) | | `bad interpreter: /bin/bash^M` o `$'\r': command not found` | El fichero tiene finales de línea de Windows | `sed -i 's/\r$//' *.sh` y repite | | `No encuentro la AWS CLI` o `Las credenciales de AWS no funcionan: ...` | Estás fuera de CloudShell sin AWS CLI configurada, o la sesión ha caducado | Usa CloudShell (recarga la pestaña si caducó) o ejecuta `aws configure` en tu PC. El mensaje trae el motivo que da AWS | | `No se encontró una VPC por defecto en ` | Región equivocada, o has borrado la VPC por defecto | Comprueba `echo "$AWS_REGION"`. Si la has borrado, `aws ec2 create-default-vpc --region eu-north-1` la recrea (el propio mensaje lo dice) | | `No hay terminal interactiva para confirmar` | Has lanzado `eliminar` o `--grant-rds` sin teclado (desde otro script, por ejemplo) | Añade `--si` (o `--yes`) para confirmarlo por adelantado | | Un aviso amarillo `Tu terminal está configurada en , pero este curso trabaja en eu-north-1` | CloudShell (o tu AWS CLI) está en otra región | El script usa `eu-north-1` igualmente; cambia la región de la consola a Estocolmo para que la consola web vea lo mismo | | `AWS no responde bien (Throttling); reintento 1/5...` | AWS pide ir más despacio | No es un error: el script espera y reintenta solo (hasta 5 veces) | | `Interrumpido (Ctrl+C)` | Pulsaste Ctrl+C a medias | Lo ya creado sigue en AWS: repite `crear` (no duplica) o ejecuta `eliminar` | **Adminer** | Síntoma | Causa | Solución | |---|---|---| | La URL no carga o da tiempo agotado | Usas `https://`; falta `/adminer.php`; aún se está instalando; la instancia está parada (apagado automático) o tiene otra IP | Usa `http:///adminer.php`; espera unos minutos; mira el estado y la IP actuales con `estado` (paso 4) | | Instancia `running` pero, pasados 10 minutos, la URL sigue sin responder | La instalación dentro de la máquina ha fallado (repositorios o `adminer.org` sin respuesta, por ejemplo). Se apagará igualmente al vencer el plazo | Bórrala (`eliminar`), no la dejes encendida, y reintenta. Si con la A falla dos veces, prueba la B (o al revés) | | Adminer carga pero no conecta con la RDS (tiempo agotado) | Adminer y la RDS no están en la misma región o VPC, la RDS no está `Available`, o falta la regla de acceso | Sigue la lista de debajo | | `Access denied` | Usuario o contraseña incorrectos | Usuario `admin` y la contraseña que pusiste al crear la RDS | | No resuelve el nombre (`getaddrinfo`, `Name or service not known`) | Endpoint mal escrito | Cópialo entero de la consola o de [03.01](../03.01-RDSMariaDB.md), sin `http://` ni puerto | | Al crear: `No hay ninguna instancia RDS todavía en ` | La RDS no existe aún, o está en otra región | Crea la RDS en esa región y luego `--grant-rds NOMBRE_DE_LA_RDS` (A y B) | | `Ya tienes una instancia de Adminer creada; no creo otra.` (A) / `El stack 'cunef-adminer' ya existe` (B) | No es un error: ya hay una desplegada | `estado` para ver su URL o `eliminar` para borrarla | | `No encuentro ningún Adminer creado en modo ...` | Lo desplegaste con el otro modo, o ya está borrado | Prueba con `--modo cli` / `--modo cloudformation`, o `estado` para ver qué hay | | `Ha quedado algo sin borrar` al hacer `eliminar` | AWS tardó más de lo normal en liberar algún recurso (el script ya ha reintentado varios minutos) | Espera un minuto y repite `eliminar`: es seguro repetirlo. Si sigue fallando, borra a mano lo que indica la comprobación final | | `El stack no terminó en CREATE_COMPLETE` (B) | Falló algún recurso | El script enseña los motivos que da CloudFormation. Vuelve a ejecutar `crear` (limpia el stack fallido) o `eliminar` | | `Unable to upload a file. Maximum allowed file size is 2MB.` o `The POST data is too large` (HTTP 413) al importar | Este Adminer tiene los límites de PHP por defecto (2 MB / 8 MB): se desplegó con la versión anterior de los scripts (que no reiniciaba `php-fpm`) o es otro Adminer | Con los scripts actuales no debería pasar. Reinicia la instancia (`aws ec2 reboot-instances --instance-ids --region eu-north-1`), bórrala y créala de nuevo, o carga el fichero con `LOAD DATA LOCAL INFILE` (ver [03.09](../03.09-ineaire/README.md)). El Adminer de Docker admite 128 MB | Si Adminer no conecta con tu RDS, comprueba por este orden: 1. La región de CloudShell (`echo "$AWS_REGION"`) es la de tu RDS. 2. La RDS está en `available` y usa la VPC por defecto. 3. La regla existe. `estado` muestra el Security Group de Adminer (`Security Group: sg-...`); sustituye `` por él: ```bash aws ec2 describe-security-groups \ --filters "Name=ip-permission.group-id,Values=" \ --query "SecurityGroups[].GroupId" --output text --region eu-north-1 ``` Debe imprimir el Security Group de tu RDS. Si no imprime nada, concede el acceso con `--grant-rds NOMBRE_DE_LA_RDS` (A y B), contestando la RDS que quieras y `s` a la confirmación. Si imprime un Security Group que no es el de tu RDS, mira en RDS > tu instancia > Connectivity & security cuál es el suyo. ## Limpieza **No borres Adminer todavía**: las actividades 03.03, 03.04 (exportar), 03.05, 03.06 y 03.09 lo usan. Esta carpeta es la que lo borra; hazlo **al terminar la última actividad que use Adminer (la 03.09)** y **antes** de borrar la RDS ([03.01](../03.01-RDSMariaDB.md)), porque Adminer quita sus reglas de tu Security Group. Si vas a parar un tiempo, déjalo como mínimo apagado o bórralo y créalo de nuevo después. - Opción A: `./gestionar-adminer.sh eliminar` (o el menú, `4`). Enseña lo que va a borrar y pide confirmación; después quita la regla de tu RDS, termina la instancia, borra el Security Group (reintentando mientras AWS lo libera) y escribe la comprobación final con `Limpieza completa`. Si ves `Ha quedado algo sin borrar`, espera un minuto y repite el comando: es seguro repetirlo y continúa donde se quedó. Funciona aunque hayas borrado algo a mano o hayas perdido el rastro de lo creado (no depende de ningún fichero). - Opción B: `./gestionar-adminer.sh eliminar` (o el menú, `4`). Quita la regla de acceso de tu RDS, borra el stack y, si se atasca en `DELETE_FAILED`, lo fuerza (y como último recurso lo borra conservando los recursos atascados y los elimina a mano), y comprueba al final que no queda nada. Con el stack sano, el borrado limpio se midió en 50-55 s con la versión anterior. - No hace falta indicar el modo: `eliminar` detecta si lo creaste con comandos o con CloudFormation (si tuvieras los dos a la vez, usa `--modo cli` o `--modo cloudformation` para elegir cuál borrar). - Opción C (Docker): `docker ps` y `docker stop `. Verificación (todo en `eu-north-1`; el propio `eliminar` ya la hace al terminar, pero puedes repetirla a mano): ```bash aws ec2 describe-instances --region eu-north-1 \ --filters "Name=instance-state-name,Values=pending,running,stopping,stopped" \ --query "Reservations[].Instances[].[InstanceId,State.Name,Tags[?Key=='Name']|[0].Value]" --output table aws ec2 describe-security-groups --region eu-north-1 \ --filters "Name=group-name,Values=g214-adminer-sg-*" --query "SecurityGroups[].GroupName" aws cloudformation list-stacks --region eu-north-1 \ --stack-status-filter CREATE_COMPLETE UPDATE_COMPLETE ROLLBACK_COMPLETE DELETE_FAILED \ --query "StackSummaries[].StackName" ``` Qué debes ver: ninguna instancia `G214-Adminer` ni `G214-AdminerWebserver` (si tienes instancias de otros laboratorios, saldrán aquí: son de otro tema), ningún Security Group `g214-adminer-sg-*` y ningún stack `cunef-adminer`. ## Cómo sabes que has terminado - [ ] Adminer desplegado (A o B), abierto con `http:///adminer.php` y conectado a tu RDS: ves tus bases de datos. - [ ] Sabes cómo arrancarlo de nuevo tras el apagado automático (`crear`) y que la IP cambia. - [ ] (Al final del tema) Has borrado Adminer y la verificación sale vacía. Anterior: [03.01 · RDS MariaDB](../03.01-RDSMariaDB.md) · Siguiente: [03.03 · SQL con la tabla de estudiantes](../03.03-sqlestudiantes/README.md)