Ansible 2.0 beta 2
О системе управления конфигурациями Ansible мы уже писали два года назад. Мы активно её используем в собственной практике и внимательно следим за всеми изменениями и обновлениями.
Конечно же, мы не могли оставить без внимания следующую новость: вышла в свет вторая бета-версия Ansible v2.0. Черновой вариант Ansible v2.0 был размещён на GitHub уже давно, а теперь наконец-то появился более или менее стабильный бета-релиз.
В этой статье мы расскажем о наиболее значимых нововведениях во второй версии.
Что нового
Никаких радикальных изменений во второй версии нет — об этом уже давно говорил один из разработчиков Ansible Джеймс Каммарата в докладе, прочитанном в этом году на конференции AnsibleFest в Нью-Йорке.
Появилось много новых модулей, а в некоторые из старых модулей были внесены изменения. Разработчики гарантируют стопроцентную совместимость со сценариями (Playbooks) для предыдущих версий.
Однако изменения затронули внутренние API, и тем, кто пользуется «самописными» плагинами, придётся эти плагины скорректировать. Разработчики уверяют (см. доклад по ссылке выше), что переход на новую версию должен произойти без особых проблем.
Подробный список всех изменений опубликован здесь.
Сообщения об ошибках
Система оповещения об ошибках в первой версии была довольно неудобной. Вот пример ошибки в имени модуля:
- hosts: all
gather_facts: no
tasks:
- debug: msg="hi"
- not_a_syntax_error_just_invalid_module: msg="error"
- debug: msg="bye"
При обнаружении этой ошибки первая версия выдавала весьма лаконичное сообщение:
ERROR: not_a_syntax_error_just_invalid_module is not a legal parameter in an Ansible
task or handler
Вторая же версия выдаёт гораздо более информативное сообщение и указывает место где была обнаружена ошибка:
ERROR! no action detected in task
The error appears to have been in '... .yml': line 5, column 44, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- debug: msg="hi"
- not_a_syntax_error_just_invalid_module: msg="error"
^ here
Это делает процесс работы с Ansible более удобным, а во многих случаях ещё и экономит время.
Блоки
Ещё одной интересной новацией являются блоки. Во многих языках программирования для обработки исключений используется конструкция try/except/finally. Похожая конструкция появилась и в Ansible:
- hosts: localhost
connection: local
gather_facts: no
tasks:
- block:
- command: /bin/false
- debug: msg="you shouldn't see me"
rescue:
- debug: msg="this is the rescue"
- command: /bin/false
- debug: msg="you shouldn't see this either"
always:
- debug: msg="this is the always block, it will always be seen"
Вывод при выполнении приведённого сценария будет выглядеть примерно так:
PLAY [<no name specified>] ******************************************************
TASK [command] ******************************************************************
fatal: [localhost]: FAILED! => ...
NO MORE HOSTS LEFT **************************************************************
CLEANUP TASK [debug msg=this is the rescue] *************************************
ok: [localhost] => {
"msg": "this is the rescue",
"changed": false
}
CLEANUP TASK [command] **********************************************************
fatal: [localhost]: FAILED! => ...
CLEANUP TASK [debug msg=this is the always block, it will always be seen] *******
ok: [localhost] => {
"msg": "this is the always block, it will always be seen",
"changed": false
}
Если при выполнении блока случится ошибка, то будут выполнены действия, указанные в секциях rescue и always. После этого выполнение сценария будет остановлено.
Стратегии
В новой версии Ansible можно выбирать, в какой последовательности будут выполняться содержащиеся в сценарии задания. Возможные варианты выполнения называются стратегиями (strategy). Существует два вида стратегий:
- линейная (linear)— работает так же, как и в предыдущей версии: выполнение нового задания начнётся после того, как текущее задание будет выполнено на всех хостах;
- произвольная (free) — на каждом хосте задание выполняется как можно быстрее и без учёта того, что происходит на других хостах.
Поясним сказанное конкретным примером и рассмотрим следующий фрагмент сценария:
- hosts: all
gather_facts: no
strategy: free
tasks:
- pause: seconds={{ 10 |random}}
- debug: msg="msg_1"
- pause: seconds={{ 10 |random}}
- debug: msg="msg_2"
- pause: seconds={{ 10 |random}}
- debug: msg="msg_3"
Если бы мы выбрали традиционную (линейную) стратегию, то при выполнении этого сценария увидели бы такой вывод (приводим в несколько сокращённом варианте):
TASK [debug msg=msg_1] **********************************************************
ok: [host3] => { "msg": "msg_1", "changed": false}
ok: [host4] => { "msg": "msg_1", "changed": false}
ok: [host2] => { "msg": "msg_1", "changed": false}
ok: [host1] => { "msg": "msg_1", "changed": false}
TASK [debug msg=msg_2] **********************************************************
ok: [host4] => {"msg": "msg_2", "changed": false}
ok: [host1] => {"msg": "msg_2", "changed": false}
ok: [host2] => {"msg": "msg_2", "changed": false}
ok: [host3] => {"msg": "msg_2", "changed": false}
TASK [debug msg=msg_3] **********************************************************
ok: [host1] => {"msg": "msg_3", "changed": false}
ok: [host2] => {"msg": "msg_3", "changed": false}
ok: [host3] => {"msg": "msg_3", "changed": false}
ok: [host4] => {"msg": "msg_3", "changed": false}
Задания выполняются в случайном порядке, но при этом выполнение заданий из группы msg_3 не будет начато до тех пор, пока не завершится выполнение заданий из группы msg_2.
Если же выбрана произвольная стратегия, вывод будет совсем другим:
PLAY [<no name specified>] ******************************************************
ok: [host3] => {"msg": "msg_1", "changed": false}
ok: [host4] => {"msg": "msg_1", "changed": false}
ok: [host2] => {"msg": "msg_1", "changed": false}
ok: [host4] => {"msg": "msg_2", "changed": false}
ok: [host2] => {"msg": "msg_2", "changed": false}
ok: [host4] => {"msg": "msg_3", "changed": false}
ok: [host1] => {"msg": "msg_1", "changed": false}
ok: [host2] => {"msg": "msg_3", "changed": false}
ok: [host3] => {"msg": "msg_2", "changed": false}
ok: [host3] => {"msg": "msg_3", "changed": false}
ok: [host1] => {"msg": "msg_2", "changed": false}
ok: [host1] => {"msg": "msg_3", "changed": false}
Как видим, все действия на хостах осуществляются в произвольном режиме. Благодаря этому нововведению многие сценарии будут выполняться гораздо быстрее.
В случае необходимости пользователь может определить и собственную стратегию — достаточно лишь написать соответствующий плагин. Правда, API для плагинов пока что работает нестабильно, да и документация оставляет желать лучшего.
Include + with
Очень часто новое — это хорошо забытое старое. В более ранних версиях Ansible уже были конструкции вида:
main.yml:
- hosts: localhost
connection: local
gather_facts: no
tasks:
- include: foo.yml some_var={{ item }}
with_items:
- a
- b
- c
foo.yml:
- debug: msg={{some_var}}
В версии 1.5 и всех последующих они уже были исключены. Во второй версии они вернулись.
Наследование блоков и ролей
Значения ‘become’ (пришло на замену ‘sudo’ c версии 1.9) и другие теперь могут быть присвоены блокам и ролям, и их будут наследовать все задания, включённые в эти блоки и роли:
- hosts: all
gather_facts: false
remote_user: testing
- roles: {role: foo , become_user: root}
tasks:
block:
- command: whoami
- command: do/something/privileged
- stat = path=/root/ .ssh/id_rsa
become_user: root
Как попробовать
Новая версия уже доступна для скачивания здесь. Кроме того, её можно собрать их исходного кода, размещённого на GitHub:
$ git clone https://github.com/ansible/ansible.git
$ cd ansible
$ git checkout v2.0.0-0.4.beta2
$ git submodule update --init
$ .hacking/env-setup
При желании можно собрать deb-пакет:
$ make deb
Или rpm-пакет:
$ make rpm
Заключение
Нововведения, появившиеся во второй версии, показывают, что в целом Ansible развивается в правильном направлении. Мы будем с интересом следить за его дальнейшим развитием.
А вы уже пробовали новую версию Ansible? Если пробовали, приглашаем поделиться впечатлениями в комментариях. Если мы забыли рассказать о каком-либо значимом нововведении — напишите нам, и мы обязательно добавим его в обзор. Также призываем сообщать обо всех замеченных ошибках разработчикам на Github, используя этот шаблон.
Читателей, не имеющих возможности оставлять комментарии здесь, приглашаем в наш блог.