
We
already wrote about Ansible configuration management system two years ago. We actively use it in our own practice and closely monitor all changes and updates.
Of course, we could not disregard the following news:
the second beta version of Ansible v2.0 was released . The draft Ansible v2.0 has been posted on GitHub for a long time, and now finally a more or less stable beta release has appeared.
')
In this article we will talk about the most significant innovations in the second version.
What's new
There are no radical changes in the second version - one of the Ansible developers, James Kammarata, spoke for a long time in a
report read this year at the AnsibleFest conference in New York.
Many new modules have appeared, and some of the old modules have been modified. The developers guarantee 100% compatibility with scripts (Playbooks) for previous versions.
However, the changes have affected the internal API, and those who use "samopisnymi" plugins will have to adjust these plugins. The developers assure (see the report on the link above) that the transition to the new version should occur without any problems.
A detailed list of all changes published
here .
Error messages
The error reporting system in the first version was rather inconvenient. Here is an example of an error in the module name:
- hosts: all gather_facts: no tasks: - debug: msg="hi" - not_a_syntax_error_just_invalid_module: msg="error" - debug: msg="bye"
When this error was detected, the first version gave a very concise message:
ERROR: not_a_syntax_error_just_invalid_module is not a legal parameter in an Ansible task or handler
The second version gives a much more informative message and indicates where the error was detected:
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
This makes the process of working with Ansible more convenient, and in many cases also saves time.
Blocks
Another interesting innovation is the blocks. In many programming languages, the try / except / finally construct is used to handle exceptions. A similar design appeared in 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"
The output when executing the above script will look something like this:
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 }
If an error occurs while executing the block, the actions specified in the rescue and always sections will be performed. After this, the script execution will be stopped.
Strategies
In the new version of Ansible, you can choose in which sequence the tasks contained in the script will be performed. Possible embodiments are called strategies. There are two types of strategies:
- linear (linear) - works in the same way as in the previous version: the execution of a new task will begin after the current task is performed on all hosts;
- arbitrary (free) - on each host the task is performed as quickly as possible and without taking into account what is happening on other hosts.
Let us explain what was said with a concrete example and consider the following fragment of the script:
- 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"
If we chose the traditional (linear) strategy, then in the execution of this scenario we would see the following conclusion (we give it in a somewhat abbreviated version):
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}
Tasks are executed in a random order, but the execution of tasks from the msg_3 group will not start until the tasks from the msg_2 group are completed.
If an arbitrary strategy is chosen, the output will be completely different:
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}
As you can see, all actions on the hosts are carried out in an arbitrary mode. Thanks to this innovation, many scenarios will be executed much faster.
If necessary, the user can define his own strategy - just write the appropriate plug-in. True, the API for plugins is still unstable, and the documentation leaves much to be desired.
Include + with
Very often the new is well forgotten old. In earlier versions of Ansible, there were already constructions of the form:
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}}
In version 1.5 and all subsequent ones they have already been excluded. In the second version, they returned.
Inheritance of blocks and roles
Values of 'become' (came to replace 'sudo' c version 1.9) and others can now be assigned to blocks and roles, and all tasks included in these blocks and roles will inherit them:
- 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
How to try
The new version is already available for download here. In addition, it can be assembled from source code hosted on 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
If you wish, you can build a deb-package:
$ make deb
Or rpm package:
$ make rpm
Conclusion
The innovations that appeared in the second version show that, in general, Ansible is developing in the right direction. We will follow its further development with interest.
Have you tried the new version of Ansible? If you tried, we invite you to share your impressions in the comments. If we forgot to tell about any significant innovation - write to us, and we will add it to the review. We also urge you to report any bugs to developers
on Github using
this template .
Readers who are not able to leave comments here are invited
to our blog .