¿Cómo configurar la opción gather_facts en un playbook de Ansible?

AnsibleBeginner
Practicar Ahora

Introducción

Ansible es una poderosa herramienta de automatización de TI que ayuda a los administradores de sistemas y desarrolladores a gestionar la infraestructura de manera eficiente. Una de sus características clave es la capacidad de recopilar información sobre los sistemas objetivo, conocida como "facts" (hechos). La opción gather_facts en Ansible determina si y cómo se recopila esta información durante la ejecución del playbook.

En este laboratorio práctico, aprenderá a configurar la opción gather_facts en los playbooks de Ansible. Explorará diferentes configuraciones, comprenderá cuándo habilitar o deshabilitar la recopilación de hechos, y descubrirá cómo usar los hechos recopilados para hacer que sus playbooks sean más dinámicos y eficientes. Al final de este laboratorio, podrá optimizar sus flujos de trabajo de Ansible controlando el proceso de recopilación de hechos de acuerdo con sus necesidades específicas.

Instalación de Ansible y exploración de la opción gather_facts

Comencemos instalando Ansible y explorando qué hace la opción gather_facts. En este paso, instalaremos Ansible, crearemos un inventario simple y ejecutaremos un comando para ver qué hechos se recopilan.

Instalación de Ansible

Primero, instalemos Ansible en nuestro sistema:

sudo apt update
sudo apt install -y ansible

Después de que se complete la instalación, verifique que Ansible esté instalado correctamente:

ansible --version

Debería ver una salida similar a esta:

ansible [core 2.12.x]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/labex/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/labex/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.x (default, Aug 14 2022, 00:00:00) [GCC 11.2.0]
  jinja version = 3.0.3
  libyaml = True

Creación de un inventario simple

Ahora, creemos un archivo de inventario simple para trabajar. El archivo de inventario define los hosts que Ansible gestionará. Para este laboratorio, crearemos un inventario local:

mkdir -p ~/project/ansible
cd ~/project/ansible

Cree un archivo de inventario llamado hosts usando el editor:

  1. Haga clic en el icono del Explorador en el WebIDE
  2. Navegue hasta el directorio /home/labex/project/ansible
  3. Haga clic con el botón derecho y seleccione "Nuevo archivo"
  4. Nombre el archivo hosts
  5. Agregue el siguiente contenido:
[local]
localhost ansible_connection=local

Este inventario configura un grupo llamado local con un solo host: localhost. El parámetro ansible_connection=local le dice a Ansible que ejecute los comandos directamente en la máquina local sin usar SSH.

Explorando gather_facts

Ejecutemos un comando simple de Ansible para ver qué hechos se recopilan de forma predeterminada:

cd ~/project/ansible
ansible local -i hosts -m setup

El comando anterior usa:

  • local: el grupo de nuestro inventario
  • -i hosts: especifica nuestro archivo de inventario
  • -m setup: ejecuta el módulo setup, que recopila hechos

Verá una gran salida JSON con información detallada sobre su sistema, incluyendo:

  • Información del hardware (CPU, memoria)
  • Configuración de la red
  • Detalles del sistema operativo
  • Variables de entorno
  • Y mucho más

Esta información es lo que Ansible recopila cuando gather_facts está habilitado (que es el comportamiento predeterminado). Estos hechos se pueden usar en los playbooks para tomar decisiones o personalizar tareas basadas en las características del sistema objetivo.

Creación de un playbook básico con la recopilación de hechos predeterminada

En este paso, crearemos un playbook básico de Ansible que utiliza el comportamiento predeterminado de recopilación de hechos y muestra parte de la información recopilada.

Comprensión de los playbooks de Ansible

Un playbook de Ansible es un archivo YAML que contiene una lista de tareas a ejecutar en los hosts gestionados. Los playbooks proporcionan una forma de definir la configuración, el despliegue y los pasos de orquestación en un formato simple y legible por humanos.

Creación de su primer playbook

Creemos un playbook simple que mostrará algunos de los hechos que Ansible recopila de forma predeterminada:

  1. En el WebIDE, navegue hasta el directorio /home/labex/project/ansible
  2. Cree un nuevo archivo llamado facts_playbook.yml
  3. Agregue el siguiente contenido:
