Journal


Section dedicated to explain my computer projects. Here is the full archive.
(Texts written in spanish)

Empezando con AWS

IAM, EC2, RDS, S3, CloudFront y Lambda

Como expliqué en la anterior entrada, mi propósito era empezar con AWS. Para tener una guía con la que empezar he seguido este video de midudev. Tras crearme la cuenta, lo primero ha sido acceder a IAM (Identity and Access Management), crear un usuario distinto de root y otorgarle los permisos necesarios para poder operar con él; lo segundo, establecer límites de presupuesto y alertas. Amazon te proporciona varios servicios gratis durante los primeros seis meses y te da 140 dólares de crédito; aún así he puesto límites muy por debajo de esos 140$ que disparan el envio de un correo electrónico cuando son superados para ser consciente de los créditos que estoy gastando y meterme en la piel de un administrador. Hecho esto, empezamos con los servicios propiamente dichos.

EC2

EC2 es el servicio de AWS que permite crear máquinas virtuales en la nube. En mi caso, lo he usado solo para hacer una primera prueba: crear una instancia, ver las opciones básicas de configuración como el sistema operativo, tipo de máquina, clave de acceso o reglas de red, conectarme desde mi consola con SSH y, tras ver que funciona, borrar la instancia inmediatamente después. La idea aquí no era desplegar nada todavía, sino entender el flujo mínimo para levantar un servidor en AWS sin dejar recursos consumiendo crédito innecesariamente.

RDS

RDS es el servicio de bases de datos gestionadas de AWS. Igual que con EC2, lo he utilizado únicamente como toma de contacto: crear una instancia, ver cómo se configura el motor de base de datos, las credenciales, la conectividad y las opciones básicas de administración, y eliminarla después. La principal diferencia frente a instalar una base de datos manualmente en un servidor es que AWS se encarga de buena parte de la gestión operativa del servicio.

S3 y Cloudfront

Como expliqué en los anteriores artículos, el primer dominio que compré fue un .click, pero después decidí migrar la página principal a un .xyz y reservar el primero para pruebas. Hasta ahora había dejado ambos dominios operativos en mi servidor personal, con dos archivos distintos de nginx en la ruta /etc/sites-available y sus correspondientes enlaces simbólicos en /etc/sites-enabled: uno para servir pabloquiros.xyz y otro para servir pabloquiros.click. Sin embargo, he borrado la configuración de nginx asociada al .click con la intención de dejar de servir ese dominio desde mi propio servidor y pasar a servirlo desde AWS. Para ello he usado dos servicios: S3 (Simple Storage Service) y CloudFront, la CDN de AWS.

Lo primero que hay que hacer es crear un bucket en S3 en el que se subir los archivos estáticos de mi página web, también he activado la opción de alojamiento de sitios web estáticos, que lo hace todo más sencillo. Una vez dados los permisos correspondientes y ver que se podía acceder a mi página web alojada en AWS, he modificado el upload.yml de mi página web para añadir dos steps inmediatamente después del despliegue en mi servidor personal que actualizan los archivos en S3:

# AWS S3 Sync for backup and CDN
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Sync files to S3
        run: |
          aws s3 sync ./public s3://${{ secrets.S3_BUCKET }} --delete

En ese momento la web ya estaba disponible, pero solo a través de la URL que proporciona AWS para el alojamiento estático del bucket. Esto sirve para comprobar que todo funciona, pero no es la forma ideal de exponer una página pública con dominio propio. El bucket está en una región concreta de AWS y el usuario accede directamente a ese origen. Ahí es donde entra CloudFront, el CDN de AWS. CloudFront se coloca delante del origen, cachea el contenido en distintas edge locations para así poder servirlo desde ubicaciones más cercanas al usuario, reduciendo latencia y evitando que todas las peticiones tengan que ir directamente contra S3. Además, CloudFront permite gestionar mejor el acceso por HTTPS y asociar un dominio propio a la distribución. Para ello es necesario crear un certificado en AWS Certificate Manager que nos permita acceder a pabloquiros.click mediante HTTPS. AWS valida ese certificado mediante DNS, así que he tenido que añadir en Cloudflare una entrada CNAME específica con el nombre que me dio AWS. Una vez validado el certificado, el dominio puede apuntar a CloudFront y la web queda accesible desde pabloquiros.click con conexión segura.

