Cómo trabajar con Ansible When y otras condiciones

Si necesitas ejecutar tareas de Ansible basadas en diferentes condiciones, estás de suerte. Ansible when y otras condicionales te permiten evaluar condiciones, como basadas en el sistema operativo, o si una tarea depende de la tarea anterior.

En este tutorial, aprenderás cómo trabajar con Ansible when y otras condicionales para que puedas ejecutar tareas sin complicaciones.

¡Empecemos!

Prerrequisitos

Este tutorial comprende ejemplos prácticos. Si quieres seguirlo, asegúrate de tener lo siguiente en su lugar:

  • A remote computer to run commands.
  • Necesitarás un archivo de inventario configurado y uno o más hosts ya configurados para ejecutar comandos y playbooks de Ansible. El tutorial utilizará un grupo de inventario llamado web.

Trabajando con Ansible when con Múltiples Tareas en el Playbook

Tener múltiples tareas en un libro de jugadas puede ser molesto si todas se ejecutan sin condiciones específicas. Comencemos este tutorial definiendo las condiciones de when en el libro de jugadas de Ansible con múltiples tareas.

1. Abre una terminal en el host controlador de Ansible.

2. Ejecuta los comandos a continuación para crear un directorio y darle el nombre que prefieras en tu directorio principal, y navega hacia ese directorio.

En este ejemplo, el directorio se llama ansible_when_condition_demo. Este directorio contendrá el libro de jugadas que usarás para invocar la condición when dentro de la tarea de Ansible.

# Crea un directorio llamado ~/ansible_when_condition_demo
mkdir ~/ansible_when_condition_demo
# Cambia el directorio de trabajo a ~/ansible_when_condition_demo
cd ~/ansible_when_condition_demo

3. En tu editor de código preferido, crea un archivo YAML en el directorio ~/ansible_when_condition_demo. En este ejemplo, el archivo se llama my_playbook.yml. Copia y pega el contenido del libro de jugadas YAML a continuación en el archivo my_playbook.yml.

En ambas tareas a continuación (Tarea-1 y Tarea-2), las condiciones when verifican en qué sistema operativo se encuentra cada host remoto. El resultado se pasa a la variable de marcador de posición ansible_os_family en cada tarea.

Si el valor de los marcadores de posición ansible_os_family es igual a RedHat o Debian, entonces Ansible ejecuta cualquiera de las tareas para instalar Apache.

---
- name: Ansible tasks to work on Ansible When
# Definición del servidor remoto donde se ejecutará Ansible
  hosts: web
  remote_user: ubuntu # Usando el host remoto como ubuntu
  become: true # Ejecutando las tareas como usuario elevado (sudo)
  tasks:

# (Tarea-1) Verifica si ansible_os_family == "RedHat" y luego instala Apache en el Nodo Remoto
    - name: Install Apache on CentOS  Server
      yum: name=httpd  state=present
      become: yes
      when: ansible_os_family == "RedHat"

# (Tarea-2) Verifica si ansible_os_family == "Debian" y luego instala Apache en el Nodo Remoto
    - name: Install Apache on Ubuntu Server
      apt:name=apache2 state=present
      become: yes
      when: ansible_os_family == "Debian"

4. Ahora ejecuta el comando ansible-playbook a continuación para ejecutar las tareas definidas en el playbook (mi_playbook.yml) en el host remoto, definido en tu archivo de inventario existente.

ansible-playbook my_playbook.yml 

En la captura de pantalla a continuación, puedes ver que:

  • La primera TAREA devolvió un estado OK, lo que muestra que la tarea no requiere cambios.
  • La segunda TAREA devolvió el estado skipping. Cuando no se cumple la condición, la tarea se omite.
  • La tercera TAREA devolvió un estado changed, lo que indica que el host remoto no estaba en el estado adecuado (es decir, Apache no está presente) y se modificó para instalar Apache.
Invoking the ansible-playbook using ansible-playbook command

5. Abre una sesión SSH en el host remoto, que fue el objetivo del playbook de Ansible, utilizando tu cliente SSH favorito para verificar que Apache esté instalado y en funcionamiento.

6. Finalmente, ejecuta el comando service a continuación para verificar si Apache está instalado (status apache2) en el host remoto.

service status apache2

Como puedes ver a continuación, has instalado el servicio Apache en la máquina remota.

Verifying the Apache service on the remote node

Trabajando con Ansible when y bucles

Anteriormente ejecutaste tareas de Ansible según un when de Ansible para un parámetro particular como ansible_os_family. Pero tal vez necesites verificar una condición con múltiples parámetros definidos en una lista. Si es así, intenta agregar un loop en una tarea.

