Как работать с Ansible при использовании условий и других условных операторов

Если вам нужно выполнить задачи Ansible в зависимости от различных условий, то вам повезло. Ansible when и другие условные операторы позволяют вам оценивать условия, например, основанные на ОС или если одна задача зависит от предыдущей.

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

Давайте приступим!

Предварительные требования

Это руководство включает практические примеры. Если вы хотите следовать за ними, убедитесь, что у вас есть следующее:

  • Хост-контроллер Ansible – в этом руководстве используется Ansible v2.9.24, установленный на машине с Ubuntu 18.04.5 LTS.
  • A remote computer to run commands.
  • Вам понадобится файл инвентаризации и один или несколько хостов, уже настроенных для выполнения команд и плейбуков Ansible. В руководстве будет использоваться группа инвентаризации с именем web.

Работа с Ansible when с несколькими задачами в плейбуке

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

1. Откройте терминал на хосте контроллера Ansible.

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

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

# Создать каталог с именем ~/ansible_when_condition_demo
mkdir ~/ansible_when_condition_demo
# Изменить рабочий каталог на ~/ansible_when_condition_demo
cd ~/ansible_when_condition_demo

3. В вашем предпочтительном редакторе кода создайте файл YAML в каталоге ~/ansible_when_condition_demo. В этом примере файл называется my_playbook.yml. Скопируйте и вставьте содержимое сценария YAML ниже в файл my_playbook.yml.

В обеих задачах ниже (Задача-1 и Задача-2) условия when проверяют, на какой операционной системе находится каждый удаленный хост. Результат затем передается в заполнитель переменной ansible_os_family для каждой задачи.

Если значение заполнителей ansible_os_family равно RedHat или Debian, то Ansible выполняет одну из задач по установке Apache.

---
- name: Ansible tasks to work on Ansible When
# Определение удаленного сервера, на котором будет выполняться Ansible
  hosts: web
  remote_user: ubuntu # Использование удаленного хоста как ubuntu
  become: true # Запуск задач от имени привилегированного пользователя (sudo)
  tasks:

# (Задача-1) Проверяет, равно ли ansible_os_family "RedHat", и затем устанавливает Apache на удаленный узел
    - name: Install Apache on CentOS  Server
      yum: name=httpd  state=present
      become: yes
      when: ansible_os_family == "RedHat"

# (Задача-2) Проверяет, равно ли ansible_os_family "Debian", и затем устанавливает Apache на удаленный узел
    - name: Install Apache on Ubuntu Server
      apt:name=apache2 state=present
      become: yes
      when: ansible_os_family == "Debian"

4. Теперь выполните команду ansible-playbook ниже, чтобы выполнить задачи, определенные в файле сценария (my_playbook.yml) на удаленном хосте, определенном в вашем существующем файле инвентаризации.

ansible-playbook my_playbook.yml 

На скриншоте ниже вы можете видеть, что:

  • Первая ЗАДАЧА вернула статус OK, что показывает, что для задачи не требуется никаких изменений.
  • Вторая ЗАДАЧА вернула статус skipping. Когда условие не выполняется, задача будет пропущена.
  • Третья ЗАДАЧА вернула статус changed, что указывает на то, что удаленный хост не находился в правильном состоянии (т. е. Apache отсутствует) и был изменен для установки Apache.
Invoking the ansible-playbook using ansible-playbook command

5. Откройте сеанс SSH на удаленном хосте, который был целью плейбука Ansible, с использованием вашего любимого SSH-клиента, чтобы убедиться, что Apache установлен и работает.

6. Наконец, выполните команду service ниже, чтобы проверить, установлен ли Apache (status apache2) на удаленном хосте.

service status apache2

Как видите ниже, вы установили службу Apache на удаленной машине.

Verifying the Apache service on the remote node

Работа с Ansible when и циклами

Ранее вы выполняли задачи Ansible в соответствии с условием Ansible when для определенного параметра, такого как ansible_os_family. Но, возможно, вам нужно проверить условие с несколькими параметрами, определенными в списке. Если это так, попробуйте добавить цикл loop в задачу.

