Desarrollo y prueba de roles de Ansible con Molecule y Podman

Una de las principales ventajas de Red Hat Ansible Automation Platform es que su lenguaje de automatización es legible no solo para un par de gurús, sino también para casi todos los involucrados en TI. Por tanto, cualquier especialista puede contribuir a la automatización, lo que facilita enormemente la organización de la interacción entre equipos y la introducción de la automatización a nivel de cultura corporativa.







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:






All Articles