Ansible playbook

Для того чтобы что-то настроить или установить на клиентском хосте нужно выполнить Ansible playbook. Ansible playbook - файл, в котором описываются задачи (tasks или roles), которые и должны выполняться на клиентском хосте.

Ansible playbook создаётся и редактируется с использованием синтаксиса YAML. Обязательное требование соблюдений отступов.

Ansible playbook

YAML

YAML (Ain’t Markup Language) — это язык для хранения информации в формате понятном человеку. Его название расшифровывается как, «Не язык разметки». Язык похож на XML и JSON, чаще всего используется как файл конфига для ПО и контейнеризации.

Модули Ansible

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

Пример использования модуля shell (выполнить bash команду):

- name: Run shell
  shell: useradd demo

Inventory

Файл инвентаризации, в котором записаны все ваши клиентские хосты, на которых вы собираетесь выполнять содержимое Ansible playbook. Желательно файл с хостами помещать в отдельную директорию inventory.

Хосты также можно разбивать по группам, как основным, так и вложенным.

Ansible inventory

Пример синтаксиса:

#группа хостов web
web:
  hosts:
	#dns именна хостов
    myweb1.aaa.lan:
    myweb2.aaa.lan:
    #ip хоста
    192.168.0.1:``

Также можно задать конкретные переменные для определённых хостов или группы, например, если нужно переписать глобальные переменные.

web:
  hosts:
    myweb1.aaa.lan:
	  ntp_source:
		- 192.168.0.1
		- 192.168.1.1

Также существует второй вариант синтаксиса файла инвентаризации INI. Но мне по душе первый YAML и в дальнейшем я буду использовать именно этот вариант.

[web]
myweb1.aaa.lan
myweb2.aaa.lan

[web:vars]
ansible_user=admin

Роли (Roles)

Роль - файл с задачами (tasks), который используется в основном Ansible playbook. В одном Ansible playbook можно использовать множественное количество ролей. Рекомендуется разбивать задачи по ролям, нежели писать все задачи (tasks) в один файл Ansible playbook.

Роли помещаются в директорию roles, далее идёт папка с наименованием роли, вложенная папка tasks и уже в этой папке файл main.yml.

Например, если вы решили создать роль delete то путь к файлу роли будет выглядеть так: roles/delete/tasks/main.yml.

Отмена операций

Если в какой-то момент выполнения вашего большого Ansible playbook вы получили ошибку, то выполненные команды откатываться не будут. Ansible не предоставляет возможности откатить все изменения назад.

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

Например, если у вас есть задача создания файла Ansible сделает следующее:

  1. Проверит есть ли такой файл, с нужными настройками
  2. Если его нет, то создаст, а если есть, то просто пропустит задачу

Пример

Для примера возьмём сервер mylab-vm-2.dc2.my.local и создадим на нём пустой файл /tmp/my.txt.

  1. На хосте с установленным ansible создаём директорию. Такой хост часто называют Control Machine.
    mkdir play1
    cd paly1
    
  2. Создаём основной файл Ansible playbook, содержимое которого будет выполнено на конечном хосте mylab-vm-2.dc2.my.local. Для создания файла будет использоваться модуль file.
    vim play1.yml
    
    #тут указываем на каких хостах выполнять задачи
    - hosts: all
      tasks:
    
     - name: Create file
       file:
         path: /tmp/my.txt
         owner: admin
         group: admin
         mode: '0644'
         state: touch
    
     #тут мы вызываем роль, которая удалит файл
     - include_role:
         name: delete        
    
  3. Для демонстрации работы ролей создадим роль с названием delete, которая удалит созданный файл.
    mkdir -p roles/delete/tasks
    vim roles/delete/tasks/main.yml
    
    - name: Delete file
      file:
      path: /tmp/my.txt
      state: absent
    
  4. Создаём файл с описанием хоста mylab-vm-2.dc2.my.local
    mkdir inventory
    vim inventory/static.yml
    
    all:
      hosts:
    mylab-vm-2.dc1.my.local:
    
  5. Для того чтобы Ansible хост мог подключаться к цели нужно добавить fingerprint.
    ssh mylab-vm-2.dc1.my.local
    yes
    CTRL+C
    
  6. Далее можно проверить что наш конечный хост доступен запуская ansible ping. Где -u указывает пользователя на стороне конечного хоста и --ask-pass выдаст запрос на пароль от этого пользователя.
    ansible all -m ping -i inventory/static.yml --ask-pass -u admin
    

    Должны получить ответ вида:

    mylab-vm-2.dc2.my.local | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
    }
    
  7. И собственно запускаем самый главный Ansible playbook - play1.yml.
    ansible-playbook -i inventory/static.yml play1.yml --ask-pass -u admin
    

    Должны получить ответ вида:

PLAY [all] *************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************
ok: [mylab-vm-2.dc2.my.local]

TASK [Create file] *****************************************************************************************************
changed: [mylab-vm-2.dc2.my.local]

TASK [include_role : delete] *******************************************************************************************

TASK [delete : Delete file] ********************************************************************************************
changed: [mylab-vm-2.dc2.my.local]

PLAY RECAP *************************************************************************************************************
mylab-vm-2.dc2.my.local    : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Что произошло

Ansible

  1. Мы добавили fingerprint для хоста mylab-vm-2.dc2.my.local
  2. Мы проверили что хост mylab-vm-2.dc2.my.local доступен, и мы можем к нему подключиться по ssh, при этом конкретно задали логин и пароль для подключения.
  3. Мы выполнили на конечном хосте команды, которые прописывали в Ansible playbook. Т.е ansible хост подключился к конечному хосту по ssh под пользователем admin и выполним команды на этом хосте.

Структура файлов

#основная папка
play1 
#файл с хостами, на который выполняются задачи (tasks)
├──inventory/static.yml
#роль, которая удаляет файл
├──roles/delete/tasks/main.yml
#Ansible playbook - основной файл 
├──play1.yml

Видео