Ansible — ПО для управления инфраструктурой и развертывания приложений, отличающееся простотой и не требующее установки агентов.
Ansible состоит из:
- Control node — хост с установленным Ansible (с него осуществляется управление)
- Managed node — хосты, которыми мы управляем
Установка:
pip3 install ansible
Если появилась ошибка
pip3: command not found
Выполним
sudo yum install python3-pip
После установки проверим
[sysadmin@almalinux ~]$ ansible --version
ansible [core 2.15.8]
Далее выполним
ansible -m ping localhost
Эта команда позволяет проверить связь между управляющим хостом ansible и целевым узлом. В случае успешного выполнения модуль ping вернет pong
[sysadmin@almalinux ~]$ ansible -m ping localhost
[WARNING]: No inventory was parsed, only implicit localhost is available
localhost | SUCCESS => {
"changed": false,
"ping": "pong"
}
Ansible playbook — это набор инструкций, написанных на языке YAML, которые описывают, что именно и на каких хостах должно быть выполнено, например установка пакетов, создание файлов и директорий, запуск служб и т.д.
Play нужны для перечисления тех действий, которые мы хотим воспроизвести на хосте или группе хостов. Он может состоять из:
name — имя самого play
hosts — список хостов
pre_tasks — это tasks выполняемые первыми, перед roles и tasks (pre_tasks являются необязательными)
tasks — то что нужно выполнить на хостах (если есть roles, то лучше не указывать)
post_tasks — выполняются после tasks и roles (также являются необязательными)
roles — роли, которые запускаются на хостах (если есть tasks, лучше не указывать)
handlers — обработчики событий, запускаются в случае обращения к ним task или role
tags — группируют roles, tasks
Пример простейшего playbook:
nano hello_world.yml
Скопируем туда следующее:
---
- name: Приветствие
hosts: localhost
gather_facts: False
tasks:
- name: Вывод сообщения
debug:
msg: "Привет, мир!"
Внимательно следите за синтаксисом и отступами
Запустим playbook
ansible-playbook hello_world.yml
[sysadmin@almalinux ~]$ ansible-playbook hello_world.yml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Приветствие] ***********************************************************************************************************************************************************************************************
TASK [Вывод сообщения] *******************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "Привет, мир!"
}
PLAY RECAP *******************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
В данном playbook:
- “name: Приветствие” задает имя для всего playbook.
- “hosts: localhost” указывает, что playbook будет запущен на локальной машине.
- “gather_facts: False” отключает сбор информации об узле перед выполнением задач. Это обычно делается для ускорения выполнения playbook, когда эта информация не нужна.
- В секции tasks: описывается одна задача, которая использует модуль debug для вывода сообщения «Привет, мир!» в консоль.
Inventory — файл со списком хостов, на которых Ansible выполняет playbook. Самый простой состоит из одного файла, в котором перечисляются хосты и группы. По умолчанию находится в /etc/ansible/hosts, но с помощью опции -i его можно указать явно.
Inventory может быть представлен в INI или YAML форматах. Предпочтительнее использовать вариант на YAML.
Рассмотрим простой Inventory файл:
dev:
hosts:
alma:
ansible_host: localhost
ansible_connection: local
localhost:
ansible_connection: local
rocky:
ansible_host: 192.168.6.235
ansible_connection: ssh
test:
hosts:
rhel:
ansible_host: 192.168.6.234
ansible_connection: ssh
Небольшой лайфхак. Чтобы лучше понять структуру своего Inventory есть команда
[sysadmin@almalinux ansible]$ ansible-inventory -i inventory/hosts.yml --graph
@all:
|--@ungrouped:
|--@dev:
| |--alma
| |--localhost
| |--rocky
|--@test:
| |--rhel
Для того, чтобы определить с какими параметрами для каждого из хостов будет запускаться ansible запустите:
[sysadmin@almalinux ansible]$ ansible-inventory -i inventory/hosts.yml --list
{
"_meta": {
"hostvars": {
"alma": {
"ansible_connection": "local",
"ansible_host": "localhost"
},
"localhost": {
"ansible_connection": "local"
},
"rhel": {
"ansible_connection": "ssh",
"ansible_host": "192.168.6.234"
},
"rocky": {
"ansible_connection": "ssh",
"ansible_host": "192.168.6.235"
}
}
},
"all": {
"children": [
"ungrouped",
"dev",
"test"
]
},
"dev": {
"hosts": [
"alma",
"localhost",
"rocky"
]
},
"test": {
"hosts": [
"rhel"
]
}
}
Если необходимо получить информацию по одному хосту
[sysadmin@almalinux ansible]$ ansible-inventory -i inventory/hosts.yml --host rocky
{
"ansible_connection": "ssh",
"ansible_host": "192.168.6.235"
}
Поднимем 2 дополнительные виртуальные машины (если происходит ошибка при подключении, возможно на хосте с ansible вам нужно сгенерировать ключи и скопировать их на удаленные машины) и выполним следующий playbook
---
- name: Подключение к серверам
hosts: all
gather_facts: False
tasks:
- name: Выполнить команду на удаленном сервере
ansible.builtin.command:
cmd: echo "Hello, world!"
[sysadmin@almalinux ansible]$ ansible-playbook -i inventory/hosts.yml hello.yml
PLAY [Подключение к серверам] ************************************************************************************************************************************************************************************
TASK [Выполнить команду на удаленном сервере] ********************************************************************************************************************************************************************
changed: [localhost]
changed: [alma]
changed: [rocky]
changed: [rhel]
PLAY RECAP *******************************************************************************************************************************************************************************************************
alma : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
rhel : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
rocky : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Ansible Vault позволяет шифровать переменные используя AES256. Это может быть полезно, когда мы хотим скрыть например пароли от общего использования.
В директории group_vars/dev/ у нас есть файл custom.yml
---
custom_var: password
Для того чтобы зашифровать данный файл введем
ansible-vault encrypt group_vars/dev/custom.yml
Ansible попросит ввести пароль от хранилища
[sysadmin@almalinux ansible]$ ansible-vault encrypt group_vars/dev/custom.yml
New Vault password:
Confirm New Vault password:
Encryption successful
Если вы попробуете прочитать данные файл, то увидите, что он зашифрован
[sysadmin@almalinux ansible]$ cat group_vars/dev/custom.yml
$ANSIBLE_VAULT;1.1;AES256
35386264653362353061373061393663366462333439663163333239653838356336313238386434
Для того чтобы применить его при запуске необходимо ввести
ansible-playbook -i inventory/hosts.yml hello.yml --ask-vault-pass
Ansible запросит пароль и без дешифровки файла применит его (в нашем случае файл использован просто для примера)
Для того, чтобы расшифровать файл
ansible-vault decrypt group_vars/dev/custom.yml
Вводим пароль, проверяем и видим что файл зашифрован
Если нужно поработать с файлом без дешифровки
Для просмотра прямо в консоли:
[sysadmin@almalinux ansible]$ ansible-vault view group_vars/dev/custom.yml
Vault password:
---
custom_var: password
Для редактирования
[sysadmin@almalinux ansible]$ ansible-vault edit group_vars/dev/custom.yml
Vault password:
Откроется vi (в статье посвященной текстовым редакторам я упомянул о том, почему важно знать хотя бы его основы) и вы сможете изменить файл.
Для проверки можно расшифровать и проверить сохраненные изменения
Можно шифровать отдельные значения
ansible-vault encrypt_string
Вводим пароль
Далее указываем значение, какое нужно зашифровать, например введем
Strong_Password
Далее нажимаем два раза Ctrl + D
В ответ получаем
Encryption successful
!vault |
$ANSIBLE_VAULT;1.1;AES256
39613265363064653132663563633362303966633362616233623861643931303830356537663530
6639326565393639326661616566323563343532613465340a646562316266303066626638643434
63613537613863616265623239356531313835613865386333643764633034353738376634346537
3663343762396339640a366565636233616437636662366466663266383463333938633336363939
3366
Копируем со значения !vault и до конца и вставляет в custom.yml вместо слова password.
Получится вот так
[sysadmin@almalinux ansible]$ cat group_vars/dev/custom.yml
---
custom_var: !vault |
$ANSIBLE_VAULT;1.1;AES256
39613265363064653132663563633362303966633362616233623861643931303830356537663530
6639326565393639326661616566323563343532613465340a646562316266303066626638643434
63613537613863616265623239356531313835613865386333643764633034353738376634346537
3663343762396339640a366565636233616437636662366466663266383463333938633336363939
3366
Для запуска
ansible-playbook -i inventory/hosts.yml hello.yml --ask-vault-pass
Файл остается зашифрованным, playbook запускается (наше значение в данном случае просто для примера)
Photo by Kevin Horvat on Unsplash