Ansible #1

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