Gestionar variables y hechos en RHEL con Ansible

AnsibleBeginner
Practicar Ahora

Introducción

En este laboratorio, aprenderás técnicas fundamentales para gestionar variables, hechos (facts) y secretos dentro de los playbooks de Ansible en un sistema Red Hat Enterprise Linux (RHEL). Explorarás cómo hacer que tu automatización sea más flexible y potente mediante el uso de variables en los playbooks, la recopilación de información del sistema con hechos de Ansible (tanto integrados como personalizados) y la protección de datos confidenciales, como contraseñas, utilizando Ansible Vault.

A través de una serie de pasos prácticos, construirás un playbook para desplegar y configurar un servidor web Apache. Comenzarás definiendo variables simples para el nombre del paquete y el contenido web, luego aprovecharás los hechos personalizados para actualizar dinámicamente la configuración del servidor web. Finalmente, utilizarás Ansible Vault para crear de forma segura un nuevo usuario del sistema con una contraseña cifrada, ejecutarás el playbook completo y verificarás que todas las configuraciones se hayan aplicado correctamente.

Definir y utilizar variables de playbook para desplegar un servidor web Apache

En este paso, aprenderás a utilizar variables en un playbook de Ansible. Las variables son esenciales para que tu automatización sea flexible, reutilizable y más fácil de leer y mantener. En lugar de codificar valores como nombres de paquetes o rutas de archivos directamente en tus tareas, puedes definirlos como variables y hacer referencia a ellos a lo largo del playbook. Crearemos un playbook sencillo que utiliza variables para instalar el servidor web Apache (httpd) y desplegar una página web básica.

  1. Navegar al directorio del proyecto

    Primero, asegúrate de estar en el directorio de trabajo correcto. Todo tu trabajo para este laboratorio se realizará dentro del directorio ~/project, el cual ha sido creado para ti.

    cd ~/project
    

    Instala el paquete ansible-core.

    sudo dnf install -y ansible-core
    
  2. Crear el playbook de Ansible

    Ahora, vamos a crear nuestro archivo de playbook. Lo llamaremos playbook.yml. Puedes utilizar un editor de texto de línea de comandos como nano para crear y editar el archivo.

    nano playbook.yml
    

    Este comando abre un archivo vacío en el editor nano. Ahora, añade la parte inicial del playbook. Esta sección define el nombre del play, el host de destino (localhost, ya que lo estamos ejecutando en la misma máquina) y una sección vars donde definiremos nuestras variables.

    ---
    - name: Deploy Apache using variables
      hosts: localhost
      become: true
      vars:
        web_pkg: httpd
        web_content: "Hello from Ansible Variables"
    

    Aquí tienes un desglose de la estructura del playbook:

    • hosts: localhost: Especifica que el playbook debe ejecutarse en la máquina local.
    • become: true: Indica a Ansible que utilice la elevación de privilegios (equivalente a sudo) para las tareas, lo cual es necesario para instalar software.
    • vars: Es un diccionario donde definimos nuestros pares clave-valor para las variables. Hemos definido web_pkg para el nombre del paquete y web_content para el contenido de nuestra página web de prueba.
  3. Añadir tareas al playbook

    A continuación, debajo de la sección vars, añade las tasks que utilizarán estas variables. La primera tarea instalará el paquete de Apache y la segunda creará un archivo index.html. Añade el siguiente bloque de tasks a tu archivo playbook.yml mientras sigues en el editor nano.

    tasks:
      - name: Install the latest version of Apache
        ansible.builtin.dnf:
          name: "{{ web_pkg }}"
          state: latest
    
      - name: Create a basic index.html file
        ansible.builtin.copy:
          content: "{{ web_content }}"
          dest: /var/www/html/index.html
    

    Observa cómo utilizamos {{ variable_name }} para hacer referencia a las variables que definimos anteriormente. Esto es la plantilla Jinja2, que Ansible utiliza para las variables. Esto hace que las definiciones de las tareas sean genéricas; si quisieras instalar Nginx en su lugar, solo tendrías que cambiar la variable web_pkg, no la tarea en sí.

  4. Revisar y guardar el playbook

    Tu archivo playbook.yml completo debería verse ahora así. Verifica dos veces el contenido y la sangría, ya que YAML es muy sensible a los espacios.

    ---
    - name: Deploy Apache using variables
      hosts: localhost
      become: true
      vars:
        web_pkg: httpd
        web_content: "Hello from Ansible Variables"
      tasks:
        - name: Install the latest version of Apache
          ansible.builtin.dnf:
            name: "{{ web_pkg }}"
            state: latest
    
        - name: Create a basic index.html file
          ansible.builtin.copy:
            content: "{{ web_content }}"
            dest: /var/www/html/index.html
    

    Para guardar el archivo en nano, presiona Ctrl+X, luego Y para confirmar los cambios y, finalmente, Enter para escribir el archivo con el nombre playbook.yml.

  5. Comprobar la sintaxis del playbook

    Antes de ejecutar un playbook, siempre es una buena práctica comprobar su sintaxis para detectar errores.

    ansible-playbook --syntax-check playbook.yml
    

    Si la sintaxis es correcta, verás la ruta del archivo del playbook como salida, confirmando que es válido:

    playbook: playbook.yml
    

    Si ves algún error, vuelve a abrir el archivo con nano playbook.yml y corrígelo. Presta mucha atención a la sangría correcta (normalmente dos espacios).

  6. Ejecutar el playbook

    Ahora, ejecuta el playbook. Ansible se conectará a localhost, leerá las variables y ejecutará las tareas.

    ansible-playbook playbook.yml
    

    Deberías ver una salida que indica la ejecución exitosa de cada tarea. El estado changed significa que Ansible realizó una modificación en el sistema, como instalar un paquete o crear un archivo.

    PLAY [Deploy Apache using variables] *******************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Install the latest version of Apache] ************************************
    changed: [localhost]
    
    TASK [Create a basic index.html file] ******************************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

    Si ejecutas el playbook por segunda vez, las tareas deberían informar ok en lugar de changed, porque el paquete ya está instalado y el archivo ya tiene el contenido correcto. Esto demuestra la idempotencia de Ansible.

  7. Verificar la configuración manualmente

    Aunque el playbook se ha completado, puedes verificar manualmente que las tareas funcionaron como se esperaba. Primero, comprueba si el paquete httpd se instaló:

    rpm -q httpd
    

    La salida debería mostrar el nombre del paquete y la versión:

    httpd-2.4.57-7.el9.x86_64
    

    A continuación, comprueba el contenido del archivo index.html:

    cat /var/www/html/index.html
    

    La salida debería coincidir con el valor de tu variable web_content:

    Hello from Ansible Variables
    

    Has utilizado con éxito variables en un playbook de Ansible para configurar un sistema.