---
- name: Show System Facts
  hosts: local
  ## By default, gather_facts is set to 'true'

  tasks:
    - name: Display operating system
      debug:
        msg: "Operating System: {{ ansible_distribution }} {{ ansible_distribution_version }}"

    - name: Display CPU information
      debug:
        msg: "CPU: {{ ansible_processor[1] }} with {{ ansible_processor_cores }} cores"

    - name: Display memory information
      debug:
        msg: "Total Memory: {{ ansible_memtotal_mb }} MB"

    - name: Display Python version
      debug:
        msg: "Python version: {{ ansible_python_version }}"

Este playbook:

  • Se dirige al grupo local definido en nuestro inventario
  • Habilita implícitamente la recopilación de hechos (comportamiento predeterminado)
  • Contiene cuatro tareas que muestran diferentes fragmentos de información recopilados por Ansible

Ejecución del playbook

Ahora, ejecutemos el playbook para ver los hechos recopilados en acción:

cd ~/project/ansible
ansible-playbook -i hosts facts_playbook.yml

Debería ver una salida similar a esta:

PLAY [Show System Facts] *****************************************************

TASK [Gathering Facts] *******************************************************
ok: [localhost]

TASK [Display operating system] **********************************************
ok: [localhost] => {
    "msg": "Operating System: Ubuntu 22.04"
}

TASK [Display CPU information] ***********************************************
ok: [localhost] => {
    "msg": "CPU: Intel(R) Xeon(R) CPU with 2 cores"
}

TASK [Display memory information] ********************************************
ok: [localhost] => {
    "msg": "Total Memory: 3907 MB"
}

TASK [Display Python version] ************************************************
ok: [localhost] => {
    "msg": "Python version: 3.10.6"
}

PLAY RECAP *******************************************************************
localhost                  : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Observe la primera tarea en la salida: TASK [Gathering Facts]. Esto es Ansible recopilando automáticamente hechos antes de ejecutar cualquiera de nuestras tareas definidas, porque el valor predeterminado de gather_facts es true.

El playbook luego muestra con éxito información sobre su sistema utilizando los hechos recopilados. Cada hecho se referencia utilizando una variable con el prefijo ansible_.

Deshabilitar la recopilación de hechos para mejorar el rendimiento

En este paso, aprenderemos a deshabilitar la recopilación de hechos para mejorar el rendimiento del playbook en situaciones donde los hechos no son necesarios.

Comprender cuándo deshabilitar la recopilación de hechos

Si bien la recopilación de hechos es útil, puede agregar una sobrecarga innecesaria en ciertos escenarios:

  • Cuando está ejecutando tareas simples que no requieren información del sistema
  • Cuando está ejecutando playbooks con frecuencia y los hechos no cambian
  • Cuando desea optimizar el tiempo de ejecución del playbook

Deshabilitar la recopilación de hechos puede mejorar significativamente la velocidad de ejecución del playbook, especialmente cuando se gestionan muchos hosts.

Creación de un playbook con la recopilación de hechos deshabilitada

Creemos un nuevo playbook que tenga la recopilación de hechos deshabilitada:

  1. En el WebIDE, navegue hasta el directorio /home/labex/project/ansible
  2. Cree un nuevo archivo llamado no_facts_playbook.yml
  3. Agregue el siguiente contenido:
---
- name: Playbook with Disabled Fact Gathering
  hosts: local
  gather_facts: false

  tasks:
    - name: Display current time
      command: date
      register: current_time

    - name: Show the current time
      debug:
        msg: "Current time is: {{ current_time.stdout }}"

    - name: List files in the project directory
      command: ls -la ~/project
      register: file_list

    - name: Show file list
      debug:
        msg: "Project directory contents:\n{{ file_list.stdout }}"

Este playbook:

  • Deshabilita explícitamente la recopilación de hechos con gather_facts: false
  • Ejecuta comandos que no dependen de los hechos del sistema
  • Utiliza la palabra clave register para capturar las salidas de los comandos
  • Muestra la información capturada utilizando el módulo debug

Ejecución del playbook con la recopilación de hechos deshabilitada

Ejecutemos el playbook y observemos las diferencias:

cd ~/project/ansible
ansible-playbook -i hosts no_facts_playbook.yml

Debería ver una salida similar a esta:

PLAY [Playbook with Disabled Fact Gathering] *********************************

TASK [Display current time] **************************************************
changed: [localhost]

