Apa perbedaan antara default dan vars dalam peran Ansible?


151

Saat membuat peran Ansible baru, templat membuat direktori varsa dan defaultsdirektori dengan main.ymlfile kosong . Ketika mendefinisikan peran saya, saya dapat menempatkan definisi variabel dalam salah satu dari ini, dan mereka akan tersedia dalam tugas saya.

Apa perbedaan antara memasukkan definisi ke dalam defaultsdan vars? Apa yang harus masuk defaults, dan apa yang harus masuk vars? Apakah masuk akal untuk menggunakan keduanya untuk data yang sama?

Saya tahu ada perbedaan dalam hal prioritas / prioritas di antara keduanya, tetapi saya ingin memahami apa yang harus dilakukan.

Katakanlah peran saya akan membuat daftar direktori pada sistem target. Saya ingin memberikan daftar direktori default yang akan dibuat, tetapi ingin memungkinkan pengguna untuk menimpanya ketika menggunakan peran.

Ini akan terlihat seperti apa:

---
- directories:
  - foo
  - bar
  - baz

Saya bisa menempatkan ini ke dalam defaults/main.ymlatau di dalam vars/main.yml, dari perspektif eksekusi, itu tidak akan membuat perbedaan - tetapi ke mana harus pergi?

Jawaban:


113

Dokumentasi Ansible tentang presedensi variabel merangkum niceley ini:

Jika beberapa variabel dengan nama yang sama didefinisikan di tempat yang berbeda, mereka menang dalam urutan tertentu, yaitu:

  • vars tambahan (-e di baris perintah) selalu menang
  • kemudian datang variabel koneksi yang didefinisikan dalam inventaris (ansible_ssh_user, dll)
  • kemudian muncul "hampir semua yang lain" (saklar baris perintah, vars dalam permainan, termasuk vars, vars peran, dll)
  • kemudian muncul sisa variabel yang ditentukan dalam inventaris
  • kemudian muncul fakta yang ditemukan tentang suatu sistem
  • lalu "role defaults", yang merupakan yang paling "defaulty" dan kehilangan prioritas untuk semuanya.

Jadi misalkan Anda memiliki peran "kucing jantan" yang Anda gunakan untuk menginstal Tomcat pada sekelompok hosting, tetapi Anda memerlukan versi kucing jantan yang berbeda pada beberapa host, perlu menjalankannya sebagai pengguna yang berbeda dalam kasus lain, dll. defaults/main.ymlFile mungkin terlihat sesuatu seperti ini:

tomcat_version: 7.0.56
tomcat_user: tomcat

Karena itu hanya nilai-nilai default, itu berarti mereka akan digunakan jika variabel-variabel itu tidak didefinisikan di tempat lain untuk host yang dimaksud. Anda bisa menimpanya melalui extra-vars, melalui fakta di file inventaris Anda, dll. Untuk menentukan nilai yang berbeda untuk variabel-variabel ini.

Sunting: Perhatikan bahwa daftar di atas untuk Ansible 1.x. Di Ansible 2.x daftar telah diperluas. Seperti biasa, Dokumentasi Ansible menyediakan deskripsi terperinci tentang variabel diutamakan untuk 2.x.


4
Terima kasih, itu halaman yang luar biasa - itulah yang saya cari. Saya masuk ke lebih banyak detail tentang apa yang harus dimasukkan defaultsdan apa yang varslebih dalam .
nwinkler

42
itu perlu ditekankan: vars peran memiliki prioritas yang sangat tinggi . dalam pengalaman saya, mereka lebih tinggi daripada vars, yang sangat menjengkelkan.
tedder42

5 tahun kemudian, tapi ... Saya cenderung melihatnya seperti ini: default peran adalah hal-hal yang saya harapkan akan ditimpa oleh pengguna peran di vars mereka di suatu tempat. Peran peran, OTOH, memungkinkan saya untuk menghindari informasi pengkodean keras dalam tugas, tetapi kemungkinan hanya akan ditimpa untuk pengujian, dan diubah oleh pengelola peran. Sebagai contoh, nama pengguna admin awal akan menjadi default, tetapi versi dependensi akan berada di vars.
ntwrkguru