Mostrar información del sistema utilizando hechos de Ansible

En este paso, explorarás los hechos (facts) de Ansible. Los hechos son piezas de información que Ansible recopila sobre los sistemas que gestiona (en este caso, localhost). Esta información incluye detalles como el sistema operativo, las interfaces de red, la memoria y mucho más. Por defecto, Ansible recopila hechos al comienzo de cada play, poniéndolos a disposición en una variable especial llamada ansible_facts. El uso de hechos te permite crear playbooks dinámicos que se adaptan al entorno en el que se ejecutan.

  1. Navegar al directorio del proyecto

    Primero, asegúrate de estar en el directorio ~/project donde crearás el nuevo playbook.

    cd ~/project
    
  2. Crear un playbook para mostrar todos los hechos

    Comencemos creando un playbook que simplemente muestre todos los hechos que Ansible puede recopilar sobre tu sistema. Esto te dará una idea de la gran cantidad de información disponible. Utiliza nano para crear un nuevo archivo llamado display_facts.yml.

    nano display_facts.yml
    

    Dentro del editor nano, añade el siguiente contenido. Este playbook apunta a localhost y utiliza el módulo ansible.builtin.debug para imprimir el contenido de la variable ansible_facts.

    ---
    - name: Display all Ansible facts
      hosts: localhost
      tasks:
        - name: Print all available facts
          ansible.builtin.debug:
            var: ansible_facts
    

    Guarda el archivo y sal de nano presionando Ctrl+X, luego Y y Enter.

  3. Ejecutar el playbook

    Ahora, ejecuta el playbook para ver el resultado.

    ansible-playbook display_facts.yml
    

    La salida será muy larga, ya que Ansible recopila muchos datos. Será una gran estructura JSON que contiene todos los detalles del sistema. Esto es lo esperado.

    PLAY [Display all Ansible facts] ***********************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Print all available facts] ***********************************************
    ok: [localhost] => {
        "ansible_facts": {
            "ansible_all_ipv4_addresses": [
                "172.17.0.2"
            ],
            "ansible_all_ipv6_addresses": [
                "fe80::42:acff:fe11:2"
            ],
            "ansible_apparmor": {
                "status": "disabled"
            },
            "ansible_architecture": "x86_64",
            "ansible_bios_date": "01/01/2011",
            "ansible_bios_version": "1.0",
            "ansible_cmdline": {
                "BOOT_IMAGE": "/boot/vmlinuz-5.14.0-427.16.1.el9_4.x86_64",
                "root": "UUID=...",
                "ro": true
            },
            "ansible_date_time": {
                "date": "2024-05-21",
                "day": "21",
                "epoch": "1716298855",
                ...
            },
            "ansible_distribution": "RedHat",
            "ansible_distribution_major_version": "9",
            "ansible_distribution_version": "9.4",
            ...
        }
    }
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
  4. Crear un playbook para mostrar hechos específicos

    Mostrar todos los hechos es útil para el descubrimiento, pero en la mayoría de los casos, solo necesitas piezas de información específicas. Vamos a crear otro playbook, display_specific_facts.yml, para mostrar un mensaje formateado con solo unos pocos hechos clave.

    nano display_specific_facts.yml
    

    Añade el siguiente contenido. Este playbook utiliza el parámetro msg del módulo debug para imprimir una cadena personalizada. Accedemos a hechos individuales utilizando la notación de corchetes, como ansible_facts['distribution'].

    ---
    - name: Display specific Ansible facts
      hosts: localhost
      tasks:
        - name: Print a summary of system facts
          ansible.builtin.debug:
            msg: >
              The operating system is {{ ansible_facts['distribution'] }}
              version {{ ansible_facts['distribution_major_version'] }}.
              It has {{ ansible_facts['processor_cores'] }} processor cores and
              {{ ansible_facts['memtotal_mb'] }} MB of total memory.
    

    El carácter > en msg: > es una característica de YAML que te permite escribir una cadena de varias líneas de forma más limpia. Guarda el archivo y sal de nano.

  5. Ejecutar el playbook para hechos específicos

    Ahora, ejecuta este nuevo playbook.

    ansible-playbook display_specific_facts.yml
    

    La salida será mucho más limpia y legible, mostrando solo la información que solicitaste.

    PLAY [Display specific Ansible facts] ******************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Print a summary of system facts] *****************************************
    ok: [localhost] => {
        "msg": "The operating system is RedHat version 9. It has 2 processor cores and 3925 MB of total memory."
    }
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

    Esto demuestra cómo puedes aprovechar los hechos de Ansible para que tus playbooks sean conscientes del entorno en el que se ejecutan, permitiendo una automatización más inteligente y condicional.