Importante: Durante la configuración de CloudFront, una de las opciones que te daban en el formulario era activar el AWS WAF para probar las capacidades de protección de aplicaciones web. Es una herramienta válida para entornos empresariales, pero su coste fijo es altísimo, lo que por suerte descubrí cuando me saltó la alarma. Pagué la primada en forma de dólar y medio en créditos que podría haberme ahorrado, es muy poco pero me sirve para estar atento a estas cosas. Incluso teniendo alarmas puestas, conviene revisar regularmente la página de precios y el impacto en Cost Explorer.

AWS Lambda

El último servicio que cubre el vídeo de midu y el que más interesante me ha resultado es AWS Lambda, que permite ejecutar funciones sin tener que administrar servidores. Charlando con ChatGPT le he preguntado si en un servicio como AWS Lambda una variable global tendría sentido (yo entendía que no) Tú subes una función, defines cuándo se ejecuta y AWS se encarga de levantar la infraestructura necesaria y Chat me ha explicado aunque Lambda sea serverless, eso no significa que cada ejecución empiece siempre desde cero. AWS puede reutilizar el entorno de ejecución entre llamadas, por lo que una variable global podría conservar su valor durante varias invocaciones… pero esto es algo que no es seguro y para lo que habría que hilar muy fino: esto excede el ámbito de mi competencia así que lo dejaré estar.

Para cerrar esta primera toma de contacto con Lambda he creado un “Hello World” para el que he configurado la URL de la función y poder hiperenlazarla desde aquí. Había pensado algo un poco más interesante: una función que devolviese al usuario el país desde el que está realizando la petición. De nuevo comentándolo con ChatGPT, surgió una idea bastante elegante. En lugar de consultar una API externa de geolocalización, podría colocar la Lambda detrás de CloudFront y aprovechar las cabeceras geográficas que este añade automáticamente a las peticiones. De esta forma la función podría conocer el país de origen del visitante utilizando información proporcionada directamente por la infraestructura de AWS. Pero todo esto, además de investigar otro tipo de desencadenadores y destinos de la función, lo dejaré para el siguiente artículo.

Nuevo dominio

Migración de .click a .xyz y relacionados

A lo largo de mi carrera laboral he tocado bastantes palos, y en varias ocasiones he tenido que aprender sobre la marcha. Unos años atrás me metieron en un proyecto de Big Data con Scala y Spark, no teniendo yo idea de nada de esto; en mi último trabajo me ofrecí a tocar cosas de Angular sin haber tocado frontend hasta el momento. También he acabado involucrado de una forma u otra en integración y despliegue continuo, Docker, o Kubernetes. Hay, sin embargo, algo en lo que nunca he tenido la necesidad de produndizar y que viendo mis búsquedas en LinkedIn queda claro que es casi un requisito indispensable.

Aunque el término cloud engloba muchas cosas, podríamos simplificarlo y dividirlo en tres niveles: SaaS, PaaS e IaaS.1 El primero es muy sencillo: cualquier hijo de vecino sabe lo que es Gmail o Dropbox, aunque no sepa que son software como servicio (Software as a Service). Las plataformas como servicio ya si que están enfocadas a desarrolladores: Openshift o Supabase (la primera usada en mi anterior trabajo, la segunda en uno de mis proyectos personales) nos permiten desplegar aplicaciones o utilizar determinados servicios sin tener que preocuparnos por la infraestructura que hay debajo. Esa infraestructura es precisamente la que entra en juego en el tercer nivel, donde ya hablamos de servidores, redes, almacenamiento, balanceadores, etcétera. Es “infraestructura como servicio” porque no tenemos el servidor físicamente en una habitación ni compramos discos duros, switches o routers, sino que alquilamos esos recursos bajo demanda a un proveedor; es a esto a lo que normalmente nos referimos cuando leemos cloud en alguna oferta de trabajo.