41

Variabel peran yang didefinisikan varmemiliki prioritas yang sangat tinggi - mereka hanya dapat ditimpa dengan melewati mereka pada baris perintah, dalam tugas tertentu atau dalam sebuah blok. Oleh karena itu, hampir semua variabel Anda harus didefinisikan dalam defaults.

Dalam artikel " Variable Precedence - Where To Put Your Role Vars ", penulis memberikan satu contoh tentang apa yang harus dimasukkan vars: konstanta khusus sistem yang tidak banyak berubah. Jadi Anda dapat memiliki vars/debian.ymldan vars/centos.ymldengan nama variabel yang sama tetapi nilai yang berbeda dan memasukkannya secara kondisional.


4

IMHO itu tidak praktis dan tidak masuk akal bahwa tempat-tempat Ansible seperti prioritas tinggi pada konfigurasi di vars dari peran . Konfigurasi dalam vars/main.ymldan defaults/main.ymlharus rendah dan mungkin prioritas yang sama.

Adakah contoh nyata dari kasus di mana kita menginginkan jenis perilaku ini?

Ada contoh yang kita tidak mau ini.

Maksudnya di sini adalah konfigurasi di defaults/main.ymltidak bisa dinamis. Konfigurasi dalam vars/main.ymlkaleng. Jadi misalnya Anda dapat memasukkan konfigurasi untuk OS dan versi tertentu secara dinamis seperti yang ditunjukkan pada geerlingguy.postgresql

Tetapi karena presedensi begitu aneh dan tidak praktis dalam geerlingguy mungkin perlu memperkenalkan variabel pseudo seperti yang dapat dilihat pada variabel.yml

- name: Define postgresql_packages.
  set_fact:
    postgresql_packages: "{{ __postgresql_packages | list }}"
  when: postgresql_packages is not defined

Ini adalah contoh nyata kehidupan nyata yang menunjukkan bahwa prioritasnya tidak praktis.

Hal lain yang ingin dibuat di sini adalah bahwa kita ingin peran dapat dikonfigurasi. Peran dapat bersifat eksternal, dikelola oleh orang lain. Sebagai aturan umum Anda tidak ingin konfigurasi dalam peran memiliki prioritas tinggi.


Ini harus berupa komentar, bukan jawaban.
ntwrkguru

3

Pada dasarnya, apa pun yang masuk ke "peran default" (folder default di dalam peran) adalah yang paling mudah ditempa dan diganti dengan mudah. Apa pun di direktori vars dari peran menimpa versi sebelumnya dari variabel tersebut di namespace. Gagasan yang harus diikuti di sini adalah bahwa semakin eksplisit Anda dalam ruang lingkup, semakin diutamakan dengan baris perintah - vars ekstra selalu menang. Host dan / atau variabel inventaris dapat memenangkan peran default, tetapi tidak termasuk eksplisit seperti direktori vars atau tugas include_vars. dokter


-4

Variabel dan default berjalan beriringan. ini sebuah contoh

-name: install package
 yum: name=xyz{{package_version}} state=present

di file default Anda, Anda akan memiliki sesuatu seperti:

package_version: 123

Apa yang mungkin dilakukan adalah, itu akan mengambil nilai package_versiondan meletakkannya di sebelah nama paket sehingga akan membaca di suatu tempat sebagai:

-name: install package
 yum: name=xyz123 state=present

Dengan cara ini ia akan menginstal xyz123dan bukan xyz123.4atau apa pun yang ada di repositori xyz.

Pada akhirnya itu akan dilakukan yum install -y xyz123

Jadi pada dasarnya default adalah nilai yang ada, jika Anda tidak menetapkan nilai spesifik untuk variabel, menyebabkan ruang itu tidak bisa tetap kosong.


Diturunkan karena tidak menjawab pertanyaan. Jelas defaultsdigunakan ketika tidak ada yang varsdidefinisikan, tetapi jawabannya tidak menjelaskan, mengapa Anda akan mendefinisikan nilai sebagai satu atau yang lain, yang merupakan apa yang diminta OP. Bandingkan dengan penjelasan di bawah ini.
Thomas Hirsch
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.