TASK [Show the current time] *************************************************
ok: [localhost] => {
    "msg": "Current time is: Wed May 17 15:30:45 UTC 2023"
}

TASK [List files in the project directory] ***********************************
changed: [localhost]

TASK [Show file list] ********************************************************
ok: [localhost] => {
    "msg": "Project directory contents:\ntotal 20\ndrwxr-xr-x 3 labex labex 4096 May 17 15:25 .\ndrwxr-xr-x 4 labex labex 4096 May 17 15:20 ..\ndrwxr-xr-x 2 labex labex 4096 May 17 15:25 ansible\n"
}

PLAY RECAP *******************************************************************
localhost                  : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Observe que no hay ninguna tarea Gathering Facts en la salida esta vez. El playbook comienza directamente con nuestra primera tarea definida.

Comparación de los tiempos de ejecución

Para ver la diferencia de rendimiento, creemos un script de temporización simple:

  1. En el WebIDE, navegue hasta el directorio /home/labex/project/ansible
  2. Cree un nuevo archivo llamado compare_timing.sh
  3. Agregue el siguiente contenido:
#!/bin/bash

echo "Running playbook with fact gathering enabled..."
time ansible-playbook -i hosts facts_playbook.yml > /dev/null

echo -e "\nRunning playbook with fact gathering disabled..."
time ansible-playbook -i hosts no_facts_playbook.yml > /dev/null
  1. Haga que el script sea ejecutable:
chmod +x compare_timing.sh
  1. Ejecute el script de comparación:
./compare_timing.sh

Debería ver una salida que muestra que el playbook con la recopilación de hechos deshabilitada se ejecuta más rápido que el que tiene la recopilación de hechos habilitada. La diferencia podría ser pequeña en nuestro ejemplo simple, pero puede ser significativa al ejecutar playbooks complejos en múltiples hosts remotos.

Uso de la recopilación selectiva de hechos

En algunos casos, es posible que necesite solo hechos específicos en lugar de toda la información del sistema. Ansible permite la recopilación selectiva de hechos para optimizar el rendimiento mientras aún recopila la información que necesita.

Comprensión de los subconjuntos de hechos

Ansible organiza los hechos en subconjuntos, como:

  • all: Todos los hechos (predeterminado)
  • min / minimal: Un conjunto mínimo de hechos
  • hardware: Información de CPU, memoria y dispositivos
  • network: Información de interfaz de red y enrutamiento
  • virtual: Detalles de virtualización
  • ohai: Hechos de Ohai (si está disponible)
  • facter: Hechos de Facter (si está disponible)

Al seleccionar solo los hechos que necesita, puede mejorar el rendimiento del playbook mientras aún tiene acceso a la información necesaria.

Creación de un playbook con recopilación selectiva de hechos

Creemos un playbook que recopile solo hechos relacionados con el hardware:

  1. En el WebIDE, navegue hasta el directorio /home/labex/project/ansible
  2. Cree un nuevo archivo llamado selective_facts_playbook.yml
  3. Agregue el siguiente contenido:
---
- name: Selective Fact Gathering
  hosts: local
  gather_facts: true
  gather_subset:
    - "!all" ## Exclude all facts by default
    - "hardware" ## Then include only hardware facts

  tasks:
    - name: Display CPU information
      debug:
        msg: "CPU: {{ ansible_processor[1] }} with {{ ansible_processor_cores }} cores"

    - name: Display memory information
      debug:
        msg: "Total Memory: {{ ansible_memtotal_mb }} MB"

    - name: Try to access network facts (should fail)
      debug:
        msg: "Default IPv4 Address: {{ ansible_default_ipv4.address }}"
      ignore_errors: true

Este playbook:

  • Habilita la recopilación de hechos con gather_facts: true
  • Utiliza gather_subset para restringir qué hechos se recopilan
  • Primero excluye todos los hechos con !all
  • Luego incluye solo los hechos de hardware con hardware
  • Intenta acceder a los hechos de la red (que no se recopilaron) para demostrar la limitación

Ejecución del playbook con recopilación selectiva de hechos

Ejecutemos el playbook para ver la recopilación selectiva de hechos en acción:

cd ~/project/ansible
ansible-playbook -i hosts selective_facts_playbook.yml

Debería ver una salida similar a esta:

PLAY [Selective Fact Gathering] **********************************************

TASK [Gathering Facts] *******************************************************
ok: [localhost]