Configurar el servidor web utilizando hechos personalizados del host gestionado

En este paso, aprenderás a utilizar hechos personalizados. Aunque Ansible recopila automáticamente una amplia gama de hechos estándar, también puedes definir los tuyos propios. Estos se denominan "hechos locales" o "hechos personalizados". Esta es una característica potente que te permite proporcionar información específica desde un host gestionado a tus playbooks, como configuraciones de aplicaciones o datos específicos del hardware que Ansible no recopila por defecto.

Ansible busca hechos personalizados en el directorio /etc/ansible/facts.d en el host gestionado. Cualquier archivo en este directorio con una extensión .fact será procesado. Estos archivos pueden ser archivos de texto simples al estilo INI o archivos JSON.

  1. Crear el directorio de hechos personalizados

    Primero, necesitas crear el directorio donde Ansible buscará los archivos de hechos personalizados. Dado que este es un directorio del sistema, debes usar sudo para crearlo.

    sudo mkdir -p /etc/ansible/facts.d
    

    La bandera -p asegura que el comando no devuelva un error si el directorio ya existe.

  2. Crear un archivo de hechos personalizados

    Ahora, vamos a crear un archivo de hechos personalizados para definir un mensaje de bienvenida para nuestro servidor web. Crearemos un archivo con formato INI llamado web_config.fact dentro del directorio /etc/ansible/facts.d.

    sudo nano /etc/ansible/facts.d/web_config.fact
    

    Añade el siguiente contenido al archivo. Esto define una sección [webserver] con una clave welcome_message.

    [webserver]
    welcome_message = Welcome to the server configured by Custom Facts!
    

    Guarda el archivo y sal de nano presionando Ctrl+X, luego Y y Enter.

  3. Crear un playbook para utilizar el hecho personalizado

    Con el hecho personalizado en su lugar, ahora podemos crear un playbook que lea este hecho y lo utilice para configurar la página de inicio de nuestro servidor web. En tu directorio ~/project, crea un nuevo playbook llamado configure_web.yml.

    cd ~/project
    nano configure_web.yml
    

    Añade el siguiente contenido al playbook. Este playbook actualizará el archivo /var/www/html/index.html con el mensaje definido en nuestro hecho personalizado.

    ---
    - name: Configure web server using custom facts
      hosts: localhost
      become: true
      tasks:
        - name: Update index.html with custom message
          ansible.builtin.copy:
            content: "{{ ansible_facts.ansible_local.web_config.webserver.welcome_message }}"
            dest: /var/www/html/index.html
    

    Desglosemos la variable {{ ansible_facts.ansible_local.web_config.webserver.welcome_message }}:

    • ansible_facts: El diccionario raíz para todos los hechos.
    • ansible_local: La clave donde se almacenan todos los hechos personalizados.
    • web_config: El nombre de nuestro archivo de hechos (web_config.fact), sin la extensión.
    • webserver: El nombre de la sección [webserver] de nuestro archivo INI.
    • welcome_message: La clave para el valor que queremos utilizar.

    Guarda el archivo y sal de nano.

  4. Ejecutar el playbook de configuración

    Ahora, ejecuta el playbook para aplicar la configuración.

    ansible-playbook configure_web.yml
    

    La salida debería mostrar que la tarea copy ha realizado un changed en el archivo index.html.

    PLAY [Configure web server using custom facts] *********************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Update index.html with custom message] ***********************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
  5. Verificar el resultado

    Finalmente, verifiquemos que la página web se actualizó correctamente. Utiliza el comando cat para ver el contenido del archivo index.html.

    cat /var/www/html/index.html
    

    La salida debería mostrar ahora el mensaje de tu archivo de hechos personalizados:

    Welcome to the server configured by Custom Facts!
    

    Has creado con éxito un hecho personalizado en el host gestionado y lo has utilizado dentro de un playbook para configurar dinámicamente un servicio. Esta técnica es increíblemente útil para hacer que tu automatización sea más flexible y basada en datos.

