Как настроить опцию gather_facts в плейбуке Ansible

AnsibleAnsibleBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

Ansible — это мощный инструмент автоматизации IT, который помогает системным администраторам и разработчикам эффективно управлять инфраструктурой. Одной из его ключевых особенностей является возможность сбора информации о целевых системах, известной как "факты" (facts). Опция gather_facts в Ansible определяет, будет ли и как эта информация собираться во время выполнения плейбука.

В этой практической лабораторной работе вы узнаете, как настроить опцию gather_facts в плейбуках Ansible. Вы изучите различные настройки, поймете, когда следует включать или отключать сбор фактов, и узнаете, как использовать собранные факты, чтобы сделать ваши плейбуки более динамичными и эффективными. К концу этой лабораторной работы вы сможете оптимизировать свои рабочие процессы Ansible, контролируя процесс сбора фактов в соответствии с вашими конкретными потребностями.

Установка Ansible и изучение опции gather_facts

Начнем с установки Ansible и изучения того, что делает опция gather_facts. На этом шаге мы установим Ansible, создадим простой инвентарь и запустим команду, чтобы увидеть, какие факты собираются.

Установка Ansible

Сначала установим Ansible в нашей системе:

sudo apt update
sudo apt install -y ansible

После завершения установки убедитесь, что Ansible установлен правильно:

ansible --version

Вы должны увидеть вывод, похожий на этот:

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

Создание простого инвентаря

Теперь давайте создадим простой файл инвентаря для работы. Файл инвентаря определяет хосты, которыми будет управлять Ansible. Для этой лабораторной работы мы создадим локальный инвентарь:

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

Создайте файл инвентаря с именем hosts, используя редактор:

  1. Нажмите на значок Explorer в WebIDE
  2. Перейдите в каталог /home/labex/project/ansible
  3. Щелкните правой кнопкой мыши и выберите "New File" (Новый файл)
  4. Назовите файл hosts
  5. Добавьте следующее содержимое:
[local]
localhost ansible_connection=local

Этот инвентарь настраивает группу с именем local только с одним хостом - localhost. Параметр ansible_connection=local указывает Ansible выполнять команды непосредственно на локальной машине, не используя SSH.

Изучение gather_facts

Давайте запустим простую команду Ansible, чтобы увидеть, какие факты собираются по умолчанию:

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

Приведенная выше команда использует:

  • local: группу из нашего инвентаря
  • -i hosts: указывает наш файл инвентаря
  • -m setup: запускает модуль setup, который собирает факты

Вы увидите большой вывод в формате JSON с подробной информацией о вашей системе, включая:

  • Информацию об аппаратном обеспечении (CPU, память)
  • Настройку сети
  • Сведения об операционной системе
  • Переменные окружения
  • И многое другое

Эта информация — то, что Ansible собирает, когда gather_facts включен (что является поведением по умолчанию). Эти факты можно использовать в плейбуках для принятия решений или настройки задач в зависимости от характеристик целевой системы.

Создание базового плейбука со сбором фактов по умолчанию

На этом шаге мы создадим базовый плейбук Ansible, который использует поведение сбора фактов по умолчанию и отображает некоторую собранную информацию.

Понимание плейбуков Ansible

Плейбук Ansible — это YAML-файл, содержащий список задач для выполнения на управляемых хостах. Плейбуки предоставляют способ определения шагов конфигурации, развертывания и оркестровки в простом, удобочитаемом формате.

Создание вашего первого плейбука

Давайте создадим простой плейбук, который отобразит некоторые факты, собираемые Ansible по умолчанию:

  1. В WebIDE перейдите в каталог /home/labex/project/ansible
  2. Создайте новый файл с именем facts_playbook.yml
  3. Добавьте следующее содержимое:
---
- 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 }}"

Этот плейбук:

  • Нацелен на группу local, определенную в нашем инвентаре
  • Неявно включает сбор фактов (поведение по умолчанию)
  • Содержит четыре задачи, которые отображают различные части информации, собранной Ansible

Запуск плейбука

Теперь давайте запустим плейбук, чтобы увидеть собранные факты в действии:

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

Вы должны увидеть вывод, похожий на этот:

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

Обратите внимание на первую задачу в выводе: TASK [Gathering Facts]. Это Ansible автоматически собирает факты перед выполнением каких-либо определенных нами задач, потому что значение по умолчанию для gather_facts равно true.