TASK [Display CPU information] ***********************************************
ok: [localhost] => {
    "msg": "CPU: Intel(R) Xeon(R) CPU with 2 cores"
}

TASK [Display memory information] ********************************************
ok: [localhost] => {
    "msg": "Total Memory: 3907 MB"
}

TASK [Try to access network facts (should fail)] *****************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'address'..."}
...ignoring

PLAY RECAP *******************************************************************
localhost                  : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1

Observe que las dos primeras tareas se completan con éxito porque acceden a los hechos de hardware que se recopilaron, pero la tercera tarea falla porque no se recopilaron los hechos de la red. Usamos ignore_errors: true para continuar la ejecución del playbook a pesar de este error.

Creación de un playbook con múltiples subconjuntos de hechos

Ahora, creemos un playbook que recopile hechos de hardware y de red:

  1. En el WebIDE, cree un nuevo archivo llamado multiple_subsets_playbook.yml
  2. Agregue el siguiente contenido:
---
- name: Multiple Fact Subsets
  hosts: local
  gather_facts: true
  gather_subset:
    - "!all" ## Exclude all facts by default
    - "hardware" ## Include hardware facts
    - "network" ## Include network facts

  tasks:
    - name: Display CPU information
      debug:
        msg: "CPU: {{ ansible_processor[1] }} with {{ ansible_processor_cores }} cores"

    - name: Display memory information
      debug:
        msg: "Total Memory: {{ ansible_memtotal_mb }} MB"

    - name: Display network information
      debug:
        msg: "Default IPv4 Address: {{ ansible_default_ipv4.address }}"

Ejecute este playbook:

ansible-playbook -i hosts multiple_subsets_playbook.yml

Esta vez, todas las tareas deberían completarse con éxito porque hemos recopilado hechos de hardware y de red.

Uso de hechos recopilados en tareas condicionales

Uno de los usos más poderosos de los hechos recopilados es la implementación de lógica condicional en sus playbooks. En este paso, crearemos un playbook que utiliza hechos para tomar decisiones sobre qué tareas ejecutar.

Comprensión de las tareas condicionales en Ansible

Ansible le permite usar la palabra clave when para ejecutar tareas condicionalmente basadas en variables, hechos o resultados de tareas. Esto le permite crear playbooks más dinámicos y adaptables.

Creación de un playbook con tareas condicionales

Creemos un playbook que realice diferentes acciones según el sistema operativo:

  1. En el WebIDE, navegue hasta el directorio /home/labex/project/ansible
  2. Cree un nuevo archivo llamado conditional_facts_playbook.yml
  3. Agregue el siguiente contenido:
---
- name: Conditional Tasks Based on Facts
  hosts: local
  gather_facts: true

  tasks:
    - name: Display OS information
      debug:
        msg: "Running on {{ ansible_distribution }} {{ ansible_distribution_version }}"

    - name: Task for Ubuntu systems
      debug:
        msg: "This is an Ubuntu system. Would run apt commands here."
      when: ansible_distribution == "Ubuntu"

    - name: Task for CentOS systems
      debug:
        msg: "This is a CentOS system. Would run yum commands here."
      when: ansible_distribution == "CentOS"

    - name: Task for systems with at least 2GB RAM
      debug:
        msg: "This system has {{ ansible_memtotal_mb }} MB RAM, which is sufficient for our application."
      when: ansible_memtotal_mb >= 2048

    - name: Task for systems with less than 2GB RAM
      debug:
        msg: "This system has only {{ ansible_memtotal_mb }} MB RAM, which may not be sufficient."
      when: ansible_memtotal_mb < 2048

Este playbook:

  • Recopila todos los hechos sobre el sistema
  • Muestra la información del sistema operativo
  • Ejecuta condicionalmente tareas basadas en el tipo de sistema operativo
  • Ejecuta condicionalmente tareas basadas en la cantidad de RAM

Ejecución del playbook condicional

Ejecutemos el playbook para ver las tareas condicionales en acción:

cd ~/project/ansible
ansible-playbook -i hosts conditional_facts_playbook.yml

Dado que estamos ejecutando en Ubuntu, debería ver una salida similar a esta:

PLAY [Conditional Tasks Based on Facts] **************************************

TASK [Gathering Facts] *******************************************************
ok: [localhost]

