Sin embargo, con tanta gente involucrada, es muy importante probar todo a fondo. Al desarrollar contenido de Ansible, como libros de jugadas, roles o colecciones, le recomendamos que pruebe todo en un entorno de prueba antes de implementarlo en producción. El propósito de esta prueba es asegurarse de que todo funcione como debería, para evitar sorpresas desagradables en los sistemas de "producción".
Probar contenido de automatización es complicado porque requiere implementar una infraestructura de prueba dedicada y configurar condiciones de prueba para garantizar que las pruebas en sí sean relevantes. Molecule es un marco de prueba integral que lo ayuda a desarrollar y probar roles de Ansible para que pueda concentrarse en desarrollar la automatización sin distraerse con la administración de su infraestructura de prueba.
Así es como se declara en la documentación del proyecto:
"Molecule está diseñado para ayudar a desarrollar y probar los roles de Ansible, y fomenta un enfoque que da como resultado roles bien redactados, fáciles de entender y mantener".
Molecule le permite probar un rol en varias instancias de destino para probarlo en una variedad de sistemas operativos y entornos de virtualización. Sin él, para cada una de estas combinaciones, tendría que crear y mantener un entorno de prueba independiente, configurar conexiones para probar instancias y revertirlas a su estado original antes de cada prueba. Molecule lo hace todo por ti, de forma automatizada y reproducible.
En esta serie de dos partes, le mostraremos cómo usar Molecule para desarrollar y probar roles de Ansible. En la primera parte, veremos cómo instalar y configurar Molecule, en la segunda, desarrollar roles con ella.
Si el rol es parte de una colección, use este enfoque para desarrollar y realizar una prueba unitaria del rol. En el próximo artículo, le mostraremos cómo usar Molecule para ejecutar pruebas integradas en colecciones.
Molecule utiliza controladores para entregar instancias de destino en una variedad de tecnologías, incluidos contenedores de Linux, máquinas virtuales y proveedores de nube. De forma predeterminada, viene con tres controladores preinstalados: Docker y Podman para contenedores, así como un controlador delegado para crear integraciones personalizadas. La comunidad de desarrollo del proyecto proporciona los impulsores para otros proveedores.
En esta publicación, usaremos el controlador Podmanpara desarrollar y probar un nuevo rol usando contenedores Linux. Podman es un motor de contenedores liviano para Linux, no necesita un demonio en ejecución y permite que se ejecuten contenedores sin raíz, lo cual es bueno para la seguridad.
Usando Molecule con el controlador Podman, desarrollaremos y probaremos un nuevo rol de Ansible desde cero que implementa una aplicación web basada en un servidor web Apache y debería ejecutarse en Red Hat Enterprise Linux (RHEL) 8 o Ubuntu 20.04.
Estamos analizando un escenario típico en el que un rol debe ejecutarse en diferentes versiones del sistema operativo. Con los contenedores de Podman y Linux, podemos crear varias instancias para probar el rol en diferentes versiones de SO. Debido a su ligereza, los contenedores le permiten iterar rápidamente a través de la funcionalidad de un rol durante el desarrollo. El uso de contenedores para probar roles es aplicable en esta situación, ya que el rol solo configura la ejecución de instancias de Linux. Para realizar pruebas en otros sistemas de destino o infraestructuras en la nube, puede utilizar el controlador delegado u otros controladores proporcionados por la comunidad.
Qué necesitamos
Para los ejemplos de este artículo, necesita una máquina Linux física o virtual con Python 3 y Podman instalados (estamos usando RHEL 8.2). Además, Podman tuvo que configurarse para ejecutar contenedores sin raíz. La instalación de Podman está fuera del alcance de este artículo, consulte la documentación oficial para obtener información relacionada . La instalación de Podman en RHEL 8 también se trata en la documentación del contenedor RHEL 8 .
Empecemos
Molecule está diseñado como un paquete de Python y, por lo tanto, se instala a través de pip. El primer paso es crear un entorno Python dedicado e instalar nuestra Molécula en él:
$ mkdir molecule-blog
$ cd molecule-blog
$ python3 -m venv molecule-venv
$ source molecule-venv/bin/activate
(molecule-venv) $ pip install "molecule[lint]"
Tenga en cuenta que estamos instalando Molecule con la opción "lint" para que pip también proporcione las herramientas "yamllint" y "ansible-lint", que nos permitirán usar Molecule para analizar estáticamente el código de función contra los estándares de codificación de Ansible.
La instalación descarga todas las dependencias necesarias de Internet, incluido Ansible. Ahora veamos qué hemos instalado:
$ molecule --version
molecule 3.0.4
ansible==2.9.10 python==3.6
Bueno, es hora de usar el comando "molécula" para inicializar el nuevo rol de Ansible.
Inicializando un nuevo rol de Ansible
En términos generales, al desarrollar un nuevo rol de Ansible, se inicializa con el comando "ansible-galaxy role init", pero usaremos el comando "molécula" en su lugar. Esto nos dará la misma estructura de roles que con el comando "ansible-galaxy", así como el código básico para ejecutar las pruebas de Molecule.
De forma predeterminada, Molecule usa el controlador Docker para ejecutar pruebas. Como queremos usar podman en su lugar, al inicializar el rol con el comando "molécula", debemos especificar el controlador apropiado usando la opción "--driver-name = podman".
Vuelva al directorio "molécula-blog" e inicialice el nuevo rol "mywebapp" con el siguiente comando:
$ molecule init role mywebapp --driver-name=podman
--> Initializing new role mywebapp...
Initialized role in /home/ricardo/molecule-blog/mywebapp successfully.
Molecule crea nuestra estructura de roles en la carpeta "mywebapp". Cambie a esta carpeta y vea qué hay allí:
$ cd mywebapp
$ tree
.
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── molecule
│ └── default
│ ├── converge.yml
│ ├── INSTALL.rst
│ ├── molecule.yml
│ └── verify.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
10 directories, 12 files
Molecule coloca sus archivos de configuración en el subdirectorio "molécula". Al inicializar un nuevo rol, solo aparece un script aquí, llamado "predeterminado". Más tarde, puede agregar sus scripts aquí para probar varias condiciones. En este artículo, solo usaremos el script "predeterminado".
Comprobemos la configuración básica en el archivo "molécula / predeterminado / molécula.yml":
$ cat molecule/default/molecule.yml
---
dependency:
name: galaxy
driver:
name: podman
platforms:
- name: instance
image: docker.io/pycontribs/centos:7
pre_build_image: true
provisioner:
name: ansible
verifier:
name: ansible
Como solicitamos, este archivo indica que el controlador Podman se utiliza para las pruebas. Aquí, la plataforma predeterminada para la instancia de prueba se establece, a través de la imagen del contenedor "docker.io/pycontribs/centos:7", que cambiaremos más adelante.
A diferencia de Molecule v2, Molecule v3 no define un linter predeterminado. Por lo tanto, abramos el archivo de configuración "molécula / predeterminado / molécula.yml" y agreguemos la configuración de pelusa al final:
$ vi molecule/default/molecule.yml
...
verifier:
name: ansible
lint: |
set -e
yamllint .
ansible-lint .
Guarde y cierre el archivo, y ejecute el comando "molécula lint" desde la carpeta raíz de nuestro proyecto para ejecutar el linter en todo el proyecto:
$ molecule lint
Obtenemos algunos errores en la salida, ya que el archivo "meta / main.yml" no contiene una cantidad de valores requeridos. Arreglemoslo: edite el archivo "meta / main.yml", agregue "autor", "empresa", "licencia", "plataformas" y elimine la línea vacía al final. Por brevedad, prescindiremos de los comentarios, y luego nuestro "meta / main.yaml" se verá así:
$ vi meta/main.yml
galaxy_info:
author: Ricardo Gerardi
description: Mywebapp role deploys a sample web app
company: Red Hat
license: MIT
min_ansible_version: 2.9
platforms:
- name: rhel
versions:
- 8
- name: ubuntu
versions:
- 20.04
galaxy_tags: []
dependencies: []
Ejecutemos el linter en el proyecto nuevamente y asegurémonos de que no haya más errores.
$ molecule lint
--> Test matrix
└── default
├── dependency
└── lint
--> Scenario: 'default'
--> Action: 'dependency'
Skipping, missing the requirements file.
Skipping, missing the requirements file.
--> Scenario: 'default'
--> Action: 'lint'
--> Executing: set -e
yamllint .
ansible-lint .
Entonces, nuestro papel se inicializa y la configuración básica de la molécula también está en su lugar. Ahora creemos una instancia de prueba.
Crea una instancia de prueba
De forma predeterminada, Molecule define solo una instancia, que se llama "instancia" y se crea a partir de la imagen "Centos: 7". Nuestro papel, si lo recuerda, debería funcionar en RHEL 8 y Ubuntu 20.04. Además, debido a que ejecuta el servidor web Apache como un servicio del sistema, necesitamos una imagen de contenedor con "systemd" habilitado.
Red Hat tiene una imagen base universal oficial para RHEL 8 con "systemd" habilitado:
• registry.access.redhat.com/ubi8/ubi-init
No hay una imagen oficial "systemd" para Ubuntu, así que usaremos la imagen mantenida por Jeff Geerling (Jeff Geerling) de la comunidad de Ansible:
• geerlingguy / docker-ubuntu2004-ansible
Para obtener instancias con "systemd", editemos el archivo de configuración "molécula / default / molécula.yml" eliminando la instancia "centos: 7" y agregando dos nuevas instancias:
$ vi molecule/default/molecule.yml
---
dependency:
name: galaxy
driver:
name: podman
platforms:
- name: rhel8
image: registry.access.redhat.com/ubi8/ubi-init
tmpfs:
- /run
- /tmp
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
capabilities:
- SYS_ADMIN
command: "/usr/sbin/init"
pre_build_image: true
- name: ubuntu
image: geerlingguy/docker-ubuntu2004-ansible
tmpfs:
- /run
- /tmp
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
capabilities:
- SYS_ADMIN
command: "/lib/systemd/systemd"
pre_build_image: true
provisioner:
name: ansible
verifier:
name: ansible
lint: |
set -e
yamllint .
ansible-lint .
Con estos parámetros, montamos para cada instancia un sistema de archivos temporal "/ run" y "/ tmp", así como el volumen "cgroup". Además, incluimos la función "SYS_ADMIN", que es necesaria para ejecutar contenedores con Systemd.
Si hace todo de manera inteligente y ejecuta este ejemplo en una máquina RHEL 8 con SELinux habilitado, entonces también necesita establecer el parámetro booleano "container_manage_cgroup" en verdadero para que los contenedores puedan ejecutar Systemd (consulte la documentación de RHEL 8 para obtener más detalles ):
sudo setsebool -P container_manage_cgroup 1
Molecule usa Ansible Playbook para inicializar estas instancias. Cambiemos y agreguemos los parámetros de inicialización modificando el diccionario "provisioner" en el archivo de configuración "molécula / predeterminado / molécula.yml".
Acepta las mismas opciones de configuración que se especifican en el archivo de configuración "ansible.cfg". Por ejemplo, actualice la configuración del aprovisionador agregando una sección de "valores predeterminados". Configure el intérprete de Python en "auto_silent" para deshabilitar las advertencias. Incluyamos los complementos de devolución de llamada "profile_tasks", "timer" y "yaml" para que la información del generador de perfiles se incluya en la salida del Playbook. Finalmente, agregue la sección "ssh_connection" y deshabilite la canalización SSH ya que no funciona con Podman:
provisioner:
name: ansible
config_options:
defaults:
interpreter_python: auto_silent
callback_whitelist: profile_tasks, timer, yaml
ssh_connection:
pipelining: false
Guardemos este archivo y creemos una instancia con el comando "crear molécula" desde el directorio raíz de nuestro rol:
$ molecule create
Molecule ejecutará el libro de jugadas de inicio y creará nuestras dos instancias. Comprobémoslos con el comando "lista de moléculas":
$ molecule list
Instance Name Driver Name Provisioner Name Scenario Name Created Converged
--------------- ------------- ------------------ --------------- --------- -----------
rhel8 podman ansible default true false
ubuntu podman ansible default true false
También verifiquemos que ambos contenedores se estén ejecutando en Podman:
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2e2f14eaa37b docker.io/geerlingguy/docker-ubuntu2004-ansible:latest /lib/systemd/syst... About a minute ago Up About a minute ago ubuntu
2ce0a0ea8692 registry.access.redhat.com/ubi8/ubi-init:latest /usr/sbin/init About a minute ago Up About a minute ago rhel8
Al desarrollar un rol, Molecule usa instancias en ejecución para probarlo. Si la prueba falla o algún error da lugar a cambios irreversibles, por lo que todo tiene que empezar de nuevo, puedes matar estas instancias en cualquier momento con el comando "molécula destruir" y recrearlas con el comando "molécula crear".
Conclusión
Si está impaciente y desea profundizar en el tema del desarrollo y la prueba de roles, o el tema de la automatización de Ansible, le recomendamos los siguientes recursos:
- Informe técnico de Ansible: cómo lograr actualizaciones continuas y una implementación continua
- Informe técnico de Ansible: Ansible en profundidad
- Guía de inicio: documentación de la molécula
- ansible-community/molecule: Molecule aids in the development and testing of Ansible roles
- Roles in the official Ansible documentation
- Galaxy Developer Guide