I do a lot of reviews for someone else's code in Ansible and write a lot myself. In the course of analyzing the mistakes (both strangers and my own), as well as a number of interviews, I realized the main mistake that Ansible users make - they climb into the difficult without mastering the basic one.
To correct this universal injustice, I decided to write an introduction to Ansible for those who already know it. I warn you, this is not a retelling of mans, this is a longread with a lot of letters and no pictures.
The expected level of the reader - several thousand lines of yamla have already been written, something is already in production, but "somehow everything is crooked."
Names
The main mistake of the Ansible user is not to know what is called. If you don't know the names, you cannot understand what is written in the documentation. A living example: at an interview, a person who allegedly claimed that he wrote a lot in Ansible could not answer the question "what elements of a playbook consists of?". And when I suggested that "the answer was that the playbook consists of play", then the murderous comment "we do not use this" followed. People write in Ansible for money and do not use play. Actually use, but do not know what it is.
So let's start with a simple: whatβs called. Maybe you know this, or maybe not, because you didnβt pay attention when you read the documentation.
ansible-playbook executes the playbook. A playbook is a file with the yml / yaml extension, inside of which something like this:
---
- hosts: group1
roles:
- role1
- hosts: group2,group3
tasks:
- debug:
We already realized that this whole file is a playbook. We can show where roles are, where tasks are. But where is play? And how is play different from role or playbook?
The documentation has it all. And they miss it. Beginners - because there are too many and you can't remember everything at once. Experienced - because "trivial things". If you are experienced, re-read these pages at least once every half a year, and your code will become a better class.
So, remember: Playbook is a list of play and import_playbook
.
This is one play:
- hosts: group1
roles:
- role1
and this is also another play:
- hosts: group2,group3
tasks:
- debug:
What is play? Why is she?
Play β playbook, play play / , . delegate_to
, lookup-, network-cli- , jump- .. . , . , . , .
"-" "-" β play. . . play. , hosts , roles/tasks β .
, ? ?
, play, ", ". , , .
. monitoring, . monitoring ( . play). , , , . delegate? iptables. delegate? / , . delegate! , include_role
, include_role
delegate_to
. ...
β - monitoring, " " β : .
? , , "x" X Y "y", : play, Y y. - "x", . .
, . ! , DRY , .
. , ( , ) , . , - .
: β . , . β . play. , play?
, . Play (, ) , .
, , ( , ) . . play. , , , .
COBOL jinja. β , . "" β .
: , , control flow. delegate_to
. meta: end host/play
. ! , ? delegate_to
. . , , , . , :
play play .
play role. tasks vs role.
play:
- hosts: somegroup
pre_tasks:
- some_tasks1:
roles:
- role1
- role2
post_tasks:
- some_task2:
- some_task3:
, foo. foo: name=foobar state=present
. ? pre? post? role?
β¦ tasks?
β play. , play , "".
play: hosts, play pre_tasks, tasks, roles, post_tasks. play .
: pre_tasks
, roles
, tasks
, post_tasks
. tasks
roles
, best practices , tasks
, roles
. roles
, pre_tasks
/post_tasks
.
, : pre_tasks
, roles
, post_tasks
.
: foo
? ? ? , β pre post?
, , " ". . : play pre_tasks
post_tasks
( tasks, roles), - , post_tasks
pre_tasks
?
, , . ?
β¦ . : flush' . .. pre_tasks
, , notify. , notify . post_tasks
.
, post_tasks
pre_tasks
, , , handler'. , pre_tasks
-, post_tasks
- , pre_tasks
, "" .
, pre_tasks
post_tasks
? , , ( ) . post_tasks
( ).
Ansible , meta: flush_handlers
, flush_handlers, play? , meta: flush_handlers , when
block
.. , "" . β pre/roles/post β .
, , 'foo'. ? pre, post roles? , , foo. , foo pre, post β β .
" " , play β tasks, tasks. roles β ( task). , tasks roles .
, , .
( )
, . foo, bar baz. , ? : ? , ?β¦ ?
( ) β , β . ? , side causes, side effects, .
, . ? side effects β , β -. side causes? . " " β - . -, . play vars . play . (set_fact
/register
). " ". " " " ".
: ansible - -. β side effect . Rust, , β unsafe
. β . : " ", " , ". . .
: β .
? -, default values (/default/main.yaml
), - .
default values? , , role defaults β ( ). , - , β . ( β |d(your_default_here)
, β ).
? , . , (.. ), ( , - β include_vars
{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml
.). files/
, templates/
. , (library/
). , playbook' ( ), , , .
: , ( galaxy). .
, : ( ) .
: ? "" / , ( ). β . β , . , . "" ( ) , .
import_role , , , .
, , galaxy.yml, include_role
β , , .
: . β . ?
, :
- hosts: group1
tasks:
- foo:
notify: handler1
handlers:
- name: handler1
bar:
handler' rolename/handlers/main.yaml. Handler' play: pre/post_tasks handler' , handler' . , "-" handler' wtf, handler'. ( best practices β handler').
, () (/ when
), β (notify changed). ? , , , changed, handler. , handler changed ? , - changed , . , . , . , .
(, .., 'basic ansible' ). : , .service
-, daemon_reload
state=started
. , , . , . . restarted ( restarted, .. ), state=started, , .. .
handler' , . β skipped ok β . β task' , handler' changed, .. β . , . , , . β changed- .
. , notify , ? , , , .
β¦ handler' , . - ( ) . β .
, listen
, handler notify handler', handler import_tasks ( include_role c with_items), -, include_role .. β "").
WTF, , . delegate_to
notify, delegate_to
, .. , play. ( , , delegate_to
).
reusable roles. , , ansible-galaxy install
. . , : . include_vars
, 100500 corner case . , , , " ". β , ( 1).
if' ( β when
include_vars
), . , , , , . galaxy ( !) when
, "" . , galaxy β - . , β - , , - " galaxy". , , - when
'β¦ . 5 , - .
- group variables, host_group_vars plugin, hostvars. How to tie the Gordian knot from spaghetti. Scope and precedence variables, Ansible memory model. "So where is the username for the database stored?"
jinja: {{ jinja }}
- nosql notype nosense soft plasticine. It is everywhere, even where you don't expect it. A little pro!!unsafe
and yaml delicious.