bash

ehoyos/

cowsay "Bienvenido"

Migración de base de datos MySQL desde un entorno local a AWS RDS utilizando AWS Database Migration Service

Este proyecto documenta la migración estratégica de una base de datos MySQL alojada localmente en un contenedor de Docker hacia la infraestructura de AWS. La solución implementa un túnel VPN a través de un Bastion Host Inmutable, garantizando una conexión segura. Para el movimiento de datos, utilicé AWS Database Migration Service (DMS), logrando una replicación continua y eficiente. A continuación, detallo el ciclo completo: desde el diseño de la arquitectura y el despliegue automatizado con Terraform, hasta la validación final de los datos

Arquitectura del proyecto

Imagen de la aplicación Flask

¿Por qué usar AWS DMS?

AWS Database Migration Service (DMS) se destaca principarmente por 3 características clave:

  • Mínimo tiempo de inactividad (Zero Downtime): A diferencia de las migraciones offline, DMS permite la replicación continua. Esto significa que la base de datos origen puede seguir recibiendo cambios mientras la migración está en curso, sincronizando los datos en tiempo real.
  • Resiliencia y Seguridad: Al integrarse de forma nativa con AWS, DMS gestiona automáticamente la recuperación ante fallos. Además, al combinarlo con nuestro Bastion Host, garantizamos que los datos viajen por un canal cifrado y privado.
  • Simplicidad en entornos heterogéneos: DMS no solo mueve datos, sino que puede manejar la conversión de esquemas y tipos de datos de forma automática, facilitando la transición entre diferentes o motores de base de datos.

Ventajas de usar un Bastion Host Inmutable y WireGuard VPN

Un componente crítico de esta arquitectura es el Bastion Host, que actúa como el único punto de entrada seguro a la infraestructura. Para este laboratorio, decidí elevar el estándar de seguridad y operatividad mediante dos tecnologías clave:

  • Inmutabilidad con NixOS: A diferencia de las distribuciones Linux tradicionales, utilicé NixOS para configurar un sistema inmutable. Esto garantiza que la configuración del servidor sea declarativa y cualquier cambio no autorizado o deriva de configuración (config drift) se elimina al reiniciar, asegurando que el servidor se mantenga exactamente en el estado definido en el código.
  • Conectividad de Alto Rendimiento con Wireguard: Para el túnel VPN, implementé Wireguard. Elegí este protocolo sobre opciones más antiguas (como OpenVPN) debido a su criptografía moderna, su mínima superficie de ataque y su excepcional velocidad, lo que permite que la replicación de datos de DMS ocurra de manera fluida y con una latencia mínima.

¿Por qué usar Docker para nuestra base de datos?

El origen de los datos reside en una instancia de MySQL desplegada mediante Docker. El uso de contenedores fue clave para este laboratorio, ya que me permitió:

  • Portabilidad y Consistencia: Gracias a Docker Compose, logré un entorno de base de datos idéntico y predecible, eliminando el clásico problema de en mi máquina funciona.
  • Ciclos de Vida Eficientes: La capacidad de desplegar, destruir y recrear el entorno en segundos facilitó las pruebas iterativas de la migración. Pude modificar configuraciones de red, usuarios y variables de entorno de forma declarativa, asegurando que el origen estuviera perfectamente optimizado para la conexión con el túnel VPN antes de iniciar el proceso en AWS.

Principales retos enfrentados

A lo largo del desarrollo, surgieron retos complejos que requirieron un análisis profundo de redes y seguridad. Estos fueron los más significativos:

  • Interconectividad Híbrida y Enrutamiento: El mayor desafío fue establecer una comunicación fluida y segura entre la infraestructura en la nube (AWS) y el contenedor Docker en mi entorno local. No se trataba solo de conectar dos puntos, sino de configurar el Bastion Host para que actuara como un puente inteligente, enrutando el tráfico de MySQL de forma precisa entre ambos mundos. Lograr que AWS DMS "viera" una base de datos contenida dentro de una red local privada requirió una configuración meticulosa de las tablas de rutas y el túnel VPN.
  • Seguridad bajo el Principio de Mínimo Privilegio: Configurar los Security Groups y las reglas de red fue un ejercicio de precisión. El objetivo no era solo que funcionara, sino que fuera seguro.

