In diesem Teil hören wir auf, über das Einfache und Angenehme zu sprechen, und beginnen, über das Schwierige zu sprechen. Variablen in Ansible: Umfang, Priorität, rekursive Interpolation. Für diejenigen, die bis zum Ende lesen, ein kleiner Bonus: eine vereinfachte Prioritätstabelle zum Leben. Vorherige Teile: 1 , 2 .
Normalerweise beginnt eine Geschichte über Variablen in Ansible mit etwas sehr Einfachem, was dem Leser die Illusion gibt, dass Variablen in Ansible wie in jeder anderen Programmiersprache sind. Veränderlich oder nicht veränderlich, lokal und global. Es ist nicht so.
Es ist nicht so.
Ansible hat ein einzigartiges Variablenmodell (Speichermodell?), Das von Grund auf neu gelernt werden muss. Und wir werden es an der Stelle betrachten, an der die Werte verwendet werden (normalerweise werden Ansible-Variablen dort berücksichtigt, wo sie erscheinen). Warum? Denn wenn wir in diese Richtung erzählen, haben wir einen gerichteten Graphen, der viel einfacher in unsere Köpfe zu setzen ist.
Hinweis - Ich sagte "Werte", weil "Variablen" nur Namen zu Werten sind. Variablen haben ihre eigene tiefe innere Welt und darüber im zweiten Teil.
In dieser Geschichte werde ich die Begriffe "erscheint" und / "wird verwendet" verwenden. Erscheint - Hier wurde der Wert festgelegt. Und "Treffer" - hier beginnt der Wert die Arbeit von Ansible zu beeinflussen, genauer gesagt seine Nebenwirkungen - auf den tatsächlichen Prozess der Ausführung von Modulen im Zielsystem. Während die Variablen im Abschnitt von Ort zu Ort verschoben werden, vars
"gelangen" die Werte nirgendwo hin und wirken sich nicht auf die umgebende Welt aus.
Dies ist der erste wichtige Gedanke, an den Sie sich in Ihrem Kopf erinnern müssen: Solange der Wert nicht von etwas verwendet wurde, das die Welt um ihn herum beeinflusst, kann er Syntaxfehler und Verweise auf nicht vorhandene Variablen usw. enthalten, und dies wird niemanden verwirren. Warum so - lesen Sie weiter.
Wo werden die Werte verwendet?
- .
- copy: src=foo.conf dest=/etc/foo.conf
.foo.conf
/etc/foo.conf
— . . , , , . , jinja, / , (, , , , ). - ( action plugin) 'template' lookup plugin' template. ( lookup plugin , , ).
- play. play ( play) play. , jinja2
gather_facts
, play. —hosts
,remote_user
. - , . ,
ansible_host
,ansbile_user
,ansible_extra_ssh_args
,ansible_transport
.. .
, :
- name: Do not do this
file: path=hello.txt state=touch
loop: '{{ groups.all }}'
vars:
ansible_host: '{{ hostvars[item].ansible_host }}'
. "" ( , ).
?
-
ansible_host
( ){{ hostvars[item].ansible_host }}
. . yaml, . -
loop
.{{ groups.all }}
. — jinja. , . loop , , item " ". -
hello.txt
touch
. jinja, . -
file
ansible_host
ssh — . ,ansible_host
Jinja, . , (.. loop). , jinja item, (.. item - ). , . ? . , .
— . , , - . set_fact
, ( ), .
. , ( best practice) IP- :
allow_access: '{{ ansible_default_ipv4.address }}'
, setup ( gathering_facts), allow_access Jinja , — , .
Jinja
— Jinja ( ). , , (), ( ). : - . . - , . , . , ( , ..). , Jinja , .
:
- debug:
msg: '{{ message }}'
vars:
foo: 'foo'
foobar: '{{ foo + "bar" }}'
message: 'This is {{ foobar }}'
, 'msg' 'debug' ( , action plugin, ), {{ message }}
. ({{
}}
) message. This is {{foobar }}
. This is {{ foo + "bar" }}
. This is foobar
. , .. . msg debug.
, , , .
WTF, " ".
- hosts: localhost
tasks:
- debug: msg={{foo}}
vars:
foo: ''{{ foo + 1 }}'
vars:
foo: 1
play, "" foo . play, . debug? msg . , {{ foo + 1 }}
, {{ foo + 1 }} + 1
.. , .
:
- hosts: localhost
tasks:
- set_fact:
foo: '{{ foo + 1 }}'
- debug: msg={{foo}}
vars:
foo: 1
""? ? set_fact
- foo. foo, . , , foo ( 1) , foo . , .
, , . .
.
- hosts: localhost
vars:
foo: '{{ bar * 2 }}'
tasks:
- debug: var=foo
loop: [1,2,3]
vars:
bar: '{{ item + 10 }}'
vars play ( ). WTF , .
? 1, 2, 3. :
foo
'{{ bar * 2 }}'
bar
'{{ item + 10 }}'
. , vars ( play, ), ( ) , . . , "", - .
debug. foo {{ bar *2 }}
, {{ (item + 10) * 2 }}
. item ( loop') 22, 24, 26.
— , , , , .. scope/precedence ( ), , .
:
- hosts: localhost
vars:
foo: '{{ bar }}'
tasks:
- debug: var=foo
vars:
bar: 'one value'
- debug: var=foo
vars:
bar: 'another value'
. , , bar . Mystery solved.
Jinja
, (, jinja) . jinja. {{ }}
, {% if True %} "" {%endif %}
. . yaml .
- foo_module:
username: <
{% for user in myusers %}
{% if user.lower() in good and user.upper() in other %}
{{ user }}
{% endif %}
{% endfor %}
'content' file
. :
- name: Configure sfcapd systemd service
become: true
copy:
content: |
[Unit]
Description=sflow capture service
[Service]
Type=simple
ExecStart=/usr/bin/sfcapd sfcapd -w -T{{ sflow_extensions }} -p {{ sflow_port }} -B {{ sflow_buffer_size }} -l {{ sflow_data_path }} -b {{ sflow_host }}
Restart=always
[Install]
WantedBy=multi-user.target
dest: /etc/systemd/system/sfcapd.service
notify:
- restart sfcapd
? 100500 . , . template
, copy
content
. , .
. .
- (, prometheus Go), . yaml- .
Ansible : safe unsafe. safe- — , . unsafe .
:
- debug:
msg: !unsafe'{{ inventory_hostname }}'
" ", {{ inventory_hostname }}
.
, .
— , ? , , : . , , ( ).
, , -, PHP .
.
---
- hosts: localhost
gather_facts: false
tasks:
- name: Case1
debug: var=item
loop: '{{ [1,2,3,4] }}'
- name: Case2
debug: var=item
loop: '{{ foo + bar }}'
- name: Case3
debug: var=item
loop: ' {{ [9,10] }}'
vars:
foo: '[5,6'
bar: '7,8]'
Case1 Jinja . , jinja2 , . , yaml'.
Case2 ( — , ) — , , - , . PHP.
Case3 — , .
Case2 Case3 — , . , , . ( ) json. , ( json').
Ansible:
- name: Case6, space at the end
debug: var=item
loop: '{{ [15, 16] }} '
- name: Case7, space at the start
debug: var=item
loop: ' {{ [15, 16] }}'
Case6 , loop ( ), Case7 , . ? . .
… . , , WTF' .
: , . 5 , , . ", ". , - — .
, : yaml, .
Scope ""
. -"", scope . :
- , inventory group_vars.
- play, play. ( , "play" — , ).
- task, .
- , . ( — ).
include_role
, include_role ( ), — include_role. , include .
Scope — scope scope:
---
- hosts: localhost
gather_facts: false
vars:
foo: 2
tasks:
- name: Case1
debug: var=foo
vars:
foo: 1
- name: Case2
debug: var=foo
play, foo=1, scope , foo scope play, foo 2. ( precedence ). "" "", ( ). "" — include_vars
, set_fact
, register
..
Variable precedence
. include_role
-"". , - scope, , . variable precedence ( — , ).
: , . , , http_port: 8088
, , http_port: 80
. -e
.. , , group_vars/
.
, , foo
inventory.yaml # [all:vars] foo=inventory
group_vars/all.yaml # foo: g_v_a
playbook.yaml
playbook.yaml
- debug: var=foo
?
… , variable precedence , , group_vars .
host_group_vars
( ) host_group_vars. , group vars host vars. , . group_vars/all.yaml , . playbook, playbook.
, , group_vars . , variable precedence (playbook), group_vars .
. group_vars , . , . , , , .. .
group_vars/other, group_vars/all, host_vars .. , .
, , — .
. precedence WTF, : ( ), hostvars .
- role/defaults — . , . pre/post tasks.
- group_vars/all — all
- group_vars/other_groups
- host_vars
- gather_facts: true (host_facts)
- play
- block
- task
- set_fact/register.
set_fact
, (.. play). - -e .
, ( ). "". .
: group_vars/all
group_vars/other_group.yaml
.
,
, . include' (, , ), , import include', add_host
, .. set_fact . , . jinja, . group_host_vars () play. , , .
Keep it clean, keep it simple.