Abre el archivo my_playbook.yml que creaste anteriormente (paso tres bajo “Trabajando con Ansible when con múltiples tareas en el playbook”). Reemplaza el contenido del archivo my_playbook.yml con el código a continuación.

La tarea en el código a continuación (Tarea-1) ejecuta un loop donde la condición when verifica si el valor del elemento es mayor que cinco y devuelve el resultado.

---
- name: Ansible tasks to work on Ansible When
# Definiendo el servidor remoto donde se ejecutará Ansible
  hosts: web
  remote_user: ubuntu   # Usando el host remoto como ubuntu
  become: true
  tasks:
  # (Tarea -1) Verificando si el valor del elemento es mayor que 5
    - name: Run with items greater than 5
      ansible.builtin.command: echo {{ item }}
      loop: [ 0, 2, 4, 6, 8, 10 ]
      when: item > 5*

Ahora ejecuta el comando a continuación para ejecutar el playbook como lo hiciste anteriormente.

 ansible-playbook my_playbook.yml

A continuación, puedes ver el estado devuelto omitir cuando la condición es falsa y cambiado cuando la condición es verdadera.

Checking the when condition for multiple parameters

Trabajando con Ansible when y Ansible facts

Tal vez desees agregar múltiples condiciones para ejecutar una tarea. Si es así, aprende cómo utilizar hechos de Ansible dentro de la condición when. Los hechos de Ansible te permiten agregar una declaración condicional para ejecutar tareas basadas en hechos recopilados, como tu sistema operativo, direcciones IP, sistemas de archivos adjuntos y más.

Reemplaza el contenido del archivo my_playbook.yml con el código a continuación.

En el código siguiente, ambas tareas (Tarea-1 y Tarea-2) solo se ejecutan (apagar el sistema) cuando alguna de las condiciones siguientes es verdadera:

  • Tanto distribution como distribtion_major_version devolvieron un valor verdadero.
  • El valor de os_family es igual a CentOS.
---
- name: Ansible When Single task example
  hosts: web
  remote_user: ubuntu
  become: true
  tasks:
# (Tarea-1): Apagar el nodo remoto si la distribución es CentOS con una versión principal 6 
    - name: Shut down CentOS 6 systems
      ansible.builtin.command: /sbin/shutdown -t now
      when:
        - ansible_facts['distribution'] == "CentOS"
        - ansible_facts['distribution_major_version'] == "6"
# (Tarea-2): Apagar el nodo remoto si la os_family es CentOS. 
    - name: Shut down CentOS flavored systems
      ansible.builtin.command: /sbin/shutdown -t now
      when: ansible_facts['os_family'] == "CentOS"

Ejecuta el playbook como lo hiciste anteriormente con el siguiente comando.

ansible-playbook my_playbook.yml

Observa que ambas tareas muestran el estado omitir ya que estás en Ubuntu. La tarea solo se ejecuta si estás en CentOS.

Executing the ansible-playbook with Ansible facts in Ansible when

Trabajando con Ansible when basado en valores registrados

En ocasiones, es posible que desees ejecutar o omitir una tarea en función del resultado de una tarea anterior en un playbook. Por ejemplo, es posible que desees configurar un servicio después de una actualización de tarea anterior. En ese caso, utiliza una variable registrada. Una variable registrada te permite registrar el resultado de la tarea anterior como una variable y utilizarla en la siguiente tarea como entrada.

1. Crea un directorio vacío llamado /home/ubuntu/hello.

2. Reemplaza el contenido del archivo my_playbook.yml con el siguiente código, que realiza lo siguiente:

La primera tarea (Tarea-1) lista el contenido (archivos y subdirectorios) del directorio /etc/hosts en la memoria y guarda ese resultado en la variable contents1 mediante el comando register.

La segunda tarea (Tarea-2) lista el contenido (actualmente vacío) del directorio /home/ubuntu/hello en la memoria y guarda esa lista en la variable contents2.

La tercera tarea (Tarea-3) verifica e imprime un mensaje de “El directorio está vacío” si el resultado registrado de la variable contents1 o contents2 está vacío.

La propiedad stdout de las variables contents1 y contents2 es la salida de la shell guardada del resultado de ejecutar los comandos de la tarea.

---
- name: Ansible When Single task example
  hosts: web
  remote_user: ubuntu
  become: true
  tasks:
# (Tarea-1): Listar el contenido del directorio en /etc/hosts
      - name: List contents of directory and Store in content1
        ansible.builtin.command: ls /etc/hosts
        register: contents1
# (Tarea-2): Listar el contenido del directorio en /home/ubuntu/hello
      - name: List contents of directory and Store in content2
        ansible.builtin.command: ls /home/ubuntu/hello
        register: contents2