Откройте файл my_playbook.yml, который вы ранее создали (шаг три в разделе «Работа с Ansible when с множественными задачами в плейбуке»). Замените содержимое файла my_playbook.yml на приведенный ниже код.

Задача в приведенном ниже коде (Task-1) выполняет loop, где условие when проверяет, является ли значение элемента больше пяти, и возвращает результат.

---
- name: Ansible tasks to work on Ansible When
# Определение удаленного сервера, на котором будет выполняться Ansible
  hosts: web
  remote_user: ubuntu   # Использование удаленного хоста как ubuntu
  become: true
  tasks:
  # (Задача -1) Проверка, является ли значение элемента больше 5
    - name: Run with items greater than 5
      ansible.builtin.command: echo {{ item }}
      loop: [ 0, 2, 4, 6, 8, 10 ]
      when: item > 5*

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

 ansible-playbook my_playbook.yml

Ниже вы можете видеть возвращенную задачу со статусом пропущено для случая, когда условие ложно, и статус изменено для случая, когда условие истинно.

Checking the when condition for multiple parameters

Работа с Ansible, используя when и факты Ansible facts

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

Замените содержимое файла my_playbook.yml на следующий код.

В приведенном ниже коде обе задачи (Task-1 и Task-2) выполняются только (выключение системы), если хотя бы одно из условий истинно:

  • И distribution, и distribtion_major_version возвращают истинное значение.
  • Значение os_family равно CentOS.
---
- name: Ansible When Single task example
  hosts: web
  remote_user: ubuntu
  become: true
  tasks:
# (Task-1): Выключить удаленный узел, если дистрибутив - CentOS с версией 6 
    - name: Shut down CentOS 6 systems
      ansible.builtin.command: /sbin/shutdown -t now
      when:
        - ansible_facts['distribution'] == "CentOS"
        - ansible_facts['distribution_major_version'] == "6"
# (Task-2): Выключить удаленный узел, если семейство операционной системы - CentOS. 
    - name: Shut down CentOS flavored systems
      ansible.builtin.command: /sbin/shutdown -t now
      when: ansible_facts['os_family'] == "CentOS"

Выполните плейбук, как вы делали ранее, с помощью следующей команды.

ansible-playbook my_playbook.yml

Обратите внимание, что обе задачи показывают статус пропущено, так как вы используете Ubuntu. Задача выполняется только в случае использования CentOS.

Executing the ansible-playbook with Ansible facts in Ansible when

Работа с Ansible when на основе зарегистрированных значений

Иногда вам может потребоваться выполнить или пропустить задачу в зависимости от результата предыдущей задачи в плейбуке. Например, вы можете захотеть настроить сервис после выполнения предыдущей задачи обновления. В таком случае используйте зарегистрированную переменную. Зарегистрированная переменная позволяет зарегистрировать результат предыдущей задачи как переменную и использовать ее для следующей задачи как входные данные.

1. Создайте пустой каталог с именем /home/ubuntu/hello.

2. Замените содержимое файла my_playbook.yml на приведенный ниже код, который выполняет следующее:

Первая задача (Task-1) перечисляет содержимое (файлы и подкаталоги) каталога /etc/hosts в памяти и сохраняет этот результат в переменную contents1 с помощью команды register.

Вторая задача (Task-2) перечисляет содержимое (в настоящее время пустое) каталога /home/ubuntu/hello в памяти и сохраняет этот список в переменную contents2.

Третья задача (Task-3) проверяет и выводит сообщение “Каталог пуст” если зарегистрированный результат для переменной contents1 или contents2 пуст.

Свойство stdout переменной contents1 и contents2 – это сохраненный вывод оболочки из результатов выполнения команд задачи.

---
- name: Ansible When Single task example
  hosts: web
  remote_user: ubuntu
  become: true
  tasks:
# (Задача-1): Вывести содержимое каталога в каталоге /etc/hosts
      - name: List contents of directory and Store in content1
        ansible.builtin.command: ls /etc/hosts
        register: contents1
# (Задача-2): Вывести содержимое каталога в /home/ubuntu/hello
      - name: List contents of directory and Store in content2
        ansible.builtin.command: ls /home/ubuntu/hello
        register: contents2