No es que me sea algo ni mucho menos ajeno. Como ya comenté en mi anterior artículo, llevo tiempo gestionando mi propio VPS. Pero cuando hablamos de sistemas más grandes, la complejidad cambia de escala: no es lo mismo mantener un servidor propio para gestionar una pequeña página web que diseñar infraestructura reproducible, escalable y fácil de automatizar. Es ahí donde entran Amazon Web Services, Microsoft Azure o Google Cloud, y es aquí donde, hasta la fecha, voy un poco más perdido. De todos ellos, el proveedor líder en el mercado es AWS, y es por eso por lo que voy a centrarme en él. Sin embargo, más que aprender un proveedor concreto, me resulta mucho más interesante entender cómo gestionar infraestructura independientemente de la plataforma. Aquí es donde entra Terraform y la IaC, Infrastructure as Code. Trabajar con Terraform me permite abstraerme en parte del proveedor y no “casarme” con nadie.

Como creo que la mejor forma de aprender es hacer cosas, mi intención es sobrecomplicar un poco mi actual infraestructura y replicar lo que ya tengo construido en mi VPS, pero esta vez usando Terraform y AWS. Para ello había comprado hace unas semanas el dominio pabloquiros.xyz en Hostinger. Pero el dominio .xyz parece, a primera vista, bastante más “serio” que el .click, que prácticamente remite a páginas de broma. Es por ello que, antes de nada, he decidido migrar de dominio y dejar en un futuro .click para futuras pruebas.

Apuntes locales

En su día, para desplegar una página web estática en un VPS, seguí algunos tutoriales sencillos de YouTube. A día de hoy ya me se de memoria lo que tengo que hacer, ya que no es muy complicado: instalar nginx en mi VPS, crear un archivo en /etc/nginx/sites-available que se vea de la siguiente forma:

