Ansible: Tentukan secara variabel variabel dalam file vars jika kondisi tertentu terpenuhi

19

Bergantung pada nilai (Benar / Salah) dari variabel yang didefinisikan ke dalam group_vars saya mencoba mendefinisikan beberapa variabel dalam file vars. Nilai mereka tergantung pada nilai var grup.

File var saya saat ini terlihat seperti ini:

{% if my_group_var %}
test:
   var1: value
   var2: value
   ...
   varn: value
{% else %}
test:
   var1: other_value
   var2: other_value
   ...
   varn: other_value
{% endif %}

Untuk setiap peran saya, saya menggunakan variabel yang didefinisikan dalam file ini.

Playbook tes saya terlihat seperti di bawah ini:

- name: blabla
  hosts: blabla
  vars_files:
     - <path>/test_vars.yml
  roles: blabla 

Kesalahan yang saya terima setelah menjalankan playbook adalah:

{% if my_group_var %}
 ^ here

exception type: <class 'yaml.scanner.ScannerError'>
exception: while scanning for the next token
found character that cannot start any token
  in "<unicode string>"

Apakah saya melakukan sesuatu yang bodoh di sini atau ini bahkan tidak didukung? Saya sudah mencoba mencari cara lain untuk mendefinisikan vars ini (saya punya banyak dari mereka) tetapi saya tidak berhasil mendapatkan sesuatu yang fungsional di sini. Ada saran?

pandoJohn
sumber
Di mana vars ini akhirnya digunakan? Ini mungkin tidak perlu jika Anda hanya menggunakannya sebagai bagian dari templatepanggilan modul.
84104
Jika testtergantung grup, itu harus ditempatkan ke dalam group_vars.
Konstantin Suvorov
Sayangnya, tes tidak tergantung pada kelompok. Seperti yang disebutkan dalam deskripsi, tes tergantung pada nilai variabel group_var.
pandoJohn

Jawaban:

11

Saya rasa Anda tidak bisa, saya biasanya membuat file terpisah untuk menyimpan koleksi variabel kondisional dan menggunakan whenklausa untuk memasukkannya pada kondisi tertentu:

- include_vars: test_environment_vars.yml
  when: global_platform == "test"

- include_vars: staging_environment_vars.yml
  when: global_platform == "staging"

- include_vars: prod_environment_vars.yml
  when: 
    - global_platform != "test" 
    - global_platform != "staging" 
HBruijn
sumber
2
Ini adalah sesuatu yang saya coba hindari. Saya tidak ingin menggunakan include vars atau untuk mendefinisikan 2 file var tambahan untuk tugas saya.
pandoJohn
Saya tidak mengerti .. ketika mungkin menggunakan include_vars dengan kondisi, mengapa tidak variabel dapat didefinisikan dengan kondisi?
GP92
10

Ansible memungkinkan salah satu dari formulir berikut untuk mendefinisikan variabel secara kondisional:

    test:
      var1: "{% if my_group_var %}value{% else %}other_value{% endif %}"
      var2: "{{'value' if (my_group_var) else 'other_value'}}"

Menggabungkan sintaks di atas dengan lookup vars kita dapat memuat vars kompleks (daftar dalam kasus ini):

test_value_when_my_group_var_is_true:
   var1: value
   var2: value

test_value_when_my_group_var_is_false:
   var1: other_value
   var2: other_value

test: "{{ lookup('vars','test_value_when_my_group_var_is_true') if (my_group_var) else lookup('vars','test_value_when_my_group_var_is_false')}}"

Ada cara lain untuk melakukan pemuatan pohon bersyarat dengan pencarian vars. Cara ini berguna ketika Anda perlu menerapkan logika kasus (yaitu variabel kondisi memiliki lebih dari dua nilai yang mungkin):

test_value_when_my_group_var_is_foo:
   var1: value
   var2: value

test_value_when_my_group_var_is_bar:
   var1: other_value
   var2: other_value

test_value_when_my_group_var_is_baz:
   var1: yet_another_value
   var2: yet_another_value

test: "{{ lookup('vars','test_value_when_my_group_var_is_' + my_group_var) }}"
Vladimir
sumber
2

Meskipun itu akan menyenangkan, saya khawatir jalan Anda tidak mungkin (atau saya tidak sadar cara yang benar).

Saya sarankan untuk terlebih dahulu menyiapkan file vars dari template jinja dan kemudian memasukkannya dengan include_vars. Lihat buku pedoman contoh:

---
- name: -Test-
  hosts: local
  vars:
    my_group_var: False
#    my_group_var: True

  tasks:

  - name: Prepare vars file from template.
    template: src=/tmp/vars.yaml.j2
              dest=/tmp/vars.yaml

  - name: Include vars
    include_vars: "/tmp/vars.yaml"

Isi contoh template jinja /tmp/vars.yaml.j2 adalah:

{% if my_group_var %}                                                                                                                                                                                             
test:                                                                                                                                                                                                             
   var1: value                                                                                                                                                                                                    
   var2: value                                                                                                                                                                                                    
{% else %}                                                                                                                                                                                                        
test:                                                                                                                                                                                                             
   var1: other_value                                                                                                                                                                                              
   var2: other_value                                                                                                                                                                                              
{% endif %}
Jaroslav Kucera
sumber
Saya suka ini tetapi masalahnya adalah setelah membuat file .yml dari template jinja ini tidak tersedia untuk tugas-tugas berikutnya dari buku pedoman saya.
pandoJohn
Mengapa? Ketika saya mencoba untuk memperluas buku pedoman uji dengan tugas debug - debug: var=testsaya bisa melihat, bahwa ada yang didefinisikan baik test.var1dan test.var2dengan nilai yang diharapkan. Jadi, Anda harus dapat menggunakan variabel-variabel ini dalam tugas-tugas lain dari buku pedoman.
Jaroslav Kucera
0

AFAIK, {} hal yang Anda coba ini adalah untuk template Jinja2 dan bukan untuk file yml. Dari dokumentasi :

ansible memungkinkan loop dan kondisi Jinja2 di templat, tetapi di playbook, kami tidak menggunakannya.

Anda dapat menyiapkan file .yml terpisah dengan permainan yang mengatur variabel yang perlu Anda gunakan saat klausa, dan kemudian mengimpor (atau termasuk) mereka di buku pedoman utama Anda. Dengan begitu Anda dapat membuat semua vars ditentukan secara kondisional dalam satu file.

ATAU: Gunakan peran. Saya pikir peran adalah pendekatan yang paling memadai untuk menyelesaikan masalah Anda.

niglesias
sumber
0

Apa yang saya lakukan pada akhirnya adalah membuat 2 file var terpisah - sebut saja type_a.ymldan type_b.yml- dan saya mendefinisikan variabel grup yang menunjukkan file apa yang digunakan - sesuatu seperti type_of_file: a. Beginilah tampilan buku pedoman saya sekarang:

- name: blabla
  hosts: blabla
  vars_files:
     - <path>/type_{{ type_of_file }}.yml
  roles: blabla

Terima kasih atas semua jawabannya. Saya menemukan mereka sangat membantu.

pandoJohn
sumber
0

Saya harap snip berikut (diambil dari Ansible Documentation ) dapat memberikan tambahan yang bermanfaat untuk kontribusi yang bermanfaat dari orang lain di atas.

- name: Show value of 'variablename'
  debug: msg="{{ lookup('vars', 'variabl' + myvar)}}"
  vars:
    variablename: hello
    myvar: ename
Peter Smallwood
sumber