Probar roles Ansible con Molecule y Docker
Introducción
Ansible Molecule es una herramienta para probar y validar roles y playbooks de Ansible en múltiples escenarios. Automatiza pruebas de código Ansible y ayuda a garantizar que los roles funcionen como se espera al aplicarlos en servidores objetivo. Molecule admite virtualización y contenedores como Docker, Podman y Vagrant, así como proveedores en la nube (AWS, Azure, GCP) a través de drivers.
Definición rápida: Molecule es un marco de trabajo para pruebas de roles de Ansible que crea entornos temporales (instancias) y ejecuta verificaciones automáticas.
Importante: Mantén Python disponible en las imágenes/instancias que vayas a usar para que Ansible y las herramientas de verificación (pytest-testinfra) funcionen.

Qué aprenderás
- Instalar dependencias: Python3, pip, virtualenv, Ansible y Docker CE en Ubuntu 22.04.
- Crear y activar un entorno virtual Python para aislar Molecule.
- Instanciar un rol de Ansible con molecule init y personalizar tareas y variables.
- Configurar Molecule para usar una imagen Docker de prueba y ejecutar converge, verify y destroy.
- Escribir pruebas con pytest-testinfra para validar paquetes y servicios en la instancia.
- Flujo recomendado para desarrollo iterativo con Molecule.
Palabras clave relacionadas
Probar roles Ansible, Molecule Docker, pytest-testinfra, CI de Ansible, pruebas de infraestructura, testing de roles.
Requisitos previos
- Un sistema Linux (el ejemplo usa Ubuntu 22.04). Mantén el nombre del host si lo deseas (ej. ansible-test).
- Un usuario no root con privilegios sudo (ej. alice).
- Conocimientos básicos de Ansible y roles de Ansible.
Instalación de dependencias
Actualiza el índice de paquetes antes de empezar:
sudo apt updateInstala Python3, pip, virtualenv, Ansible y utilidades necesarias:
sudo apt install python3 python3-pip python3-venv ansible ca-certificates curl gnupg lsb-releaseConfirma con “y” y ENTER cuando se solicite.

A continuación, instala Docker CE desde el repositorio oficial:
- Crea el directorio para las claves y añade la GPG del repositorio:
sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg- Añade el repositorio de Docker a APT:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null- Actualiza la caché e instala Docker CE:
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Añade tu usuario al grupo docker para ejecutar contenedores sin sudo:
sudo usermod -aG docker $USERVerifica que Docker puede ejecutar contenedores:
docker run hello-worldDeberías ver la salida del contenedor hello-world si todo está correcto.

Con esto quedan instaladas las dependencias principales: Python3, pip, virtualenv, Ansible y Docker. El siguiente paso es instalar Molecule dentro de un entorno virtual para mantener dependencias controladas.
Instalar Molecule en un entorno virtual
Crea y activa un entorno virtual Python para aislar las dependencias de desarrollo:
python3 -m venv ansible-venv
source ansible-venv/bin/activateCambia a la carpeta del entorno (opcional) y usa pip para instalar wheel, molecule y el plugin Docker:
cd ansible-venv/
pip3 install wheel molecule 'molecule-plugins[docker]'
Tras la instalación, estarás listo para crear un rol de Ansible con Molecule.
Inicializar un rol de Ansible con Molecule
En este ejemplo crearemos un rol llamado test.lemp que instalará componentes de LEMP (Nginx, MariaDB, PHP-FPM).
Genera el esqueleto del rol con driver docker:
molecule init role test.lemp --driver-name dockerEsto creará un directorio llamado lemp con la estructura típica de un rol y la configuración de Molecule.

Entra en el directorio del rol:
cd lempAbre tasks/main.yml y define las tareas principales. Por ejemplo, instalar paquetes y asegurar los servicios:
---
- name: "Installing LEMP Stack"
apt:
name: "{{ pkg_list }}"
state: present
- name: "Ensure LEMP Services is running"
service:
name: "{{ item }}"
state: started
enabled: true
with_items: "{{ svc_list }}"Guarda y cierra el archivo.

