Escribir Playbooks idempotentes con módulos comunes

AnsibleBeginner
Practicar Ahora

Introducción

La idempotencia significa que un playbook puede ejecutarse repetidamente y solo realizará cambios en el sistema cuando el estado deseado no exista o sea diferente al actual.

En este laboratorio, utilizará módulos comunes de Ansible para crear directorios y archivos de configuración para alias de hosts, y luego ejecutará el playbook dos veces para demostrar que la segunda ejecución es estable.

Crear un proyecto de práctica de idempotencia

En este paso, creará un pequeño proyecto de Ansible con dos alias de hosts gestionados locales. Cada alias escribe en su propio directorio para que pueda ver los resultados específicos de cada host mientras permanece dentro de una única máquina virtual RHEL 10.

Comience desde el espacio de trabajo predeterminado de LabEx.

cd /home/labex/project

La opción -p le indica a mkdir que cree los directorios principales cuando sea necesario y que finalice correctamente si el directorio ya existe.

mkdir -p rhce-ansible/{inventory/group_vars,playbooks,managed,reports}
cd rhce-ansible

Cree los valores predeterminados del proyecto que apuntan Ansible a su inventario y mantienen los archivos de reintento (retry files) deshabilitados.

cat > ansible.cfg <<'EOF'
[defaults]
inventory = ./inventory/hosts
host_key_checking = False
retry_files_enabled = False
EOF

El directorio managed contendrá los archivos producidos por el playbook, mientras que reports guardará la salida del playbook. Mantenerlos separados facilita la comparación del contenido deseado con la evidencia de ejecución de Ansible.

Definir hosts gestionados locales y variables

En este paso, creará un inventario y variables de grupo. Los alias utilizan ansible_connection=local, lo que significa que Ansible apunta a los hosts nombrados mientras se ejecuta de forma segura en esta máquina virtual. Antes de ejecutar los comandos en este paso, regrese al directorio del proyecto de Ansible. Esto mantiene los comandos estables incluso cuando LabEx ejecuta cada paso por separado.

cd /home/labex/project/rhce-ansible

Cree dos alias de hosts de aplicación en un grupo.

cat > inventory/hosts <<'EOF'
[app]
app1 ansible_connection=local
app2 ansible_connection=local
EOF

Las variables de grupo describen el estado deseado compartido por cada host en el grupo.

cat > inventory/group_vars/app.yml <<'EOF'
app_owner: labex
app_environment: training
app_message: Managed by Ansible common modules
EOF

Confirme que Ansible puede ver los dos hosts.

ansible app --list-hosts

La salida debería listar app1 y app2. Esta comprobación es útil antes de escribir un playbook, ya que una ejecución (play) dirigida a app solo puede afectar a los hosts que el inventario resuelve en ese grupo.

Escribir un playbook de estado deseado

En este paso, escribirá un playbook que utiliza file, copy y lineinfile. Estos módulos describen el estado final en lugar de ejecutar comandos de shell manualmente. Antes de ejecutar los comandos en este paso, regrese al directorio del proyecto de Ansible. Esto mantiene los comandos estables incluso cuando LabEx ejecuta cada paso por separado.

cd /home/labex/project/rhce-ansible

Cree el playbook. Las rutas incluyen {{ inventory_hostname }} para que cada alias obtenga su propio directorio de salida.

cat > playbooks/common-modules.yml <<'EOF'
---
- name: Configure app host directories with common modules
  hosts: app
  gather_facts: false
  tasks:
    - name: Ensure host directory exists
      ansible.builtin.file:
        path: "/home/labex/project/rhce-ansible/managed/{{ inventory_hostname }}"
        state: directory
        mode: '0755'

    - name: Install base application configuration
      ansible.builtin.copy:
        dest: "/home/labex/project/rhce-ansible/managed/{{ inventory_hostname }}/app.conf"
        content: |
          owner={{ app_owner }}
          environment={{ app_environment }}
          message={{ app_message }}
        mode: '0644'

    - name: Ensure managed message is present
      ansible.builtin.lineinfile:
        path: "/home/labex/project/rhce-ansible/managed/{{ inventory_hostname }}/app.conf"
        line: "message={{ app_message }}"
        create: true
        mode: '0644'
EOF

La tarea file crea el directorio, la tarea copy escribe la configuración completa y la tarea lineinfile demuestra cómo asegurar una línea específica. Estos módulos comparan el estado actual con el estado deseado, razón por la cual pueden ser idempotentes.

Utilice la comprobación de sintaxis antes de ejecutar un nuevo playbook.

ansible-playbook playbooks/common-modules.yml --syntax-check

Ejecutar el playbook e inspeccionar los archivos

En este paso, ejecutará el playbook de estado deseado por primera vez. La primera ejecución debería informar cambios porque los archivos de destino aún no existen. Antes de ejecutar los comandos en este paso, regrese al directorio del proyecto de Ansible. Esto mantiene los comandos estables incluso cuando LabEx ejecuta cada paso por separado.

cd /home/labex/project/rhce-ansible

Ejecute el playbook y guarde la salida para una comparación posterior.

ansible-playbook playbooks/common-modules.yml | tee reports/first-run.txt

La primera ejecución debería informar cambios porque los directorios de host y los archivos app.conf son nuevos. tee le permite observar la ejecución mientras guarda la misma salida para la comprobación de idempotencia.

Inspeccione los archivos específicos del host que creó Ansible.

cat managed/app1/app.conf managed/app2/app.conf

Ambos archivos deberían contener los mismos valores de propietario, entorno y mensaje, pero residen en directorios de alias de host diferentes. Esto demuestra que el playbook aplicó el mismo estado deseado a cada host del inventario.

Ejecutar el playbook nuevamente para probar la idempotencia

En este paso, ejecutará el mismo playbook nuevamente. Debido a que los archivos ya coinciden con el estado deseado, Ansible debería informar cero cambios para ambos hosts. Antes de ejecutar los comandos en este paso, regrese al directorio del proyecto de Ansible. Esto mantiene los comandos estables incluso cuando LabEx ejecuta cada paso por separado.

cd /home/labex/project/rhce-ansible

Ejecute el playbook por segunda vez y guarde la salida.

ansible-playbook playbooks/common-modules.yml | tee reports/second-run.txt

Busque changed=0 en las líneas de resumen.

grep -E 'app[12].*changed=0' reports/second-run.txt

changed=0 en la segunda ejecución es la señal clave de idempotencia. Significa que los módulos inspeccionaron los archivos existentes y determinaron que no era necesaria ninguna reparación.

Resumen

Ha construido un proyecto de Ansible, utilizado módulos comunes para describir el estado deseado, ejecutado el playbook y demostrado la idempotencia con una segunda ejecución que no informó cambios.