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:
- Haga clic en el icono del Explorador en el WebIDE
- Navegue hasta el directorio
/home/labex/project/ansible - Haga clic con el botón derecho y seleccione "Nuevo archivo"
- Nombre el archivo
hosts - 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:
- En el WebIDE, navegue hasta el directorio
/home/labex/project/ansible - Cree un nuevo archivo llamado
facts_playbook.yml - 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
localdefinido 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:
- En el WebIDE, navegue hasta el directorio
/home/labex/project/ansible - Cree un nuevo archivo llamado
no_facts_playbook.yml - 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
registerpara 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:
- En el WebIDE, navegue hasta el directorio
/home/labex/project/ansible - Cree un nuevo archivo llamado
compare_timing.sh - 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
- Haga que el script sea ejecutable:
chmod +x compare_timing.sh
- 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 hechoshardware: Información de CPU, memoria y dispositivosnetwork: Información de interfaz de red y enrutamientovirtual: Detalles de virtualizaciónohai: 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:
- En el WebIDE, navegue hasta el directorio
/home/labex/project/ansible - Cree un nuevo archivo llamado
selective_facts_playbook.yml - 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_subsetpara 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:
- En el WebIDE, cree un nuevo archivo llamado
multiple_subsets_playbook.yml - 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:
- En el WebIDE, navegue hasta el directorio
/home/labex/project/ansible - Cree un nuevo archivo llamado
conditional_facts_playbook.yml - 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:
- En el WebIDE, cree un nuevo archivo llamado
practical_conditional_playbook.yml - 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:
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.
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.
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.
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.
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.