server {
    listen 80;
    listen [::]:80;

    server_name midominio.com www.midominio.com;

    root /var/www/mi-web;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

generar un link simbólico de este archivo en /etc/nginx/sites-enabled, recargar nginx y voilá!, ya tenemos página web, cuyo contenido será lo que haya en el archivo /var/www/mi-web/index.html. Habría también que añadir certbot, lo cual también es muy sencillo.

Pese a que recuerdo todos estos pasos, uno siempre se puede olvidar de algo, por lo que viene bien tener a mano documentación; aquí es donde entra un proyecto personal del que todavía no había hablado y que tenía un poco abandonado, pero que he vuelto a actualizar aprovechando la coyuntura. Se trata de una bóveda de Obsidian local donde pretendo crear una suerte de apuntes de informática. En ella doy cabida a la máxima cantidad de información y documentación posible. Este es un proyecto que en el mejor de los casos caerá presa del síndrome del 90%, ya que siempre se le podrán añadir nuevas carpetas y nuevos apuntes, así que nunca planeo terminarlo como tal, pero si espero que me resulte útil a futuro. Actualmente este es su árbol de carpetas:

├── Anexo
├── Full-stack
│   ├── 1. Lenguajes de programación
│   │   ├── 1.1 Lenguajes de propósito general
│   │   ├── 1.2 Marcado y estilos
│   │   ├── 1.3 Consulta
│   │   └── 1.4 Configuración
│   ├── 2. Arquitectura de software
│   │   └── 2.1 Seguridad
│   ├── 3. Infraestructura
│   │   ├── 3.1 Sistemas
│   │   ├── 3.2 Redes
│   │   ├── 3.3 Hosting
│   │   ├── 3.4 Contenedores
|   |   ├── 3.5 Cloud
│   │   └── 3.6 Seguridad
│   ├── 4. Backend
│   ├── 5. Frontend
│   │   └── Frameworks Javascript
│   ├── 6. Bases de datos
│   │   ├── 6.1 Relacionales
│   │   └── 6.2 No relacionales
│   ├── 7. CI-CD
│   │   ├── 7.1 Control de versiones
│   │   ├── 7.2 Dependencias y build
│   │   ├── 7.3 Pipelines
│   │   └── 7.4 Despliegue
│   └── 8. Testing
└── Proyectos

De momento tengo muy poca documentación. Tras realizar la migración, en la sección 3.3.Hosting añadí un archivo detallando como realizar el deploy de una web estática, además de añadir otros como nginx.md (3.2 Redes) o docker.md (3.4 Contenedores). Cuando estos apuntes sean ya algo útil planeo subirlos a mi servidor para que sean accesibles, pero de momento es un proyecto a futuro y no le voy a dar prioridad.

DNS

En el dominio .click había empezado usando los nameservers de Epik durante las primeras semanas, hasta que un día decidí pasarme a los de Vultr. Tenía pensado hacer lo mismo con el dominio .xyz, pero pensé que tenía más sentido centralizarlo todo en Cloudflare, que no solo actúa como proveedor de DNS sino que añade una capa adicional de cacheo, protección frente a ataques, certificados SSL automáticos y, en general, una mejora en el rendimiento. Basta con crear una cuenta gratuita en Cloudflare, añadir el dominio y revisar los registros DNS que detecta automáticamente. Una vez verificado que todo es correcto, solo hay que cambiar los nameservers en el registrador para que apunten a Cloudflare. A partir de ahí, se gestionan todos los registros DNS desde su panel.

Al principio y para hacer la prueba empecé usando el modo “DNS only”, es decir, sin pasar el tráfico por los servidores de Cloudflare. Una vez comprobado que todo funcionaba bien, activé el modo proxy2; en el panel de Cloudflare me permiten ver el tráfico de mi página o parchear de forma sencilla las vulnerabilidades que me indican en el apartado de Security insights. Son este tipo de cosas las que quiero empezar a integrar dentro de un entorno cloud más estructurado en los próximos pasos.

Esta semana empezaré mi formación de Terraform y AWS.


  1. Existe otro modelo cada vez más popular, el FaaS (Function as a Service), que podríamos situar entre PaaS y otros modelos más abstractos. En este modelo se ejecuta código en forma de funciones bajo demanda, dentro del llamado paradigma serverless. Profundizaré en esto cuando haya buceado un poco más en AWS Lambda. ↩︎

  2. Dejando una “puerta de entrada” DNS only para SSH. ↩︎

Toma de contacto

Proyectos ya realizados y proyectos por realizar en 2026

Los familiarizados con términos marinos sabrán que la bitácora es un mueble que se fija a la cubierta de las embarcaciones, al lado del timón. Su particular forma, con dos esferas de hierro a cada lado que le dan la apariencia de un púgil preparado para el combate, no es accidental; un complicado mecanismo de hierros e imanes reduce al mínimo posible los desvíos magnéticos, lo que permite alojar en ella la brújula y que esta señale en todo momento el norte. Los caprichos del lenguaje quisieron que al guardarse el cuaderno de navegación al lado de la brújula, el nombre del mueble acabara designando al cuaderno mismo. Si hacemos este ejercicio etimológico con la lengua inglesa, descubrimos que nuestro cuaderno de bitácora es para ellos el logbook, voz compuesta por book, libro, y log, leño. Para calcular la velocidad del navío, se ataba un madero a una cuerda con varios nudos que se arrojaba al mar; aún hoy seguimos usando los nudos, equivalentes a una milla náutica por hora, como unidad de medida. El logbook era por lo tanto el libro donde se anotaban, entre otras cosas, las mediciones obtenidas con aquel ingenio. Con el tiempo y como bien sabrán los informáticos, log pasó a significar también registro ordenado de eventos, y de esa misma raíz nació en la era digital el web-log, después abreviado en blog.

La etimología náutica le viene a estos apuntes como anillo al dedo. No hace tanto que hablábamos de navegar por Internet, expresión caída en desuso quizá porque hoy casi todos nos movemos en las mismas tres o cuatro plataformas centralizadas y “navegamos” más bien poco. Pero para aquellos que tratamos de ganarnos el pan con la informática, sigue siendo procedente usar el verbo; las procelosas aguas del software no nos dan respiro. Es dificil, por no decir imposible, seguir el ritmo: cada día aparecen nuevas tecnologías, nuevos frameworks, nuevos modelos de lenguaje. Análisis de datos, cloud, IA, crypto… Así las cosas, resulta indispensable no perder el norte y mantener un registro de los avances. Hasta ahora no había sido lo que en lenguaje corporativo se ha dado en llamar “proactivo”; me limitaba a realizar mi trabajo y dejar que la corriente marcara el rumbo; pero ante la complejidad cada vez mayor de este entorno y, al mismo tiempo, la facilidad para hacer cosas por cuenta propia, he decidido coger el timón.

En esta primera entrada de mi particular cuaderno de bitácora detallaré lo construido hasta ahora para, a partir de aquí, ir dando cuenta de mis próximos pasos. Hay muchos proyectos que me rondan la mente por lo que es probable que algunos de ellos se queden en eso, en proyectos.

Hecho hasta ahora

  • VPS y dominio: En 2023 decidí autoalojar un proyecto muy simple que explicaré más adelante, para ello me hice una cuenta en epik para obtener un dominio y otra en vultr para obtener un servidor virtual, el más barato posible, que dejé de pagar el año pasado, pero que volví a alquilar a comienzos de este año.

  • Codex: Fue en Enero cuando me pareció que todo el mundo en Internet estaba hablando de Claude Code; por supuesto esta sensación derivaba de leer a gente muy concreta, pero si que entendí que copiar y pegar cosas de ChatGPT empezaba a ser algo ya propio del medievo digital. Instalé Codex en mi ordenador personal, primero como CLI y luego como extensión de Visual Studio, y estoy muy contento con lo que me ha permitido hacer. He estado tentado de probar Claude Code pero he leido a mucha gente quejarse en lo relativo a los tokens, por lo que me mantengo con mi elección inicial.

  • Concurso: El proyecto que decidí hacer en 2023 fue una página web a modo de regalo de cumpleaños para mi madre, la página consistía en un concurso en el que se mostraba una foto familiar y se preguntaba bien de que año era, bien en que ciudad había sido tomada. La primera versión que publiqué es de Junio de 2023, habiendo aprendido un poco a la carrera Vue.js sin haber tenido experiencia con frontend. Este enero decidí rebuscar en mi GitHub para rehacer la web, mejorándola bastante. Le añadí una sección de administración para darle complejidad, añadí un script con Python para ingestar fotos, y, aunque claramente sea una sobrecomplicación, la dividí en distintos contenedores (frontend, backend, mongo, ingesta) para cacharrear un poco con Docker y Docker compose. Este es el repositorio de GitHub y aquí se puede ver su estado actual, hoy no hay fotos en ella porque están todas solo disponibles para usuarios autenticados (mi familia), que también pueden añadir o modificar los campos (año y ciudad) de las fotos existentes.
    Stack: Vue.js, express.js, mongodb, nginx, docker, GitHub Actions.

  • Página web: Quise desarrollar una página web propia en la que, mismamente, poder escribir cosas como esta. Creo que buena parte de las actuales páginas web están muy sobrecargadas (bloated, como dicen los anglosajones) sin motivo, así que busqué un enfoque más minimalista utilizando un generador de páginas estáticas como Hugo. No estaba muy familiarizado con su sintaxis y nunca había programado con Go, pero gracias a Codex he podido avanzar bastante rápido y he aprendido como funciona sobre la marcha y con algunos tutoriales rápidos. El repositorio de GitHub en el que actualizo los cambios que le hago a la página es privado, pero he creado este otro repositorio que se actualiza cuando se han modificado carpetas relativas a estilos para que otros usuarios puedan descargárselo como theme y usarlo en su propia página. Stack: Hugo, Github Actions

  • App de gimnasio: Esta página fue vibecodeada confiando en GPT sin tanta supervisión como en las anteriores y con fines puramente prácticos, ya que mi mujer y yo necesitabamos una aplicación lo más sencilla posible donde guardar nuestra evolución en el gym. En primera instancia mi intención era crear una aplicación para el smartphone, por lo que usé React Native con Expo, pero pronto me di cuenta de que me llevaría bastante trabajo y que publicar una aplicación en el ecosistema Apple (no así en Android) es un infierno, por lo que decidí mantenerla sólo como página web. React me gusta menos que Angular, con el que tengo experiencia laboral, y Vue.js, con el que he hecho la página del concurso; su sintaxis es en mi opinión demasiado enrevesada, aunque entiendo que a los que estén más acostumbrados al frontend les gustará. Decidí también usar este proyecto para aprender como funciona Supabase; para esta aplicación estoy usando las funcionalidades de autenticación y la base de datos. Este es el repositorio en GitHub y ésta es la página web. Stack: React Native, Supabase, Github Actions.

En la próxima entrada explicaré mi objetivo principal para las próximas semanas.