# (Задача-3): Отобразить "Каталог пуст", если любой из каталогов 
# /etc/hosts или /home/ubuntu/hello является пустым каталогом
      - name: Check contents for emptiness for content1 or content2
        ansible.builtin.debug:
          msg: "Directory is empty"
        when: contents1.stdout == "" or contents2.stdout == ""

3. Наконец, выполните плейбук с помощью команды ansible-playbook ниже.

ansible-playbook my_playbook.yml

Как показано ниже, поскольку зарегистрированный результат для переменной contents2 пуст, третья задача возвращает сообщение Каталог пуст.

Running the Ansible playbook for Ansible when based on registered values

Работа с условием Ansible when в ролях Ansible

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

1. Выполните команды ниже, чтобы создать каталог с именем ~/ansible_role_when_demo в вашем домашнем каталоге и перейти в этот каталог в качестве рабочего. Каталог ~/ansible_role_when_demo будет содержать файлы демонстрации этого примера.

# Создание каталога с именем ~/ansible_role_when_demo в вашем домашнем каталоге
mkdir ~/ansible_role_when_demo
# Переход в каталог ~/ansible_role_when_demo
cd ~/ansible_role_when_demo

2. Затем выполните команды ниже, чтобы создать каталог ~/ansible_role_when_demo/roles и ~/ansible_role_when_demo/roles/java/tasks.

Ниже приведено содержимое каждого каталога:

  • Каталог ~/ansible_role_when_demo/roles будет содержать роль, которую вам нужно развернуть.

По умолчанию Ansible ищет роли в двух местах: в каталоге с именем roles/ в каталоге, где находится файл сценария, или в /etc/ansible/roles. Если вы хотите хранить роли в других местах, укажите пути, используя параметр - role: в сценарии.

  • Папка ~/ansible_role_when_demo/roles/java/tasks будет содержать файл main.yml, который вам нужно развернуть в роли.
# Создайте каталог с именем roles внутри каталога ~/ansible_role_when_demo
mkdir -p roles
# Измените рабочий каталог на ~/ansible_role_when_demo/roles
cd roles 
# Создайте родительский (-р) каталог с именем java и подкаталог с именем tasks
mkdir -p java/tasks

Теперь создайте файл с именем main.yml в каталоге ~/ansible_role_when_demo/roles/java/tasks, затем скопируйте и вставьте код плейбука, приведенный ниже, в файл main.yml.

Плейбук ниже устанавливает Java на удаленном узле, на котором он выполняется, с использованием модуля apt.

---
# Установка Java (Open Jdk)
- name: Install Java 1.8
  apt: name=openjdk-8-jdk

4. Создайте еще один файл YAML с предпочтительным вами именем и скопируйте/вставьте приведенный ниже код. В этом примере файл назван ~/ansible_role_when_demo/java-setup.yml.

Приведенный ниже код развертывает роль Ansible (java) для удаленного пользователя (ubuntu), обладающего правами администратора, только если удаленный пользователь находится в Debian OS.

- name: Java Installation playbook
# Определение удаленного сервера, на котором будет развернут пакет
  hosts: myserver
  remote_user: ubuntu   # Использование удаленного пользователя как ubuntu
  become: true
  tasks:  
  roles:
     - role: java
       # Выполнить задачу только в том случае, если remote_user находится в Debian OS.
       when: ansible_facts['os_family'] == 'Debian'

5. Выполните команду tree, чтобы проверить, существуют ли все необходимые папки и файлы в директории ~/ansible_role_when_demo.

Verifying all of the required folders in the ~/ansible_role_when_demo directory

6. Наконец, выполните плейбук с помощью команды ansible-playbook ниже. ansible-playbook java-setup.yml

ansible-playbook java-setup.yml

Ниже задача вернула статус changed, указывающий на успешную установку Java, так как удаленный узел работает под управлением операционной системы Debian. Запуск плейбука Ansible с использованием Ansible when с ролями Ansible

Running the Ansible playbook using Ansible when with Ansible roles

Заключение

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

Теперь как вы бы расширили свои знания? Возможно, сэкономить время настройки нескольких серверов с помощью шаблонов Ansible, применяя условия Ansible when?

Source:
https://adamtheautomator.com/ansible-when/