Затем плейбук успешно отображает информацию о вашей системе, используя собранные факты. На каждый факт ссылаются с использованием переменной с префиксом ansible_.

Отключение сбора фактов для повышения производительности

На этом шаге мы узнаем, как отключить сбор фактов, чтобы повысить производительность плейбука в ситуациях, когда факты не нужны.

Понимание, когда следует отключать сбор фактов

Хотя сбор фактов полезен, он может добавить ненужные накладные расходы в определенных сценариях:

  • При выполнении простых задач, которые не требуют информации о системе
  • При частом выполнении плейбуков, когда факты не меняются
  • Когда вы хотите оптимизировать время выполнения плейбука

Отключение сбора фактов может значительно повысить скорость выполнения плейбука, особенно при управлении многими хостами.

Создание плейбука с отключенным сбором фактов

Давайте создадим новый плейбук, в котором сбор фактов отключен:

  1. В WebIDE перейдите в каталог /home/labex/project/ansible
  2. Создайте новый файл с именем no_facts_playbook.yml
  3. Добавьте следующее содержимое:
---
- 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 }}"

Этот плейбук:

  • Явно отключает сбор фактов с помощью gather_facts: false
  • Выполняет команды, которые не зависят от системных фактов
  • Использует ключевое слово register для захвата вывода команд
  • Отображает захваченную информацию с помощью модуля debug

Запуск плейбука с отключенным сбором фактов

Давайте запустим плейбук и посмотрим на различия:

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

Вы должны увидеть вывод, похожий на этот:

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

Обратите внимание, что на этот раз в выводе нет задачи Gathering Facts. Плейбук начинается непосредственно с нашей первой определенной задачи.

Сравнение времени выполнения

Чтобы увидеть разницу в производительности, давайте создадим простой скрипт для измерения времени:

  1. В WebIDE перейдите в каталог /home/labex/project/ansible
  2. Создайте новый файл с именем compare_timing.sh
  3. Добавьте следующее содержимое:
#!/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. Сделайте скрипт исполняемым:
chmod +x compare_timing.sh
  1. Запустите скрипт сравнения:
./compare_timing.sh

Вы должны увидеть вывод, показывающий, что плейбук с отключенным сбором фактов выполняется быстрее, чем плейбук с включенным сбором фактов. Разница может быть небольшой в нашем простом примере, но она может быть значительной при выполнении сложных плейбуков на нескольких удаленных хостах.

Использование выборочного сбора фактов

В некоторых случаях вам могут потребоваться только определенные факты, а не вся информация о системе. Ansible позволяет выполнять выборочный сбор фактов для оптимизации производительности, сохраняя при этом возможность сбора необходимой информации.

Понимание подмножеств фактов

Ansible организует факты в подмножества, такие как:

  • all: Все факты (по умолчанию)
  • min / minimal: Минимальный набор фактов
  • hardware: Информация о процессоре, памяти и устройствах
  • network: Информация о сетевом интерфейсе и маршрутизации
  • virtual: Сведения о виртуализации
  • ohai: Факты из Ohai (если доступны)
  • facter: Факты из Facter (если доступны)

Выбирая только необходимые факты, вы можете повысить производительность плейбука, сохраняя при этом доступ к необходимой информации.

Создание плейбука с выборочным сбором фактов

Давайте создадим плейбук, который собирает только факты, связанные с оборудованием:

  1. В WebIDE перейдите в каталог /home/labex/project/ansible
  2. Создайте новый файл с именем selective_facts_playbook.yml
  3. Добавьте следующее содержимое:
---
- 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

Этот плейбук:

  • Включает сбор фактов с помощью gather_facts: true
  • Использует gather_subset для ограничения собираемых фактов
  • Сначала исключает все факты с помощью !all
  • Затем включает только факты об оборудовании с помощью hardware
  • Пытается получить доступ к сетевым фактам (которые не были собраны), чтобы продемонстрировать ограничение

Запуск плейбука с выборочным сбором фактов

Давайте запустим плейбук, чтобы увидеть выборочный сбор фактов в действии:

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

Вы должны увидеть вывод, похожий на этот:

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

Обратите внимание, что первые две задачи выполнены успешно, потому что они обращаются к фактам об оборудовании, которые были собраны, но третья задача завершается неудачей, потому что сетевые факты не были собраны. Мы использовали ignore_errors: true, чтобы продолжить выполнение плейбука, несмотря на эту ошибку.

