Ansible – это современный инструмент управления конфигурацией. Для связи и выполнения команд на управляемых серверах (нодах) он использует только SSH и Python – то есть вам не нужно устанавливать агентское программное обеспечение на удаленные ноды. В этой серии мануалов вы познакомитесь с основными функциями Ansible, которые можно использовать для написания сценариев автоматизации серверов. В конце серии вы найдете практический пример плейбука для автоматизации настройки удаленного веб-сервера Nginx и развертывания на нем статического HTML-сайта.
Примечание: Этот мануал является частью серии по работе с Ansible. Другие мануалы из этой серии вы найдете по тегу ansible-practice. Весь код можно найти в этом репозитории.
В Ansible можно определять условия, которые будут оцениваться перед выполнением задачи: если условие не выполнено, задача пропускается. Условия определяются с помощью ключевого слова when. Оно принимает выражения, которые, как правило, основаны на переменной или факте.
В следующем примере мы определили две переменные: create_user_file и user. Если create_user_file оценивается как true, в домашнем каталоге пользователя, заданном переменной user, будет создан новый файл.
Создайте новый файл по имени playbook-04.yml в каталоге ansible-practice:
nano ~/ansible-practice/playbook-04.yml
Затем добавьте в новый плейбук следующие строки:
---
- hosts: all
vars:
- create_user_file: yes
- user: 8host
tasks:
- name: create file for user
file:
path: /home/{{ user }}/myfile
state: touch
when: create_user_file
Сохраните и закройте файл.
Чтобы запустить этот плейбук на серверах из вашего инвентаря, используйте команду ansible-playbook с теми же аргументами подключения, которые вы использовали ранее (при запуске других плейбуков из этой серии мануалов). Мы снова будем использовать файл инвентаря по имени inventory и пользователя 8host для подключения к удаленным серверам (замените эти данные своими):
ansible-playbook -i inventory playbook-04.yml -u 8host
Если условие выполнено, вы увидите статус changed в выводе плея:
... TASK [create file for user] ***************************************************************************** changed: [203.0.113.10] ...
Если вы измените значение create_user_file на no, условие будет оценено как false. В таком случае в выводе плея вы увидите статус skipping, указывающий, что задача не была выполнена:
... TASK [create file for user] ***************************************************************************** skipping: [203.0.113.10] ...
Чаще всего в контексте сценариев Ansible условия объединяются с register. Это ключевое слово, которое создает новую переменную и присваивает ей полученный результат команды. Таким образом, для оценки выполнения задачи вы можете использовать любую внешнюю команду.
Важно отметить: если команда, которую вы используете для оценки условия, не срабатывает, по умолчанию Ansible прерывает плей. Чтобы отключить это поведение, нужно добавить в задачу директиву ignore_errors со значением yes, и это заставит Ansible перейти к следующей задаче и продолжить обработку плея.
В следующем примере новый файл создается в домашнем каталоге пользователя только в том случае, если он еще не существует – а это мы проверим с помощью команды ls. Если же файл существует, плейбук выведет сообщение с помощью модуля debug.
В нашем каталоге ansible-practice создайте новый файл с именем playbook-05.yml:
nano ~/ansible-practice/playbook-05.yml
Затем добавьте в новый плейбук следующий контент:
---
- hosts: all
vars:
- user: 8host
tasks:
- name: Check if file already exists
command: ls /home/{{ user }}/myfile
register: file_exists
ignore_errors: yes
- name: create file for user
file:
path: /home/{{ user }}/myfile
state: touch
when: file_exists is failed
- name: show message if file exists
debug:
msg: The user file already exists.
when: file_exists is succeeded
Сохраните и закройте файл.
Затем запустите команду ansible-playbook с аргументами подключения из предыдущих примеров (мы, как обычно, используем инвентарь по имени inventory и пользователя 8host, но вам следует соответствующим образом изменить эти значения):
ansible-playbook -i inventory playbook-05.yml -u 8host
При первом запуске этого плейбука выполнение команды завершится ошибкой, поскольку такой файл не существует по этому пути. Затем будет выполнена задача, создающая файл, а последняя задача будет пропущена:
...
TASK [Check if file already exists] *********************************************************************
fatal: [203.0.113.10]: FAILED! => {"changed": true, "cmd": ["ls", "/home/8host/myfile"], "delta": "0:00:00.004258", "end": "2020-10-22 13:10:12.680074", "msg": "non-zero return code", "rc": 2, "start": "2020-10-22 13:10:12.675816", "stderr": "ls: cannot access '/home/8host/myfile': No such file or directory", "stderr_lines": ["ls: cannot access '/home/8host/myfile': No such file or directory"], "stdout": "", "stdout_lines": []}
...ignoring
TASK [create file for user] *****************************************************************************
changed: [203.0.113.10]
TASK [show message if file exists] **********************************************************************
skipping: [203.0.113.10]
...
По выходным данным вы можете увидеть, что задача «create file for user» вызвала изменение на сервере, следовательно, файл был создан. Теперь запустите плейбук еще раз:
ansible-playbook -i inventory playbook-05.yml -u 8host
и вы получите другой результат:
...
TASK [Check if file already exists] *********************************************************************
changed: [203.0.113.10]
TASK [create file for user] *****************************************************************************
skipping: [203.0.113.10]
TASK [show message if file exists] **********************************************************************
ok: [203.0.113.10] => {
"msg": "The user file already exists."
}
...
Больше информации об условиях в плейбуках Ansible вы найдете в официальной документации инструмента.