Define las variables en vars/main.yml:
---
pkg_list:
- nginx
- mariadb-server
- php-fpm
- php-cli
svc_list:
- nginx
- mariadb
- php8.1-fpm
Nota: Ajusta versiones de paquetes (por ejemplo php8.1-fpm) según la distribución base de la imagen Docker que elijas.
Preparar la instancia de prueba en Docker
Para las pruebas usaremos una imagen Docker que ya incluya Python3. En el tutorial se usa mipguerrero26/ubuntu-python3 (basada en Ubuntu 22.04).
Descarga la imagen:
docker pull mipguerrero26/ubuntu-python3Verifica que la imagen está disponible:
docker images
Puedes ejecutar la imagen de forma interactiva para inspeccionarla:
docker run -it mipguerrero26/ubuntu-python3 /bin/bash
python3 --version
cat /etc/lsb-release
exit
Abre el archivo de configuración de Molecule generado: molecule/default/molecule.yml y ajusta la sección platforms para usar la imagen descargada y marcar privileged cuando sea necesario:
platforms:
- name: instance-ubuntu22.04
image: mipguerrero26/ubuntu-python3
privileged: trueGuarda y cierra.

Lista las instancias que Molecule conoce en este proyecto:
molecule listDeberías ver instance-ubuntu22.04 con el driver Docker.

Ejecutar converge con Molecule
Con la instancia configurada, aplica el rol hacia la instancia usando:
molecule convergeMolecule creará la instancia Docker y aplicará el rol lemp.

Mientras Ansible se aplica, verás las tareas ejecutándose en el contenedor.

Verifica los contenedores en ejecución con docker ps. Debería aparecer instance-ubuntu22.04 tal y como se definió en platforms.
Conéctate al contenedor para inspección manual:
docker exec -it instance-ubuntu22.04 /bin/bash
ss -tulpn
ss -pl | grep php
exitLos puertos típicos son: 80 (Nginx), 3306 (MariaDB); PHP-FPM puede exponer un socket local como /run/php/php8.1-fpm.sock.
Cuando termines, destruye la instancia con:
molecule destroy
Verifica con docker ps y docker ps -a que el contenedor ha sido eliminado.
Crear pruebas con pytest-testinfra
Usaremos testinfra (pytest-testinfra) para verificar programas, paquetes y servicios dentro de la instancia creada por Molecule.
Instala el verificador testinfra dentro del entorno virtual:
pip3 install pytest-testinfra
Crea el directorio de pruebas y el archivo test_default.py:
mkdir -p molecule/default/tests/
nano molecule/default/tests/test_default.pyContenido de ejemplo para comprobar paquetes y servicios:
import os
import pytest
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
@pytest.mark.parametrize('pkg', [
'nginx',
'mariadb-server',
'php-fpm'
])
def test_pkg(host, pkg):
package = host.package(pkg)
assert package.is_installed
@pytest.mark.parametrize('svc', [
'nginx',
'mariadb',
'php8.1-fpm'
])
def test_svc(host, svc):
service = host.service(svc)
assert service.is_running
assert service.is_enabledGuarda el archivo.

Configura el verificador en molecule/default/molecule.yml para usar testinfra y el directorio tests:
verifier:
name: testinfra
directory: testsGuarda y cierra.

Ahora ejecuta el ciclo completo de prueba:
molecule testEste comando realiza: destroy (si hay instancia existente), create, converge (aplica el rol), verify (ejecuta testinfra) y destroy final.
Ejemplo de pasos visuales durante molecule test:



Cuando las pruebas pasan deberías ver una salida de pytest similar a “collected 6 items - 6 passed” indicando que los paquetes y servicios están presentes y activos.

Al final, Molecule destruirá la instancia creada para dejar el entorno limpio.