Guía de Despliegue Automatizado con Terraform

Requisitos previos:

  • AWS CLI instalado y configurado con las credenciales de usuario adecuadas.
  • Key pair de AWS para acceder a las instancias EC2.
  • Terraform, WireGuard y Git instalados en la máquina local.
  • Docker y Docker Compose instalados para ejecutar la base de datos MySQL localmente.

Despliegue del bastión inmutable

En el directorio del proyecto, dentro de la subcarpeta: "server-keys" usar el siguiente comando:

wg genkey | tee private.key | wg pubkey > public.key

Esto generará dos archivos: private.key y public.key. El archivo private.key es la llave privada que se usará en el bastion host, mientras que el archivo public.key es la llave pública que se compartirá con el cliente para establecer la conexión WireGuard.

Posteriormente crearemos las llaves para el equipo local en el directorio "/etc/wireguard":

wg genkey | tee local-private.key | wg pubkey > local-public.key

Una vez realizado este paso, es importante cambiar los permisos de nuestra llave privada:

sudo chmod 600 /etc/wireguard/local-private.key

Con ambos pares de llaves listos, debe editarse primero el archivo de configuration.nix que se encuentra en la subcarpeta "flake-wireguard" en la sección de "publicKey" introduciendo el contenido de la llave local-public.key.

Archivo configuration.nix

Antes de desplegar, editar el archivo "variables.tf" y especificar en "key_name" el nombre del key pair de AWS para acceso SSH. Luego ejecutar "terraform init" y "terraform apply" desde la carpeta del proyecto para crear todos los recursos en AWS.

Key pair de AWS para acceso SSH

Una vez completado el despliegue, Terraform mostrará en la terminal la IP pública y privada del bastion host, necesarias para configurar WireGuard y el RDS endpoint que se usará en AWS DMS.

IPs del bastion host y servidor de pruebas

Finalmente, crear el archivo de configuración "/etc/wireguard/wg0.conf" en el equipo local con el siguiente contenido:

Archivo de config local para wireguard

Una vez realizado este paso, es necesario iniciar el servicio de WireGuard en el equipo local:

sudo wg-quick up wg0

Con esto, ya deberíamos tener un bastion host inmutable en AWS con WireGuard configurado y funcionando. y podemos proceder a desplegar la base de datos MySQL en Docker usando en archivo docker-compose.yml proporcionado en el repositorio.

Contenedor Docker con MySQL

Configuración de AWS DMS para la migración

Con el túnel VPN activo y la base de datos MySQL corriendo en Docker, podemos proceder a configurar AWS DMS para la migración de datos. En la consola de AWS DMS, crearemos los endpoints de origen y destino, así como la tarea de migración.

Configuración de AWS DMS para la migraciónTarea de migración en AWS DMS

Una vez configurados los endpoints y la tarea de migración, podemos iniciar la tarea en modo de replicación continua para asegurar que todos los cambios en la base de datos origen se reflejen en el destino.

Tarea de migración en ejecución

Validación de la migración

Después de que la tarea de migración haya estado en ejecución durante un tiempo, es crucial validar que los datos se hayan migrado correctamente y que la replicación continua esté funcionando como se espera. Para ello, podemos conectarnos a la base de datos RDS y verificar la integridad de los datos.

Validación de datos en RDS

Conclusiones y Repositorio en GitHub del Proyecto

Este proyecto demuestra la viabilidad de integrar entornos locales y de nube mediante una arquitectura híbrida segura y automatizada. La combinación de NixOS y Wireguard en un Bastion Host inmutable, junto con la precisión de Terraform, permitió crear una infraestructura resiliente que garantiza la seguridad bajo el principio de mínimo privilegio. Finalmente, el uso de AWS DMS validó que es posible ejecutar migraciones de datos complejas con alta disponibilidad, consolidando un flujo de trabajo profesional que prioriza la integridad de la información, la eficiencia operativa y las mejores prácticas de DevOps. Si quieres conocer más detalles técnicos o ver el código fuente, puedes visitar mi repositorio en GitHub db-migration

Sitio desarrollado con Reflex.

Built with Reflex