Ansible basics, tanpanya pedoman Anda adalah gumpalan pasta, bagian 3

Pada bagian ini, kita berhenti berbicara tentang yang sederhana dan menyenangkan dan mulai berbicara tentang yang sulit. Variabel dalam Ansible: scope, precedence, recursive interpolation. Bagi mereka yang membaca sampai akhir, sedikit bonus: tabel prioritas yang disederhanakan. Bagian sebelumnya: 1 , 2 .



Biasanya, cerita tentang variabel di Ansible dimulai dengan sesuatu yang sangat sederhana, yang memberikan ilusi kepada pembaca bahwa variabel di Ansible sama seperti bahasa pemrograman lainnya. Bisa berubah atau tidak, lokal dan global. Ini tidak benar.



Ini tidak benar.



Ansible memiliki model variabel unik (model memori?), Yang harus dipelajari dari awal. Dan kami akan mulai mempertimbangkannya dari tempat nilai digunakan (biasanya variabel yang memungkinkan dipertimbangkan dari tempat munculnya). Mengapa? Karena ketika memberi tahu arah ini, kita memiliki grafik berarah, yang jauh lebih mudah untuk dimasukkan ke dalam pikiran kita.



Catatan - Saya mengatakan "nilai" karena "variabel" hanyalah nama untuk nilai. Variabel memiliki dunia batin mereka sendiri, dan tentang itu di bagian kedua.



Sepanjang cerita ini, saya akan menggunakan istilah "muncul" dan / "digunakan". Muncul - Di sinilah nilai ditetapkan. Dan "hits" - ini adalah tempat di mana nilai mulai memengaruhi pekerjaan Ansible, lebih tepatnya, efek sampingnya - pada proses nyata menjalankan modul dalam sistem target. Sementara variabel dipindahkan dari satu tempat ke tempat lain di bagian tersebut vars, nilainya tidak "sampai" ke mana pun dan tidak memengaruhi dunia sekitarnya dengan cara apa pun.



Ini adalah pemikiran penting pertama yang perlu Anda ingat di kepala Anda: selama nilainya belum digunakan oleh sesuatu yang memengaruhi dunia di sekitarnya, ia dapat berisi kesalahan sintaks dan referensi ke variabel yang tidak ada, dll., Dan ini tidak akan membingungkan siapa pun. Mengapa begitu - baca terus.



Jadi di mana nilai-nilai itu digunakan?



  1. . - copy: src=foo.conf dest=/etc/foo.conf. foo.conf /etc/foo.conf — . . , , , . , jinja, / , (, , , , ).
  2. ( action plugin) 'template' lookup plugin' template. ( lookup plugin , , ).
  3. play. play ( play) play. , jinja2 gather_facts, play. — hosts, remote_user .
  4. , . , 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 }}'


. "" ( , ).



?



  1. ansible_host ( ) {{ hostvars[item].ansible_host }}. . yaml, .
  2. loop. {{ groups.all }}. — jinja. , . loop , , item " ".
  3. hello.txt touch. jinja, .
  4. 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 . :



  1. , inventory group_vars.
  2. play, play. ( , "play" — , ).
  3. task, .
  4. , . ( — ).


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



( ) 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 .





, , WTF'.



  • 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.




All Articles