Crear un usuario del sistema utilizando variables cifradas con Ansible Vault

En este paso, aprenderás a gestionar datos confidenciales, como contraseñas o claves API, utilizando Ansible Vault. Almacenar información confidencial en texto plano dentro de tus playbooks es un riesgo de seguridad importante. Ansible Vault proporciona una forma de cifrar archivos o variables individuales, manteniendo tus secretos a salvo. Luego puedes utilizar estos archivos cifrados en tus playbooks, y Ansible los descifrará en tiempo de ejecución cuando proporciones la contraseña correcta.

Crearemos un archivo cifrado que contiene un nombre de usuario y una contraseña con hash, y luego utilizaremos un playbook para crear un nuevo usuario del sistema con estas credenciales.

  1. Navegar al directorio del proyecto

    Asegúrate de estar en el directorio ~/project para esta tarea.

    cd ~/project
    
  2. Crear un archivo Vault cifrado

    Utilizaremos el comando ansible-vault create para crear un nuevo archivo YAML cifrado llamado secrets.yml. Este comando te pedirá que crees una contraseña para el vault. Esta contraseña es necesaria para abrir, editar o utilizar el archivo más adelante.

    Primero, configuremos el editor a nano para facilitar el trabajo:

    export EDITOR=nano
    

    Ahora crea el archivo vault:

    ansible-vault create secrets.yml
    

    Cuando se te solicite, introduce una contraseña para tu vault. Para este laboratorio, usemos labex como contraseña del vault para simplificar las cosas. Tendrás que introducirla dos veces.

    New Vault password:
    Confirm New Vault password:
    

    Después de confirmar la contraseña, el comando abrirá el archivo secrets.yml en el editor de texto nano.

  3. Añadir variables secretas al archivo Vault

    Dentro del editor nano, que ahora está editando el archivo cifrado secrets.yml, añade las siguientes variables. Definiremos un nombre de usuario y una contraseña pre-hasheada para un nuevo usuario. Usar una contraseña con hash es mucho más seguro que almacenar una contraseña en texto plano.

    username: myappuser
    pwhash: $6$mysalt$QwMzWSEyCAGmz7tzVrAi5o.8k4d05i2QsfGGwmPtlJsWhGjSjCW6yFCH/OEqEsHk7GMSxqYNXu5sshxPmWyxo0
    
    • username: El nombre del usuario del sistema que queremos crear.
    • pwhash: Una contraseña cifrada de forma segura. Este hash específico corresponde a la contraseña AnsibleUserP@ssw0rd y está en un formato que el módulo ansible.builtin.user entiende.

    Guarda el archivo y sal de nano (Ctrl+X, luego Y, luego Enter). El archivo secrets.yml en tu directorio ~/project ahora está cifrado. Si intentas verlo con cat secrets.yml, solo verás texto cifrado.

  4. Crear un playbook para utilizar el archivo Vault

    Ahora, crea un nuevo playbook llamado create_user.yml que utilizará las variables de tu archivo cifrado secrets.yml.

    nano create_user.yml
    

    Añade el siguiente contenido. La directiva vars_files le dice a Ansible que cargue variables desde el archivo especificado.

    ---
    - name: Create a user from secret variables
      hosts: localhost
      become: true
      vars_files:
        - secrets.yml
      tasks:
        - name: Create the {{ username }} user
          ansible.builtin.user:
            name: "{{ username }}"
            password: "{{ pwhash }}"
            state: present
    

    Este playbook creará un usuario con el nombre y el hash de contraseña definidos en secrets.yml. Guarda el archivo y sal de nano.

  5. Ejecutar el playbook con la contraseña del Vault

    Para ejecutar un playbook que utiliza un archivo cifrado, debes proporcionar la contraseña del vault. Puedes hacerlo de forma interactiva utilizando la bandera --ask-vault-pass.

    ansible-playbook --ask-vault-pass create_user.yml
    

    Ansible te pedirá la contraseña del vault. Introduce labex (la contraseña que estableciste en el paso 2).

    Vault password:
    

    Después de proporcionar la contraseña correcta, Ansible descifrará el archivo en memoria y ejecutará el playbook. Deberías ver la siguiente salida, indicando que el usuario fue creado.

    PLAY [Create a user from secret variables] *************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Create the myappuser user] ***********************************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
  6. Verificar que el usuario fue creado

    Puedes confirmar que el myappuser se creó correctamente en el sistema utilizando el comando id.

    id myappuser
    

    Si el usuario existe, verás su información de ID de usuario (uid) e ID de grupo (gid).

    uid=1002(myappuser) gid=1002(myappuser) groups=1002(myappuser)
    

    Esto confirma que has utilizado con éxito Ansible Vault para gestionar datos confidenciales para tus tareas de automatización.

