863 lines
32 KiB
Markdown
863 lines
32 KiB
Markdown
|
###### top
|
|||
|
## Ansible
|
|||
|
[Официальная документация](https://docs.ansible.com/ansible/latest/user_guide/)
|
|||
|
|
|||
|
***
|
|||
|
|
|||
|
[Базовые понятия Ansible](#part1)
|
|||
|
- [inventory](#chapter1)
|
|||
|
- [Модули](#chapter2)
|
|||
|
- [Ad-hoc команды](#chapter3)
|
|||
|
|
|||
|
[Ansible playbook](#part2)
|
|||
|
- [Простой playbook](#chapter4)
|
|||
|
- [Переменные](#chapter5)
|
|||
|
- [Отладка](#chapter6)
|
|||
|
- [Блоки и обработка ошибок](#chapter7)
|
|||
|
- [Асинхронные задачи](#chapter8)
|
|||
|
- [Пример playbook - установка Docker + Docker-compose](#chapter9)
|
|||
|
- [](#chapter10)
|
|||
|
- [](#chapter11)
|
|||
|
- [](#chapter12)
|
|||
|
|
|||
|
***
|
|||
|
|
|||
|
###### part1
|
|||
|
## Базовые понятия Ansible
|
|||
|
[вверх](#top)
|
|||
|
|
|||
|
Установить ansible можно с помощью пакетного менеджера, будет установлена версия, которая есть в репозиториях дистрибутива, скорее всего, эта версия не будет являться последней.
|
|||
|
При установке через пакетный менеджер будет создана папка с параметрами по-умолчанию по пути `/etc/ansible/`.
|
|||
|
|
|||
|
Также, ansible можно установить с помощью pip. Будет установлена последняя версия, но папка с параметрами по-умолчанию создана не будет.
|
|||
|
|
|||
|
###### Chapter1
|
|||
|
### inventory
|
|||
|
https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#intro-inventory
|
|||
|
|
|||
|
Описание хостов, на которых необходимо выполнять какие-то действия производится в файле inventory.
|
|||
|
Синтаксис файла может быть в виде `ini` или `yaml` форматов.
|
|||
|
|
|||
|
Пример описания inventory с использованием ini
|
|||
|
```dosini
|
|||
|
my.domain.com
|
|||
|
|
|||
|
[mygroup]
|
|||
|
domain.com
|
|||
|
app.domain.com
|
|||
|
|
|||
|
[dbservers]
|
|||
|
db.domain.com
|
|||
|
```
|
|||
|
|
|||
|
Пример описания inventory с использованием yaml
|
|||
|
```yaml
|
|||
|
all:
|
|||
|
hosts:
|
|||
|
my.domain.com:
|
|||
|
children:
|
|||
|
mygroup:
|
|||
|
hosts:
|
|||
|
domain.com:
|
|||
|
app.domain.com:
|
|||
|
dbservers:
|
|||
|
hosts:
|
|||
|
db.domain.com:
|
|||
|
```
|
|||
|
|
|||
|
Указывать хосты можно в виде диапазона
|
|||
|
```dosini
|
|||
|
[webservers]
|
|||
|
www[01:50].example.com
|
|||
|
```
|
|||
|
|
|||
|
Для удобства хостам можно задавать свои имена и передавать переменные которые будут доступны на хостах
|
|||
|
```dosini
|
|||
|
[db]
|
|||
|
mydb env=production replicas=2
|
|||
|
```
|
|||
|
|
|||
|
Можно указать параметры подключения
|
|||
|
```dosini
|
|||
|
[db]
|
|||
|
myhost ansible_port=222 ansible_host=192.168.1.23
|
|||
|
```
|
|||
|
|
|||
|
Переменные можно указать для группы хостов
|
|||
|
```dosini
|
|||
|
[db]
|
|||
|
db1.com
|
|||
|
db2.com
|
|||
|
|
|||
|
[db:vars]
|
|||
|
env=production
|
|||
|
```
|
|||
|
|
|||
|
В inventory можно указать параметры подключения
|
|||
|
```
|
|||
|
ansible_connection
|
|||
|
ansible_host
|
|||
|
ansible_port
|
|||
|
ansible_user
|
|||
|
ansible_password
|
|||
|
```
|
|||
|
|
|||
|
Параметры подключения ssh/sftp/scp
|
|||
|
```
|
|||
|
ansible_ssh_private_key_file
|
|||
|
ansible_ssh_common_args
|
|||
|
ansible_ssh_extra_args
|
|||
|
ansible_ssh_pipelining
|
|||
|
ansible_ssh_executable
|
|||
|
|
|||
|
ansible_scp_extra_args
|
|||
|
ansible_sftp_extra_args
|
|||
|
```
|
|||
|
|
|||
|
Привилегии
|
|||
|
```
|
|||
|
ansible_become
|
|||
|
ansible_become_method
|
|||
|
ansible_become_user
|
|||
|
ansible_become_password
|
|||
|
ansible_become_exe
|
|||
|
ansible_become_flags
|
|||
|
```
|
|||
|
|
|||
|
Настройки shell
|
|||
|
```
|
|||
|
ansible_shell_type
|
|||
|
ansible_python_interpreter
|
|||
|
ansible_shell_executable
|
|||
|
```
|
|||
|
|
|||
|
Пример файла inventory
|
|||
|
```bash
|
|||
|
user@host$ cat hosts.ini
|
|||
|
```
|
|||
|
|
|||
|
```dosini
|
|||
|
[deploy]
|
|||
|
us1 ansible_host=192.168.10.151
|
|||
|
|
|||
|
[managers]
|
|||
|
us2 ansible_host=192.168.10.152
|
|||
|
us3 ansible_host=192.168.10.153
|
|||
|
|
|||
|
[workers]
|
|||
|
us154 ansible_host=192.168.10.154
|
|||
|
us155 ansible_host=192.168.10.155
|
|||
|
|
|||
|
[all:vars]
|
|||
|
ansible_user=da2001
|
|||
|
ansible_port=22
|
|||
|
ansible_ssh_private_key_file=~/.ssh/id_rsa.pub
|
|||
|
```
|
|||
|
|
|||
|
Пользовательский файл инвентаря
|
|||
|
*Файл инвентаря по-умолчанию обычно находится в /etc/ansible/hosts, но можно использовать опцию `-i` для указания пользовательских файлов при запуске команд и плейбуков Ansible. Это удобный способ настройки индивидуального инвентаря для каждого проекта, который можно включить в системы контроля версий, такие как Git:*
|
|||
|
```bash
|
|||
|
ansible all -m ping -i my_custom_inventory
|
|||
|
```
|
|||
|
Такая опция действительна и для ansible-playbook:
|
|||
|
```bash
|
|||
|
ansible-playbook myplaybook.yml -i my_custom_inventory
|
|||
|
```
|
|||
|
Динамический файл инвентаря
|
|||
|
*Ansible поддерживает сценарии инвентаризации для создания динамических файлов. Это полезно если инвентарь часто меняется, когда серверы создаются и уничтожаются.*
|
|||
|
|
|||
|
*Существуют готовые скрипты с открытым исходным кодом в официальном репозитории [Ansible GitHub](https://github.com/ansible/ansible). После загрузки требуемого сценария на Ansible control machine и настройки необходимых параметров (например, учетных данных API) можно запустить исполняемый файл в качестве пользовательского инвентаря с любой командой Ansible, которая поддерживает эту опцию.*
|
|||
|
|
|||
|
*Следующая команда использует скрипт инвентаря my_inventory.py с командой ping для проверки подключения ко всем текущим активным серверам:*
|
|||
|
```bash
|
|||
|
ansible all -m ping -i my_inventory.py
|
|||
|
```
|
|||
|
*Как использовать динамические файлы инвентаризации описано в [официальной документации Ansible](https://docs.ansible.com/ansible/latest/user_guide/intro_dynamic_inventory.html).*
|
|||
|
|
|||
|
Инвентарь можно описывать в отдельной папке и группировать хосты в отдельных файлах.
|
|||
|
*например, можно создать папку `hosts`, в ней папку `bd` и уже в этой папке создавать файлы с описанием хостов*
|
|||
|
Запуск в этом случае будет выглядеть так:
|
|||
|
```bash
|
|||
|
ansible -i hosts -m ping
|
|||
|
```
|
|||
|
или
|
|||
|
```bash
|
|||
|
ansible -i bd -m ping
|
|||
|
```
|
|||
|
|
|||
|
[вверх](#top)
|
|||
|
|
|||
|
***
|
|||
|
|
|||
|
###### Chapter2
|
|||
|
### Модули
|
|||
|
|
|||
|
https://docs.ansible.com/ansible/latest/user_guide/modules.html
|
|||
|
|
|||
|
Пример использования модулей
|
|||
|
```bash
|
|||
|
ansible webservers -m service -a "name=httpd state=started"
|
|||
|
```
|
|||
|
```bash
|
|||
|
ansible webservers -i /home/user/ansible/hosts.ini -m command -a "/sbin/reboot -t now"
|
|||
|
```
|
|||
|
|
|||
|
[Список доступных модулей на сайте Ansible](https://docs.ansible.com/ansible/2.8/modules/list_of_all_modules.html)
|
|||
|
*описание модулей можно получить в cli, для этого используется команда*
|
|||
|
```bash
|
|||
|
ansible-doc -l
|
|||
|
```
|
|||
|
*будет выведен список доступных модулей в less подобном отображении*
|
|||
|
|
|||
|
Документация по конкретному модулю `ansible-doc <название модуля>`
|
|||
|
```bash
|
|||
|
ansible-doc user
|
|||
|
```
|
|||
|
|
|||
|
[вверх](#top)
|
|||
|
|
|||
|
***
|
|||
|
|
|||
|
###### Chapter3
|
|||
|
### Ad-hoc команды
|
|||
|
|
|||
|
https://docs.ansible.com/ansible/latest/user_guide/intro_adhoc.html
|
|||
|
|
|||
|
Структура команды
|
|||
|
```bash
|
|||
|
ansible -i hosts -m user -a "name=student state=present" all
|
|||
|
^ ^ ^ ^
|
|||
|
| | | |
|
|||
|
инвентарь | аргументы используемые хосты
|
|||
|
модуль
|
|||
|
```
|
|||
|
|
|||
|
Создание пользователя на хостах
|
|||
|
*если пользователь существует, вернётся сообщение зеленого цвета*
|
|||
|
*если пользователь не существует, ansible попытается его создать. Если команда была запущена не от root, вернётся сообщение красного цвета типа __Pemission denied__*
|
|||
|
```bash
|
|||
|
ansible -i hosts.ini -m user -a "name=da2001 state=present" all
|
|||
|
```
|
|||
|
*создать нового пользователя с повышением привилегий - sudo*
|
|||
|
```bash
|
|||
|
ansible -i hosts.ini -m user -a "name=student state=present" -b -K all
|
|||
|
```
|
|||
|
`-b` - команда должна выполняться с привилегиями sudo
|
|||
|
`-K` - запрашивать пароль sudo перед выполнением команды
|
|||
|
|
|||
|
*удалить пользователя*
|
|||
|
```bash
|
|||
|
ansible -i hosts.ini -m user -a "name=student state=absent" -b -K all
|
|||
|
```
|
|||
|
|
|||
|
*передать sudo пароль в виде аргументов - extra args*
|
|||
|
```bash
|
|||
|
ansible -i hosts.ini -m user -a "name=student state=present" -e "ansible_become=true ansible_become_password=USER-PASS" all
|
|||
|
```
|
|||
|
`USER-PASS` - пароль пользователя для выполнения команды с привилегиями sudo
|
|||
|
|
|||
|
[вверх](#top)
|
|||
|
|
|||
|
***
|
|||
|
|
|||
|
###### part2
|
|||
|
## Ansible playbook
|
|||
|
[вверх](#top)
|
|||
|
|
|||
|
https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html
|
|||
|
|
|||
|
###### Chapter4
|
|||
|
### Простой playbook
|
|||
|
```bash
|
|||
|
cat user.yml
|
|||
|
```
|
|||
|
```bash
|
|||
|
---
|
|||
|
- name: user - имя playbook, произвольное
|
|||
|
hosts: deploy - группа хостов из файла inventory
|
|||
|
tasks: - задачи, выполняемые в этом плейбуке
|
|||
|
- name: Create user - имя задачи, произвольное
|
|||
|
user: - название модуля, который используется в этой задаче
|
|||
|
name: da2001 - аргументы модуля
|
|||
|
state: present - аргументы модуля
|
|||
|
become: true
|
|||
|
```
|
|||
|
|
|||
|
```bash
|
|||
|
ansible-playbook -i hosts.ini user.yml -K
|
|||
|
```
|
|||
|
|
|||
|
[вверх](#top)
|
|||
|
|
|||
|
***
|
|||
|
|
|||
|
###### Chapter5
|
|||
|
### Переменные
|
|||
|
|
|||
|
https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html
|
|||
|
|
|||
|
Переменные можно задавать в:
|
|||
|
- playbook
|
|||
|
- block
|
|||
|
- tasks
|
|||
|
- group_vars
|
|||
|
- host_vars
|
|||
|
- inventory
|
|||
|
- extra_vars
|
|||
|
- var_files
|
|||
|
|
|||
|
***переменная задаётся в фигурных скобках, обязательно в кавычках***
|
|||
|
```bash
|
|||
|
cat user.yml
|
|||
|
```
|
|||
|
```yaml
|
|||
|
---
|
|||
|
- name: user
|
|||
|
hosts: deploy
|
|||
|
tasks:
|
|||
|
- name: Create user
|
|||
|
vars:
|
|||
|
user: da2001
|
|||
|
user:
|
|||
|
name: "{{ user }}"
|
|||
|
state: present
|
|||
|
become: true
|
|||
|
```
|
|||
|
|
|||
|
Переменная может быть задана во внешнем файле
|
|||
|
```bash
|
|||
|
cat myvars.yml
|
|||
|
```
|
|||
|
```yaml
|
|||
|
user: da2001
|
|||
|
```
|
|||
|
*в плейбуке необходимо указать файл с переменными*
|
|||
|
```yaml
|
|||
|
---
|
|||
|
- name: user
|
|||
|
hosts: deploy
|
|||
|
vars_files:
|
|||
|
- ./myvars.yml
|
|||
|
tasks:
|
|||
|
- name: Create user
|
|||
|
user:
|
|||
|
name: "{{ user }}"
|
|||
|
state: present
|
|||
|
become: true
|
|||
|
```
|
|||
|
|
|||
|
Вместе с ansible устанавливается плагин, который позволяет считывать переменные из определённых файлов и папок без явного указания этих файлов и папок в плейбуке
|
|||
|
- `group_vars` - папка в которой нужно создать папку с названием группы, для которой будут задаваться переменные. Например, для группы хостов `deploy` необходимо создать такой путь/файл - `./group_vars/deploy/vars.yml`
|
|||
|
```bash
|
|||
|
cat ./group_vars/deploy/vars.yml
|
|||
|
```
|
|||
|
```yaml
|
|||
|
user: da2001
|
|||
|
```
|
|||
|
*в самом плейбуке нет необходимости где-то указывать ссылки на файл с переменными*
|
|||
|
```bash
|
|||
|
cat user.yml
|
|||
|
```
|
|||
|
```yaml
|
|||
|
---
|
|||
|
- name: user
|
|||
|
hosts: deploy
|
|||
|
tasks:
|
|||
|
- name: Create user
|
|||
|
user:
|
|||
|
name: "{{ user }}"
|
|||
|
state: present
|
|||
|
become: true
|
|||
|
```
|
|||
|
Если переменные могут использоваться во всех группах, можно создать папку `all` - `./group_vars/all/vars.yml`
|
|||
|
|
|||
|
- `host_vars` - папка, в которой создаётся файл с именем хоста - `./host_vars/us1.yml`. Если для хоста имя не задано - `./host_vars/192.168.10.151.yml`
|
|||
|
- создание переменных в файле инвентаря
|
|||
|
*для хоста us1 добавлена переменная `user`*
|
|||
|
```bash
|
|||
|
cat hosts.ini
|
|||
|
```
|
|||
|
```
|
|||
|
[deploy]
|
|||
|
us1 ansible_host=192.168.10.151 user=da2001
|
|||
|
|
|||
|
[managers]
|
|||
|
us2 ansible_host=192.168.10.152
|
|||
|
us3 ansible_host=192.168.10.153
|
|||
|
|
|||
|
[workers]
|
|||
|
us154 ansible_host=192.168.10.154
|
|||
|
us155 ansible_host=192.168.10.155
|
|||
|
|
|||
|
[all:vars]
|
|||
|
ansible_user=da2001
|
|||
|
ansible_port=22
|
|||
|
ansible_ssh_private_key_file=~/.ssh/id_rsa.pub
|
|||
|
```
|
|||
|
|
|||
|
- `--extra-vars` - передача переменных в команде запуска
|
|||
|
```bash
|
|||
|
ansible-playbook -i hosts.ini user.yml -K --extra-vars "user=da2001"
|
|||
|
```
|
|||
|
|
|||
|
- `vars-prompt` - ввод переменных в интерактивном режиме при выполнении playbook
|
|||
|
```bash
|
|||
|
cat user.yml
|
|||
|
```
|
|||
|
```yaml
|
|||
|
---
|
|||
|
- name: user
|
|||
|
hosts: deploy
|
|||
|
vars_prompt:
|
|||
|
- name: user
|
|||
|
prompt: "Введите имя пользователя"
|
|||
|
private: no
|
|||
|
tasks:
|
|||
|
- name: Create user
|
|||
|
user:
|
|||
|
name: "{{ user }}"
|
|||
|
state: present
|
|||
|
become: true
|
|||
|
```
|
|||
|
`private: no` - отображать ли вводимые символы
|
|||
|
|
|||
|
[вверх](#top)
|
|||
|
|
|||
|
***
|
|||
|
|
|||
|
###### Chapter6
|
|||
|
### Отладка
|
|||
|
|
|||
|
Очень полезно получать в консоль результат выполнения плейбука.
|
|||
|
1. Один из способов это создание в плейбуке поля `register` с какой-либо переменной для вывода. Далее этот вывод получаем в таске `debug`. Например:
|
|||
|
```yaml
|
|||
|
---
|
|||
|
- name: user
|
|||
|
hosts: deploy
|
|||
|
tasks:
|
|||
|
- name: Create user
|
|||
|
vars:
|
|||
|
user: da2001
|
|||
|
user:
|
|||
|
name: "{{ user }}"
|
|||
|
state: present
|
|||
|
become: true
|
|||
|
register: output
|
|||
|
- debug:
|
|||
|
var: output
|
|||
|
```
|
|||
|
После запуска плейбука
|
|||
|
```bash
|
|||
|
ansible-playbook -i hosts.ini user.yml -K
|
|||
|
```
|
|||
|
к выводу добавится значение таск `debug` с выводом значения созданной нами переменной `output`
|
|||
|
```json
|
|||
|
TASK [debug] ***********************************************************************************************************
|
|||
|
ok: [us1] => {
|
|||
|
"output": {
|
|||
|
"append": false,
|
|||
|
"changed": false,
|
|||
|
"comment": "da2001",
|
|||
|
"failed": false,
|
|||
|
"group": 1000,
|
|||
|
"home": "/home/da2001",
|
|||
|
"move_home": false,
|
|||
|
"name": "da2001",
|
|||
|
"shell": "/bin/bash",
|
|||
|
"state": "present",
|
|||
|
"uid": 1000
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
2. Debugger
|
|||
|
https://docs.ansible.com/ansible/latest/user_guide/playbooks_debugger.html#playbook-debugger
|
|||
|
|
|||
|
| Значение | Результат |
|
|||
|
|----------------|-----------|
|
|||
|
| always | всегда вызывать отладчик, независимо от результата |
|
|||
|
| never | никогда не запускать отладчик, независимо от результата |
|
|||
|
| on_failed | вызывать отладчик только в случае сбоя задачи |
|
|||
|
| on_unreachable | вызывать отладчик только в том случае, если хост недоступен |
|
|||
|
| on_skipped | вызывать отладчик только в том случае, если задача пропущена |
|
|||
|
|
|||
|
```yaml
|
|||
|
---
|
|||
|
- name: user
|
|||
|
hosts: deploy
|
|||
|
tasks:
|
|||
|
- name: Create user
|
|||
|
vars:
|
|||
|
user: da2001
|
|||
|
user:
|
|||
|
name: "{{ user }}"
|
|||
|
state: present
|
|||
|
become: true
|
|||
|
debugger: always
|
|||
|
```
|
|||
|
При наступлении условия, при котором вызывается отладчик, выполнение задачи приостанавливается и отладчик ожидает действий от пользователя
|
|||
|
```bash
|
|||
|
user@host:~$ ansible-playbook -i hosts.ini user.yml -K
|
|||
|
BECOME password:
|
|||
|
|
|||
|
PLAY [user] ************************************************************************************************************
|
|||
|
|
|||
|
TASK [Gathering Facts] *************************************************************************************************
|
|||
|
ok: [us1]
|
|||
|
|
|||
|
TASK [Create user] *****************************************************************************************************
|
|||
|
ok: [us1]
|
|||
|
[us1] TASK: Create user (debug)>
|
|||
|
```
|
|||
|
Отладчик принимает команды:
|
|||
|
|
|||
|
| Команда | Сокр. вызов | Действие |
|
|||
|
| -------------------------- | ----------- | ------------------------------------------------------------ |
|
|||
|
| print | p | напечатать информацию о задаче |
|
|||
|
| task.args[*key*] = *value* | no shortcut | изменить значение аргумента |
|
|||
|
| task_vars[*key*] = *value* | no shortcut | изменить значение переменной (далее необходимо выполнить `update_task`) |
|
|||
|
| update_task | u | повторно создать задачу с обновленными переменными |
|
|||
|
| redo | r | заново запустить задачу |
|
|||
|
| continue | c | продолжить выполнение, запуск следующей задачи |
|
|||
|
| quit | q | выход из отладчика |
|
|||
|
|
|||
|
*Примеры:*
|
|||
|
```
|
|||
|
[us1] TASK: Create user (debug)> p task
|
|||
|
TASK: Create user
|
|||
|
```
|
|||
|
```
|
|||
|
[us1] TASK: Create user (debug)> p task.args
|
|||
|
{'_ansible_check_mode': False,
|
|||
|
|
|||
|
...
|
|||
|
|
|||
|
'_ansible_version': '2.11.6',
|
|||
|
'name': 'da2001',
|
|||
|
'state': 'present'}
|
|||
|
```
|
|||
|
```
|
|||
|
[us1] TASK: Create user (debug)> p task.vars
|
|||
|
{'user': 'da2001'}
|
|||
|
```
|
|||
|
```
|
|||
|
[us1] TASK: Create user (debug)> p task_vars
|
|||
|
{'ansible_all_ipv4_addresses': ['192.168.10.151'],
|
|||
|
|
|||
|
...
|
|||
|
|
|||
|
'playbook_dir': '/home/da2001/ansible/udemy/ansible',
|
|||
|
'role_names': [],
|
|||
|
'user': 'da2001'}}
|
|||
|
```
|
|||
|
```
|
|||
|
[us1] TASK: Create user (debug)> p task_vars['user']
|
|||
|
'da2001'
|
|||
|
```
|
|||
|
```
|
|||
|
[us1] TASK: Create user (debug)> p host
|
|||
|
us1
|
|||
|
```
|
|||
|
```
|
|||
|
[us1] TASK: Create user (debug)> task_vars['user'] = 'user'
|
|||
|
[us1] TASK: Create user (debug)> p task_vars['user']
|
|||
|
'user'
|
|||
|
[us1] TASK: Create user (debug)> update_task
|
|||
|
[us1] TASK: Create user (debug)> redo
|
|||
|
```
|
|||
|
|
|||
|
[вверх](#top)
|
|||
|
|
|||
|
***
|
|||
|
|
|||
|
###### Chapter7
|
|||
|
### Блоки и обработка ошибок
|
|||
|
|
|||
|
Пример блока
|
|||
|
```yaml
|
|||
|
---
|
|||
|
- name: user
|
|||
|
hosts: deploy
|
|||
|
tasks:
|
|||
|
- name: Preconfig block
|
|||
|
block:
|
|||
|
- name: Create user
|
|||
|
vars:
|
|||
|
user: da2001
|
|||
|
user:
|
|||
|
name: "{{ user }}"
|
|||
|
state: present
|
|||
|
- name: Install curl
|
|||
|
apt:
|
|||
|
name: curl
|
|||
|
update-cashe: yes
|
|||
|
become: true
|
|||
|
```
|
|||
|
|
|||
|
Условие выполнения блока
|
|||
|
*в начале выполнения плейбука, ansible собирает факты о хостах, на основе полученных фактов можно описывать условия выполнения блоков.*
|
|||
|
Например: добавим условие, при котором блок будет выполняться только если в качестве хоста используется Ubuntu. Для этого в блок нужно добавить:
|
|||
|
```yaml
|
|||
|
when: ansible_facts['distribution' == 'Ubuntu']
|
|||
|
```
|
|||
|
|
|||
|
Обработка ошибок
|
|||
|
```yaml
|
|||
|
---
|
|||
|
- name: user
|
|||
|
hosts: deploy
|
|||
|
tasks:
|
|||
|
- name: Preconfig block
|
|||
|
block:
|
|||
|
- name: Create user
|
|||
|
vars:
|
|||
|
user: da2001
|
|||
|
user:
|
|||
|
name: "{{ user }}"
|
|||
|
state: present
|
|||
|
register: error
|
|||
|
- name: Install curl
|
|||
|
apt:
|
|||
|
name: curl
|
|||
|
update-cashe: yes
|
|||
|
register: error
|
|||
|
become: true
|
|||
|
rescue:
|
|||
|
- name: Some error print
|
|||
|
debug:
|
|||
|
var: error
|
|||
|
always:
|
|||
|
- name: Reboot
|
|||
|
debug:
|
|||
|
msg: "Rebooooooting"
|
|||
|
```
|
|||
|
Обработка ошибок происходит в блоке `rescue`. В каждом задании мы определили `register: error` - переменную, которая будет отображаться при возникновении ошибки. Т.к. в блоке `rescue` определена единственная переменная `var: error` - она будет выводиться при ошибке в любом задании. Для каждого задания можно определить свою переменную.
|
|||
|
|
|||
|
Блок `always` будет выполняться всегда, вне зависимости от того, были ошибки в заданиях или нет.
|
|||
|
|
|||
|
**Другие возможности управления ошибками**
|
|||
|
- `any_errors_fatal` - true/false. Если установлено значение `true` - появление любой ошибки будет приводить к остановке плейбука, `false` - имеет обратное значение, плейбук попытается продолжить своё выполнение при любых ошибках.
|
|||
|
- `ignore_errors` - true/false. В некоторых задачах можно установить параметр, чтобы игнорировать возникающие ошибки и перейти к выполнению следующей задачи.
|
|||
|
|
|||
|
- принудительный вызов ошибки. Можно создать отдельную задачу, в которой будет перехвачен вывод и будет сымитирована ошибка, которая приведёт к остановке выполнения плейбука. В нужное место плейбука добавить подобную задачу:
|
|||
|
```yaml
|
|||
|
- name: Fail on FAILED
|
|||
|
command: echo "FAILED"
|
|||
|
register: command_result
|
|||
|
failed_when: "'FAILED' in command_result.stdout"
|
|||
|
```
|
|||
|
*при выполнении этой задачи, команда echo выведет в консоль слово `FAILED`, следующей строкой происходит перехват вывода и проверяется на соответствие условию - `'FAILED' in command_result.stdout`, если условие выполняется, сформируется ошибка и дальнейшее выполнение будет остановлено.*
|
|||
|
|
|||
|
[вверх](#top)
|
|||
|
|
|||
|
***
|
|||
|
|
|||
|
###### Chapter8
|
|||
|
### Асинхронные задачи
|
|||
|
|
|||
|
Ansible выполняет задачи плейбука последовательно, иногда возникают ситуации, когда есть независимые друг от друга задачи, которые могут выполняться параллельно. Именно для этого используется асинхронный запуск длинных задач.
|
|||
|
Т.е. задача запускается и ansible отключается от неё, чтобы подождать выполнение или переключиться на другую задачу.
|
|||
|
*Пример - 1*
|
|||
|
`async: 1000` - максимальное время в секундах, в течение которого задача должна выполниться
|
|||
|
`poll: 5` - интервал в секундах, в течение которого ansible будет проверять состояние задачи
|
|||
|
|
|||
|
```bash
|
|||
|
cat async.yml
|
|||
|
```
|
|||
|
|
|||
|
```yaml
|
|||
|
---
|
|||
|
- name: user
|
|||
|
hosts: deploy
|
|||
|
tasks:
|
|||
|
- name: Preconfig block
|
|||
|
block:
|
|||
|
- name: Sleep
|
|||
|
command: sleep 15
|
|||
|
async: 1000
|
|||
|
poll: 5
|
|||
|
become: true
|
|||
|
```
|
|||
|
|
|||
|
```bash
|
|||
|
user@host:~$ ansible-playbook -i hosts.ini async.yml -K
|
|||
|
BECOME password:
|
|||
|
|
|||
|
PLAY [user] ************************************************************************************************************
|
|||
|
|
|||
|
TASK [Gathering Facts] *************************************************************************************************
|
|||
|
ok: [us1]
|
|||
|
|
|||
|
TASK [Sleep] ***********************************************************************************************************
|
|||
|
ASYNC POLL on us1: jid=290251027418.31066 started=1 finished=0
|
|||
|
ASYNC POLL on us1: jid=290251027418.31066 started=1 finished=0
|
|||
|
changed: [us1]
|
|||
|
|
|||
|
PLAY RECAP *************************************************************************************************************
|
|||
|
us1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
|||
|
|
|||
|
```
|
|||
|
`ASYNC POLL on us1: jid=290251027418.31066 started=1 finished=0` - каждые 5 секунд (значение poll) ansible подключается к задаче по id (`jid=290251027418.31066`) и проверяет её статус. При этом, переключение на следующую задачу не произойдёт до завершения текущей задачи.
|
|||
|
|
|||
|
*Пример - 2*
|
|||
|
*Задача 1 - спим 15 секунд, не дожидаясь окончания задачи переходим к следующей*
|
|||
|
*Задача 2 - выполняем команду echo*
|
|||
|
*Зачада 3 - проверяем статус выполнения первой задачи*
|
|||
|
*`jid: "{{ sleep.ansible_job_id }}"` - получаем статус задачи __(выполнение задачи и получение её статуса важно делать от одного и того же пользователя, иначе ansible не увидит задачу. Т.е. если основная задача выполняется от sudo (`become: true`), то и проверять статус также нужно от sudo)__.*
|
|||
|
*ждём выполнения задачи `until: job_result.finished`, при этом задаём необязательные параметры -*
|
|||
|
*`retries: 100` - проверяем выполнение отслеживаемой задачи 100 раз*
|
|||
|
*`delay: 1` - задержка между повторами - 1 секунда.*
|
|||
|
```bash
|
|||
|
cat async.yml
|
|||
|
```
|
|||
|
|
|||
|
```yaml
|
|||
|
---
|
|||
|
- name: user
|
|||
|
hosts: deploy
|
|||
|
tasks:
|
|||
|
- name: Preconfig block
|
|||
|
block:
|
|||
|
- name: Sleep
|
|||
|
command: sleep 10
|
|||
|
async: 1000
|
|||
|
poll: 0
|
|||
|
register: sleep
|
|||
|
- name: Echo
|
|||
|
command: echo "Задача выполнена"
|
|||
|
become: true
|
|||
|
- name: Check sleep status
|
|||
|
async_status:
|
|||
|
jid: "{{ sleep.ansible_job_id }}"
|
|||
|
register: job_result
|
|||
|
until: job_result.finished
|
|||
|
retries: 100
|
|||
|
delay: 1
|
|||
|
become: true
|
|||
|
```
|
|||
|
```bash
|
|||
|
user@host:~$ ansible-playbook -i hosts.ini async.yml -K
|
|||
|
BECOME password:
|
|||
|
|
|||
|
PLAY [user] ************************************************************************************************************
|
|||
|
|
|||
|
TASK [Gathering Facts] *************************************************************************************************
|
|||
|
ok: [us1]
|
|||
|
|
|||
|
TASK [Sleep] ***********************************************************************************************************
|
|||
|
changed: [us1]
|
|||
|
|
|||
|
TASK [Echo] ************************************************************************************************************
|
|||
|
changed: [us1]
|
|||
|
|
|||
|
TASK [Check sleep status] **********************************************************************************************
|
|||
|
FAILED - RETRYING: Check sleep status (100 retries left).
|
|||
|
FAILED - RETRYING: Check sleep status (99 retries left).
|
|||
|
FAILED - RETRYING: Check sleep status (98 retries left).
|
|||
|
FAILED - RETRYING: Check sleep status (97 retries left).
|
|||
|
FAILED - RETRYING: Check sleep status (96 retries left).
|
|||
|
FAILED - RETRYING: Check sleep status (95 retries left).
|
|||
|
changed: [us1]
|
|||
|
|
|||
|
PLAY RECAP *************************************************************************************************************
|
|||
|
us1 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
|||
|
```
|
|||
|
|
|||
|
[вверх](#top)
|
|||
|
|
|||
|
***
|
|||
|
|
|||
|
###### Chapter9
|
|||
|
### Пример playbook - установка Docker + Docker-compose
|
|||
|
```yaml
|
|||
|
---
|
|||
|
- name: Preconfig
|
|||
|
hosts: deploy
|
|||
|
tasks:
|
|||
|
- name: Установка Docker
|
|||
|
block:
|
|||
|
- name: Добавление репо Ububntu universe
|
|||
|
apt_repository:
|
|||
|
repo: "deb http://archive.ubuntu.com/ubuntu {{ ansible_distribution_release }} main universe restricted multiverse"
|
|||
|
state: present
|
|||
|
|
|||
|
- name: Установка дополнительных пакетов
|
|||
|
apt:
|
|||
|
name:
|
|||
|
- ca-certificates
|
|||
|
- curl
|
|||
|
- gnupg
|
|||
|
- lsb-release
|
|||
|
update_cache: true
|
|||
|
|
|||
|
- name: Добавление ключа Docker
|
|||
|
apt_key:
|
|||
|
url: https://download.docker.com/linux/ubuntu/gpg
|
|||
|
keyring: /usr/share/keyrings/docker-archive-keyring.gpg
|
|||
|
state: present
|
|||
|
|
|||
|
- name: Установка репозитория Docker
|
|||
|
apt_repository:
|
|||
|
repo: >
|
|||
|
deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg]
|
|||
|
https://download.docker.com/linux/ubuntu
|
|||
|
{{ ansible_distribution_release }} stable
|
|||
|
state: present
|
|||
|
update_cache: true
|
|||
|
filename: docker
|
|||
|
|
|||
|
- name: Установка Docker
|
|||
|
apt:
|
|||
|
name:
|
|||
|
- docker-ce
|
|||
|
- docker-ce-cli
|
|||
|
- containerd.io
|
|||
|
update_cache: true
|
|||
|
|
|||
|
- name: Проверка корректности установки Docker
|
|||
|
service:
|
|||
|
name: docker
|
|||
|
state: restarted
|
|||
|
enabled: true
|
|||
|
become: true
|
|||
|
|
|||
|
- name: Установка Docker-compose
|
|||
|
block:
|
|||
|
- name: Получение последней версии Docker-compose
|
|||
|
uri:
|
|||
|
url: "https://api.github.com/repos/docker/compose/releases/latest"
|
|||
|
body_format: json
|
|||
|
register: page
|
|||
|
|
|||
|
- name: Установка Docker-compose
|
|||
|
get_url:
|
|||
|
url: "https://github.com/docker/compose/releases/download/{{ page.json.tag_name }}/docker-compose-Linux-x86_64"
|
|||
|
dest: /usr/local/bin/docker-compose
|
|||
|
mode: 0755
|
|||
|
become: true
|
|||
|
|
|||
|
- name: Завершение установки
|
|||
|
block:
|
|||
|
- name: Добавление пользователя в группу Docker
|
|||
|
user:
|
|||
|
name: "{{ ansible_user }}"
|
|||
|
groups: docker
|
|||
|
append: true
|
|||
|
|
|||
|
- name: Перезагрузка
|
|||
|
reboot:
|
|||
|
become: true
|
|||
|
```
|
|||
|
*перечень необходимых пакетов, ссылки на репозитории и прочие данные, необходимые для установки взяты из официальной документации*
|
|||
|
*https://docs.docker.com/engine/install/ubuntu/*
|
|||
|
*https://docs.docker.com/compose/install/*
|
|||
|
|
|||
|
[вверх](#top)
|
|||
|
|
|||
|
***
|
|||
|
|
|||
|
```bash
|
|||
|
git add . && git commit -m 'mod ansible' && git push
|
|||
|
```
|