Flujo recomendado en desarrollo con Molecule
- Genera el rol con molecule init.
- Añade tareas, handlers, templates y variables al rol.
- Define plataformas y la imagen base en molecule/default/molecule.yml.
- Escribe pruebas testinfra pequeñas que validen estado idempotente (paquetes instalados, servicios en ejecución, archivos con contenido esperado).
- Ejecuta molecule converge para aplicar cambios manualmente y comprobar logs.
- Ejecuta molecule verify o molecule test para el ciclo completo de build/verificación/destrucción.
- Itera hasta que las pruebas sean fiables y repetibles.
Comandos útiles:
molecule converge
molecule verify
molecule destroy
molecule test
molecule --helpBuenas prácticas y consejos
- Mantén tus pruebas rápidas y deterministas; evita dependencias externas (internet, servicios remotos) en pruebas unitarias de rol.
- Usa imágenes base que incluyan Python3 o instala Python como parte del setup para que Ansible funcione.
- Valida idempotencia: después de aplicar el rol dos veces no deberían producirse cambios.
- Evita privilegios innecesarios; solo usa privileged: true cuando sea imprescindible (por ejemplo, para probar contenedores con cgroup o configuraciones especiales).
- Integra molecule test en tu pipeline CI para verificar cambios en cada PR.
Mapa mental rápido sobre cuándo Molecule ayuda y cuándo no
- Útil: validar roles aislados, comprobar idempotencia, ejecutar pruebas en contenedores reproducibles, automatizar pruebas en CI.
- No es suficiente: pruebas de integración complejas con dependencias externas o pruebas de aceptación humana; para eso complementa con entornos de staging y pruebas E2E.
Metodología breve para crear pruebas robustas
- Define el estado deseado (lista de paquetes, servicios y archivos).
- Escribe pruebas unitarias con testinfra que verifiquen ese estado.
- Ejecuta molecule converge y luego molecule verify en local hasta que pasen las pruebas.
- Añade estos pasos a CI (ejecutar dentro de un runner que soporte Docker).
Criterios de aceptación
- Todas las pruebas pytest-testinfra deben pasar (salida pytest con todos los items marcados como passed).
- La ejecución del rol debe ser idempotente (segunda ejecución no cambia el sistema).
- El contenedor/instancia se destruye al final del pipeline para evitar fugas de recursos.
Roles y checklist de responsabilidades
- Desarrollador de roles:
- Crear molecule init y estructura del rol.
- Añadir tasks, handlers, templates y vars.
- Escribir pruebas básicas testinfra.
- Ingeniero de QA/CI:
- Integrar molecule test en pipeline.
- Asegurar runners con Docker o herramientas compatibles.
- Operaciones/Infra:
- Mantener imágenes base actualizadas y seguras.
- Revisar requisitos privileged y permisos Docker.
Casos en los que este enfoque falla y alternativas
- Si tus roles dependen de servicios externos (APIs, servicios remotos), las pruebas con Molecule en contenedores pueden no reproducir el entorno real. Alternativa: integrar pruebas de integración en un entorno de staging real.
- Si necesitas probar cambios en el kernel o módulos de bajo nivel, Docker puede no ser suficiente. Alternativa: usar Vagrant/VMs reales o instancias en la nube soportadas por Molecule.
Mini guía de resolución de problemas
- Problema: Ansible no encuentra Python en la imagen. Solución: usa una imagen con python3 instalado o añade un play previa para instalar python3.
- Problema: testinfra no encuentra MOLECULE_INVENTORY_FILE. Solución: asegúrate de ejecutar dentro del entorno creado por Molecule (molecule verify) o exporta la variable correctamente.
- Problema: permisos Docker insuficientes. Solución: añade el usuario al grupo docker o ejecuta con sudo durante pruebas locales.
Seguridad y privacidad
- Evita incluir credenciales en archivos molecule.yml, vars o tests. Usa variables de entorno o vaults de Ansible si necesitas secretos.
- En CI, guarda secretos en el gestor seguro del proveedor (GitHub Actions Secrets, GitLab CI variables, etc.).
Glosario (1 línea cada término)
- Molecule: marco de pruebas para roles de Ansible que crea entornos temporales y ejecuta verificaciones.
- Testinfra: biblioteca basada en pytest para testing de infraestructura (comprobar paquetes, servicios, archivos).
- Converge: acción de Ansible que aplica el rol para lograr el estado deseado.
- Idempotencia: propiedad de una operación que al aplicarse varias veces produce el mismo resultado sin cambios posteriores.
Resumen final
- Molecule facilita la creación de ciclos de prueba reproducibles para roles de Ansible usando drivers como Docker.
- Es recomendable aislar las dependencias en un entorno virtual y mantener pruebas pequeñas y deterministas.
- Integrar molecule test en CI ayuda a detectar regresiones en roles antes de desplegar en entornos reales.
Si necesitas, puedo generar plantillas de pipeline CI (GitHub Actions/GitLab CI) para ejecutar molecule test automáticamente en cada pull request.
Materiales similares
Podman en Debian 11: instalación y uso
Apt-pinning en Debian: guía práctica
OptiScaler: inyectar FSR 4 en casi cualquier juego
Dansguardian + Squid NTLM en Debian Etch
Arreglar error de instalación Android en SD