Ejecutar un playbook con un archivo de contraseña de Vault para aplicar configuraciones

En este paso, aprenderás una forma más automatizada de proporcionar la contraseña del vault a Ansible. En el paso anterior, utilizaste --ask-vault-pass para introducir la contraseña de forma interactiva. Aunque esto es seguro, no es adecuado para entornos automatizados como las tuberías CI/CD donde no hay ningún usuario presente para escribir una contraseña.

La solución es utilizar un archivo de contraseña de vault. Este es un archivo de texto simple que contiene la contraseña del vault. Luego puedes hacer referencia a este archivo al ejecutar tu playbook, y Ansible leerá la contraseña automáticamente. Por seguridad, es crucial restringir los permisos de este archivo de contraseña para que solo los usuarios autorizados puedan leerlo.

  1. Navegar al directorio del proyecto

    Asegúrate de estar en el directorio ~/project donde se encuentran tu playbook y tu archivo vault.

    cd ~/project
    
  2. Crear el archivo de contraseña de Vault

    Vamos a crear un archivo para almacenar nuestra contraseña de vault. Lo llamaremos vault_pass.txt. Podemos usar el comando echo para crear el archivo y escribir la contraseña (labex) en él en un solo paso.

    echo "labex" > vault_pass.txt
    

    Puedes verificar el contenido del archivo con cat:

    cat vault_pass.txt
    

    La salida debería ser:

    labex
    
  3. Proteger el archivo de contraseña

    Almacenar una contraseña en un archivo de texto plano es arriesgado. Debes restringir sus permisos de archivo para protegerlo. El comando chmod te permite cambiar los permisos de archivo. Estableceremos los permisos en 600, lo que significa que solo el propietario del archivo (en este caso, el usuario labex) tiene permisos de lectura y escritura. Ningún otro usuario en el sistema podrá acceder a él.

    chmod 600 vault_pass.txt
    

    Puedes verificar los nuevos permisos utilizando el comando ls -l:

    ls -l vault_pass.txt
    

    La salida debería comenzar con -rw-------, confirmando los permisos restringidos.

    -rw-------. 1 labex labex 6 May 21 14:30 vault_pass.txt
    
  4. Modificar el playbook para añadir un usuario a un grupo

    Modifiquemos nuestro playbook create_user.yml para realizar una acción adicional. Añadiremos el myappuser al grupo wheel, que en muchos sistemas otorga privilegios administrativos (sudo). Esto demostrará la ejecución de un playbook que realiza un cambio en una configuración existente.

    Primero, abre el playbook create_user.yml para editarlo.

    nano create_user.yml
    

    Modifica la tarea ansible.builtin.user para incluir los parámetros groups y append.

    ---
    - name: Create a user from secret variables
      hosts: localhost
      become: true
      vars_files:
        - secrets.yml
      tasks:
        - name: Create the {{ username }} user and add to wheel group
          ansible.builtin.user:
            name: "{{ username }}"
            password: "{{ pwhash }}"
            state: present
            groups: wheel
            append: true
    
    • groups: wheel: Especifica el grupo al que añadir el usuario.
    • append: true: Asegura que el usuario se añada a este grupo sin eliminarlo de ningún otro grupo al que pueda pertenecer.

    Guarda el archivo y sal de nano.

  5. Ejecutar el playbook con el archivo de contraseña de Vault

    Ahora, ejecuta el playbook de nuevo. Esta vez, en lugar de --ask-vault-pass, utiliza la opción --vault-password-file (o su alias más corto --vault-pass-file) para especificar la ruta a tu archivo de contraseña.

    ansible-playbook --vault-password-file vault_pass.txt create_user.yml
    

    Ansible se ejecutará ahora sin pedir una contraseña porque la lee directamente de vault_pass.txt. Deberías ver una salida indicando que la configuración del usuario fue cambiada.

    PLAY [Create a user from secret variables] *************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Create the myappuser user and add to wheel group] ************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

    El estado changed confirma que Ansible modificó el usuario añadiéndolo al grupo wheel.

  6. Verificar la pertenencia al grupo del usuario

    Finalmente, verifica que myappuser es ahora miembro del grupo wheel. Puedes hacerlo con el comando groups.

    groups myappuser
    

    La salida debería mostrar tanto el grupo principal del usuario (myappuser) como el grupo wheel.

    myappuser : myappuser wheel
    

    Has utilizado con éxito un archivo de contraseña de vault para ejecutar un playbook de forma no interactiva, una habilidad clave para automatizar flujos de trabajo seguros.