TASK [Display OS information] ************************************************
ok: [localhost] => {
    "msg": "Running on Ubuntu 22.04"
}

TASK [Task for Ubuntu systems] ***********************************************
ok: [localhost] => {
    "msg": "This is an Ubuntu system. Would run apt commands here."
}

TASK [Task for CentOS systems] ***********************************************
skipping: [localhost]

TASK [Task for systems with at least 2GB RAM] ********************************
ok: [localhost] => {
    "msg": "This system has 3907 MB RAM, which is sufficient for our application."
}

TASK [Task for systems with less than 2GB RAM] *******************************
skipping: [localhost]

PLAY RECAP *******************************************************************
localhost                  : ok=4    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0

Observe cómo algunas tareas se ejecutan mientras que otras se omiten en función de las condiciones. La tarea de CentOS se omite porque estamos ejecutando en Ubuntu, y la tarea "menos de 2GB RAM" se omite porque nuestro sistema tiene más de 2GB de RAM.

Creación de un ejemplo más práctico

Ahora, creemos un ejemplo más práctico que podría usarse en un entorno real:

  1. En el WebIDE, cree un nuevo archivo llamado practical_conditional_playbook.yml
  2. Agregue el siguiente contenido:
---
- name: Practical Conditional Playbook
  hosts: local
  gather_facts: true

  vars:
    app_dir: "/home/labex/project/app"

  tasks:
    - name: Create application directory
      file:
        path: "{{ app_dir }}"
        state: directory
        mode: "0755"

    - name: Configure for production environment
      copy:
        dest: "{{ app_dir }}/config.yml"
        content: |
          environment: production
          memory_limit: high
          debug: false
      when: ansible_memtotal_mb >= 4096

    - name: Configure for development environment
      copy:
        dest: "{{ app_dir }}/config.yml"
        content: |
          environment: development
          memory_limit: low
          debug: true
      when: ansible_memtotal_mb < 4096

    - name: Display configuration
      command: cat {{ app_dir }}/config.yml
      register: config_content

    - name: Show configuration
      debug:
        msg: "{{ config_content.stdout_lines }}"

Este playbook:

  • Crea un directorio para una aplicación
  • Escribe un archivo de configuración diferente según la memoria del sistema disponible
  • Muestra la configuración resultante

Ejecute el playbook práctico:

ansible-playbook -i hosts practical_conditional_playbook.yml

Este ejemplo demuestra cómo puede usar los hechos recopilados para adaptar automáticamente las configuraciones en función de las características del sistema.

Resumen

En este laboratorio, ha aprendido a configurar y usar eficazmente la opción gather_facts en los playbooks de Ansible. Aquí hay un resumen de lo que ha logrado:

  1. Recopilación básica de hechos: Ha instalado Ansible y explorado el comportamiento predeterminado de recopilación de hechos, viendo la amplia gama de información del sistema que Ansible recopila.

  2. Deshabilitar la recopilación de hechos: Ha aprendido a deshabilitar la recopilación de hechos para mejorar el rendimiento del playbook cuando los hechos no son necesarios.

  3. Recopilación selectiva de hechos: Ha descubierto cómo recopilar solo subconjuntos específicos de hechos para equilibrar el rendimiento y tener la información necesaria.

  4. Tareas condicionales: Ha implementado lógica condicional en sus playbooks basada en hechos recopilados, lo que permite un comportamiento dinámico según las características del sistema.

  5. Aplicaciones prácticas: Ha creado ejemplos prácticos que demuestran cómo usar los hechos recopilados en escenarios del mundo real.

Al dominar la opción gather_facts, puede optimizar sus playbooks de Ansible para un mejor rendimiento, manteniendo el acceso a la información del sistema que necesita. Este conocimiento le ayudará a crear flujos de trabajo de automatización más eficientes, flexibles y potentes.

Algunas de las mejores prácticas para recordar:

  • Habilite la recopilación de hechos solo cuando sea necesario
  • Use la recopilación selectiva de hechos cuando necesite solo información específica
  • Aproveche los hechos recopilados para tareas condicionales para que sus playbooks sean más adaptables
  • Considere el almacenamiento en caché de hechos cuando ejecute playbooks con frecuencia en los mismos hosts

Con estas habilidades, está bien equipado para crear una automatización de Ansible más sofisticada y eficiente para sus necesidades de gestión de infraestructura.