Создание плейбука с несколькими подмножествами фактов

Теперь давайте создадим плейбук, который собирает как аппаратные, так и сетевые факты:

  1. В WebIDE создайте новый файл с именем multiple_subsets_playbook.yml
  2. Добавьте следующее содержимое:
---
- 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 }}"

Запустите этот плейбук:

ansible-playbook -i hosts multiple_subsets_playbook.yml

На этот раз все задачи должны быть выполнены успешно, потому что мы собрали как аппаратные, так и сетевые факты.

Использование собранных фактов в условных задачах

Одним из самых мощных способов использования собранных фактов является реализация условной логики в ваших плейбуках. На этом шаге мы создадим плейбук, который использует факты для принятия решений о том, какие задачи запускать.

Понимание условных задач в Ansible

Ansible позволяет использовать ключевое слово when для условного выполнения задач на основе переменных, фактов или результатов задач. Это позволяет создавать более динамичные и адаптируемые плейбуки.

Создание плейбука с условными задачами

Давайте создадим плейбук, который выполняет разные действия в зависимости от операционной системы:

  1. В WebIDE перейдите в каталог /home/labex/project/ansible
  2. Создайте новый файл с именем conditional_facts_playbook.yml
  3. Добавьте следующее содержимое:
---
- 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

Этот плейбук:

  • Собирает все факты о системе
  • Отображает информацию об операционной системе
  • Условно выполняет задачи в зависимости от типа операционной системы
  • Условно выполняет задачи в зависимости от объема оперативной памяти

Запуск условного плейбука

Давайте запустим плейбук, чтобы увидеть условные задачи в действии:

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

Поскольку мы работаем в Ubuntu, вы должны увидеть вывод, похожий на этот:

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

Обратите внимание, как некоторые задачи выполняются, а другие пропускаются в зависимости от условий. Задача CentOS пропускается, потому что мы работаем в Ubuntu, а задача «менее 2 ГБ ОЗУ» пропускается, потому что в нашей системе более 2 ГБ ОЗУ.

Создание более практичного примера

Теперь давайте создадим более практичный пример, который можно использовать в реальной среде:

  1. В WebIDE создайте новый файл с именем practical_conditional_playbook.yml
  2. Добавьте следующее содержимое:
---
- 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 }}"

Этот плейбук:

  • Создает каталог для приложения
  • Записывает другой файл конфигурации в зависимости от доступной памяти системы
  • Отображает полученную конфигурацию

Запустите практичный плейбук:

ansible-playbook -i hosts practical_conditional_playbook.yml

Этот пример демонстрирует, как можно использовать собранные факты для автоматической адаптации конфигураций в зависимости от характеристик системы.

Резюме

В этой лабораторной работе вы узнали, как эффективно настраивать и использовать опцию gather_facts в плейбуках Ansible. Вот краткий обзор того, что вы сделали:

  1. Базовый сбор фактов: Вы установили Ansible и изучили поведение по умолчанию при сборе фактов, увидев широкий спектр системной информации, которую собирает Ansible.

  2. Отключение сбора фактов: Вы узнали, как отключить сбор фактов, чтобы повысить производительность плейбука, когда факты не нужны.

  3. Выборочный сбор фактов: Вы узнали, как собирать только определенные подмножества фактов, чтобы сбалансировать производительность и наличие необходимой информации.

  4. Условные задачи: Вы реализовали условную логику в своих плейбуках на основе собранных фактов, что позволяет динамически изменять поведение в зависимости от характеристик системы.

  5. Практическое применение: Вы создали практические примеры, демонстрирующие использование собранных фактов в реальных сценариях.

Освоив опцию gather_facts, вы можете оптимизировать свои плейбуки Ansible для повышения производительности, сохраняя при этом доступ к необходимой информации о системе. Эти знания помогут вам создавать более эффективные, гибкие и мощные рабочие процессы автоматизации.

Некоторые лучшие практики, которые следует помнить:

  • Включайте сбор фактов только при необходимости
  • Используйте выборочный сбор фактов, когда вам нужна только определенная информация
  • Используйте собранные факты для условных задач, чтобы сделать ваши плейбуки более адаптируемыми
  • Рассмотрите возможность кэширования фактов при частом запуске плейбуков на одних и тех же хостах

Обладая этими навыками, вы хорошо подготовлены к созданию более сложных и эффективных автоматизаций Ansible для управления вашей инфраструктурой.