Verificar la configuración del servidor web y del usuario

En este paso final, consolidarás tu aprendizaje creando un playbook de verificación dedicado. Hasta ahora, has estado comprobando manualmente los resultados de tus playbooks utilizando comandos estándar de Linux como cat, id y groups. Un enfoque más potente y repetible es utilizar Ansible para auditar y validar el estado de tu sistema.

Este playbook actuará como un conjunto de pruebas, comprobando programáticamente que el servidor web está instalado, la página web tiene el contenido correcto y el usuario del sistema existe con la pertenencia al grupo adecuada. Esto demuestra cómo Ansible puede utilizarse no solo para la gestión de la configuración, sino también para el cumplimiento y la validación del estado.

  1. Navegar al directorio del proyecto

    Primero, asegúrate de estar en el directorio ~/project.

    cd ~/project
    
  2. Crear el playbook de verificación

    Vamos a crear un nuevo playbook llamado verify_config.yml. Este playbook contendrá una serie de tareas que comprueban las configuraciones que aplicaste en los pasos anteriores.

    nano verify_config.yml
    
  3. Añadir tareas para verificar la configuración

    Dentro del editor nano, añade el siguiente contenido. Construiremos este playbook con varias tareas, cada una diseñada para afirmar que una condición específica es verdadera. Si alguna afirmación falla, el playbook se detendrá e informará de un error, diciéndote inmediatamente qué está mal.

    ---
    - name: Verify system configuration
      hosts: localhost
      become: true
      tasks:
        - name: Check if httpd package is installed
          ansible.builtin.dnf:
            list: httpd
          register: httpd_pkg_info
    
        - name: Assert that httpd is installed
          ansible.builtin.assert:
            that:
              - httpd_pkg_info.results | length > 0
            fail_msg: "Apache (httpd) package is not installed."
            success_msg: "Apache (httpd) package is installed."
    
        - name: Read the content of the index.html file
          ansible.builtin.slurp:
            src: /var/www/html/index.html
          register: index_file
    
        - name: Assert that the web page content is correct
          ansible.builtin.assert:
            that:
              - "'Custom Facts' in (index_file.content | b64decode)"
            fail_msg: "Web page content is incorrect."
            success_msg: "Web page content is correct."
    
        - name: Check if myappuser exists
          ansible.builtin.getent:
            database: passwd
            key: myappuser
          register: user_info
    
        - name: Assert that myappuser exists
          ansible.builtin.assert:
            that:
              - user_info.ansible_facts.getent_passwd['myappuser'] is defined
            fail_msg: "User 'myappuser' does not exist."
            success_msg: "User 'myappuser' exists."
    
        - name: Query the wheel group members
          ansible.builtin.getent:
            database: group
            key: wheel
          register: wheel_group_info
    
        - name: Assert that myappuser is in the wheel group
          ansible.builtin.assert:
            that:
              - "'myappuser' in (wheel_group_info.ansible_facts.getent_group['wheel'][2] | default('') | split(','))"
            fail_msg: "User 'myappuser' is not in the wheel group."
            success_msg: "User 'myappuser' is in the wheel group."
    

    Revisemos los módulos clave utilizados aquí:

    • ansible.builtin.dnf con list: Esto comprueba un paquete y registra el resultado.
    • ansible.builtin.slurp: Esto "absorbe" todo el contenido de un archivo desde el host remoto. El contenido está codificado en base64 para un transporte seguro.
    • ansible.builtin.getent: Esta es una forma segura de consultar bases de datos del sistema como passwd y group. Los resultados se almacenan bajo ansible_facts, por lo que se accede a los datos devueltos a través de claves como user_info.ansible_facts.getent_passwd.
    • ansible.builtin.assert: Este es el núcleo de nuestra verificación. Comprueba si una condición dada es verdadera. Si no, falla el play. Proporcionamos mensajes personalizados de éxito y error.
    • b64decode: Este es un filtro de Jinja2 utilizado para decodificar el contenido en base64 que obtuvimos del módulo slurp.

    Observa que consultamos las bases de datos passwd y group por separado. Esto mantiene la comprobación de existencia del usuario y la comprobación de pertenencia al grupo wheel alineadas con los datos reales devueltos por getent.

    Guarda el archivo y sal de nano (Ctrl+X, Y, Enter).

  4. Ejecutar el playbook de verificación

    Ahora, ejecuta tu playbook de verificación. Como no utiliza ningún archivo cifrado, no necesitas proporcionar una contraseña.

    ansible-playbook verify_config.yml
    

    Si todos tus pasos anteriores se completaron correctamente, el playbook se ejecutará con éxito y verás el mensaje de éxito personalizado para cada afirmación.

    PLAY [Verify system configuration] *********************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Check if httpd package is installed] *************************************
    ok: [localhost]
    
    TASK [Assert that httpd is installed] ******************************************
    ok: [localhost] => {
        "changed": false,
        "msg": "Apache (httpd) package is installed."
    }
    
    TASK [Read the content of the index.html file] *********************************
    ok: [localhost]
    
    TASK [Assert that the web page content is correct] *****************************
    ok: [localhost] => {
        "changed": false,
        "msg": "Web page content is correct."
    }
    
    TASK [Check if myappuser exists] ***********************************************
    ok: [localhost]
    
    TASK [Assert that myappuser exists] ********************************************
    ok: [localhost] => {
        "changed": false,
        "msg": "User 'myappuser' exists."
    }
    
    TASK [Query the wheel group members] *******************************************
    ok: [localhost]
    
    TASK [Assert that myappuser is in the wheel group] *****************************
    ok: [localhost] => {
        "changed": false,
        "msg": "User 'myappuser' is in the wheel group."
    }
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=9    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

    ¡Felicidades! Has utilizado con éxito Ansible para definir variables, recopilar hechos del sistema, gestionar secretos con Vault y, finalmente, verificar el estado de tu sistema de forma automatizada.

Resumen

En este laboratorio, aprendiste a gestionar diferentes tipos de datos dentro de los playbooks de Ansible para configurar un sistema RHEL. Comenzaste definiendo y utilizando variables de playbook estándar para instalar y configurar de forma flexible un servidor web Apache. A continuación, exploraste cómo aprovechar los hechos integrados de Ansible para mostrar información del sistema, proporcionando una base para crear tareas de automatización dinámicas y conscientes del host.

Basándote en esto, configuraste aún más el servidor web creando y utilizando hechos personalizados desde el host gestionado. Para manejar información confidencial de forma segura, utilizaste Ansible Vault para cifrar una contraseña de usuario, creaste un nuevo usuario del sistema con esta variable cifrada y ejecutaste el playbook de forma no interactiva con un archivo de contraseña de vault. El laboratorio concluyó verificando que tanto el servidor web como el nuevo usuario del sistema estuvieran configurados correctamente, confirmando la aplicación exitosa de todos los conceptos aprendidos.