# (Tarea-3): Mostrar que el directorio está vacío si alguno de los directorios
# /etc/hosts o /home/ubuntu/hello está vacío
      - name: Check contents for emptiness for content1 or content2
        ansible.builtin.debug:
          msg: "Directory is empty"
        when: contents1.stdout == "" or contents2.stdout == ""

3. Finalmente, ejecuta el playbook con el comando ansible-playbook a continuación.

ansible-playbook my_playbook.yml

Como se muestra a continuación, dado que el resultado registrado para la variable contents2 está vacío, la tercera tarea devuelve el mensaje El directorio está vacío.

Running the Ansible playbook for Ansible when based on registered values

Trabajando con el condicional when en Roles de Ansible

En este ejemplo final, aprenderás cómo funciona el condicional when en los roles de Ansible. Los roles de Ansible te permiten reutilizar configuraciones estándar y realizar implementaciones más rápidas. Sigue leyendo para aprender cómo una tarea invoca a los roles de Ansible solo si la condición del condicional when es verdadera.

1. Ejecute los siguientes comandos para crear un directorio llamado ~/ansible_role_when_demo en su directorio personal y cambie a esa carpeta como directorio de trabajo. El directorio ~/ansible_role_when_demo contendrá los archivos de demostración de este ejemplo.

# Cree un directorio llamado ~/ansible_role_when_demo en su directorio personal
mkdir ~/ansible_role_when_demo
# Cambie al directorio ~/ansible_role_when_demo
cd ~/ansible_role_when_demo

2. A continuación, ejecute los siguientes comandos para crear un directorio ~/ansible_role_when_demo/roles y ~/ansible_role_when_demo/roles/java/tasks.

A continuación se muestra lo que contendrá cada directorio:

  • El directorio ~/ansible_role_when_demo/roles contendrá el rol que necesita implementar.

De forma predeterminada, Ansible busca roles en dos ubicaciones en un directorio llamado roles/ dentro del directorio donde reside el playbook o en /etc/ansible/roles. Si desea almacenar roles en diferentes rutas, declare las rutas usando el parámetro - role: en el playbook.

  • La carpeta ~/ansible_role_when_demo/roles/java/tasks contendrá un archivo main.yml que necesitará para implementar un rol.
# Crea un directorio llamado roles dentro del directorio ~/ansible_role_when_demo
mkdir -p roles
# Cambia el directorio de trabajo al directorio ~/ansible_role_when_demo/roles
cd roles 
# Crea el directorio padre (-p) llamado java y un subdirectorio llamado tasks
mkdir -p java/tasks

Ahora, crea un archivo llamado main.yml en el directorio ~/ansible_role_when_demo/roles/java/tasks, luego copia y pega el código del playbook a continuación en el archivo main.yml.

El playbook a continuación instala Java en el nodo remoto en el que se ejecuta con el módulo apt.

---
# Instalando Java (Open Jdk)
- name: Install Java 1.8
  apt: name=openjdk-8-jdk

4. Crea otro archivo YAML con el nombre que prefieras y copia/pega el siguiente código. Para este ejemplo, el archivo se llama ~/ansible_role_when_demo/java-setup.yml.

El código a continuación implementa el rol de Ansible (java) en el usuario remoto (ubuntu) que tiene acceso de administrador solo cuando el usuario remoto está en el sistema operativo Debian.

- name: Java Installation playbook
# Definiendo el servidor remoto donde se implementará el paquete
  hosts: myserver
  remote_user: ubuntu   # Usando el usuario remoto como ubuntu
  become: true
  tasks:  
  roles:
     - role: java
       # Ejecutar la tarea solo si el usuario remoto está en un sistema operativo Debian.
       when: ansible_facts['os_family'] == 'Debian'

5. Ejecute el comando tree para verificar que todas las carpetas y archivos requeridos existan en el directorio ~/ansible_role_when_demo.

Verifying all of the required folders in the ~/ansible_role_when_demo directory

6. Finalmente, ejecute el playbook con el comando ansible-playbook a continuación. ansible-playbook java-setup.yml

ansible-playbook java-setup.yml

A continuación, la tarea devolvió un estado cambiado, lo que indica que Java se ha instalado correctamente, ya que el nodo remoto está en un sistema operativo Debian. Ejecutando el playbook de Ansible usando Ansible when con roles de Ansible

Running the Ansible playbook using Ansible when with Ansible roles

Conclusión

En este tutorial, aprendió diferentes formas de utilizar Ansible when y otras condicionales. También aprendió cómo aplicar condiciones when de Ansible, desde tareas básicas aprovechando facts de Ansible hasta implementar roles de Ansible.

Ahora, ¿cómo podría aprovechar este conocimiento recién adquirido? ¿Quizás ahorrar tiempo configurando múltiples servidores con plantillas de Ansible mientras aplica condiciones when de Ansible?

Source:
https://adamtheautomator.com/ansible-when/