Dasar-dasar yang mungkin, yang tanpanya buku pedoman Anda akan menjadi segumpal pasta yang lengket

Saya melakukan banyak review terhadap kode Ansible orang lain dan menulis banyak sendiri. Dalam menganalisis kesalahan (baik kesalahan orang lain maupun kesalahan saya sendiri), serta sejumlah wawancara, saya menyadari kesalahan utama yang dilakukan pengguna Ansible - mereka terlibat dalam hal-hal rumit tanpa menguasai dasar-dasarnya.

Untuk memperbaiki ketidakadilan universal ini, saya memutuskan untuk menulis pengantar Ansible bagi mereka yang sudah mengetahuinya. Saya peringatkan Anda, ini bukan menceritakan kembali manusia, ini adalah bacaan panjang dengan banyak huruf dan tanpa gambar.

Tingkat yang diharapkan dari pembaca adalah bahwa beberapa ribu baris yamla telah ditulis, ada sesuatu yang sedang dalam produksi, tetapi “entah bagaimana semuanya bengkok.”

Nama

Kesalahan utama yang dilakukan pengguna Ansible adalah tidak mengetahui apa namanya. Jika Anda tidak tahu namanya, Anda tidak akan mengerti isi dokumentasinya. Contoh nyata: selama wawancara, seseorang yang sepertinya mengatakan bahwa dia banyak menulis di Ansible tidak dapat menjawab pertanyaan “terdiri dari elemen apa saja pedoman tersebut?” Dan ketika saya menyarankan bahwa “jawabannya diharapkan bahwa pedoman tersebut terdiri dari permainan,” komentar yang memberatkan “kami tidak menggunakannya” menyusul. Orang-orang menulis Ansible demi uang dan tidak menggunakan permainan. Mereka sebenarnya menggunakannya, tapi tidak tahu apa itu.

Jadi mari kita mulai dengan sesuatu yang sederhana: apa namanya? Mungkin Anda mengetahuinya, atau mungkin juga tidak, karena Anda tidak memperhatikan saat membaca dokumentasinya.

buku pedoman yang mungkin mengeksekusi buku pedoman tersebut. Playbook adalah file dengan ekstensi yml/yaml, yang di dalamnya terdapat sesuatu seperti ini:

---
- hosts: group1
  roles:
    - role1

- hosts: group2,group3
  tasks:
    - debug:

Kami telah menyadari bahwa keseluruhan file ini adalah pedoman. Kita bisa menunjukkan di mana perannya dan di mana tugasnya. Tapi dimana permainannya? Dan apa perbedaan antara bermain dan peran atau pedoman?

Semuanya ada di dokumentasi. Dan mereka merindukannya. Pemula - karena terlalu banyak dan Anda tidak akan mengingat semuanya sekaligus. Berpengalaman - karena "hal-hal sepele". Jika Anda berpengalaman, baca kembali halaman ini setidaknya sekali setiap enam bulan, dan kode Anda akan menjadi yang terdepan di kelasnya.

Jadi, ingat: Playbook adalah daftar yang terdiri dari play dan import_playbook.
Ini adalah salah satu permainan:

- hosts: group1
  roles:
    - role1

dan ini juga drama lainnya:

- hosts: group2,group3
  tasks:
    - debug:

Apa itu bermain? Kenapa dia?

Play adalah elemen kunci untuk sebuah pedoman, karena play dan only play mengaitkan daftar peran dan/atau tugas dengan daftar host di mana peran dan/atau tugas tersebut harus dijalankan. Di kedalaman dokumentasi, Anda dapat menemukan penyebutannya delegate_to, plugin pencarian lokal, pengaturan khusus klien jaringan, jump host, dll. Mereka memungkinkan Anda untuk sedikit mengubah tempat di mana tugas dilakukan. Tapi, lupakan saja. Masing-masing opsi cerdas ini memiliki kegunaan yang sangat spesifik, dan tentunya tidak universal. Dan kita berbicara tentang hal-hal dasar yang harus diketahui dan digunakan setiap orang.

Jika Anda ingin menampilkan “sesuatu” “di suatu tempat”, Anda menulis drama. Bukan peran. Bukan peran dengan modul dan delegasi. Anda mengambilnya dan menulis drama. Di mana, di bidang host Anda mencantumkan tempat untuk mengeksekusi, dan dalam peran/tugas - apa yang harus dieksekusi.

Sederhana, bukan? Bagaimana bisa sebaliknya?

Salah satu momen khas ketika orang memiliki keinginan untuk melakukan hal ini bukan melalui permainan adalah “peran yang mengatur segalanya”. Saya ingin memiliki peran yang mengonfigurasi server tipe pertama dan server tipe kedua.

Contoh tipikalnya adalah pemantauan. Saya ingin memiliki peran pemantauan yang akan mengonfigurasi pemantauan. Peran pemantauan ditugaskan untuk memantau host (menurut permainan). Namun ternyata untuk monitoring kita perlu mengirimkan paket ke host yang kita pantau. Mengapa tidak menggunakan delegasi? Anda juga perlu mengkonfigurasi iptables. melimpahkan? Anda juga perlu menulis/memperbaiki konfigurasi DBMS untuk mengaktifkan pemantauan. melimpahkan! Dan jika kreativitasnya kurang, maka bisa dilakukan delegasi include_role dalam loop bersarang menggunakan filter rumit pada daftar grup, dan di dalamnya include_role Anda dapat berbuat lebih banyak delegate_to lagi. Dan kita berangkat...

Keinginan yang baik - untuk memiliki satu peran pemantauan, yang "melakukan segalanya" - membawa kita ke neraka yang seringkali hanya ada satu jalan keluar: menulis ulang semuanya dari awal.

Dimana kesalahannya terjadi disini? Saat Anda mengetahui bahwa untuk melakukan tugas "x" pada host X Anda harus pergi ke host Y dan melakukan "y" di sana, Anda harus melakukan latihan sederhana: pergi dan tulis permainan, yang pada host Y melakukan y. Jangan menambahkan sesuatu ke "x", tapi tulislah dari awal. Bahkan dengan variabel hardcoded.

Tampaknya semua paragraf di atas dikatakan dengan benar. Tapi ini bukan kasusmu! Karena Anda ingin menulis kode yang dapat digunakan kembali yang KERING dan mirip perpustakaan, dan Anda perlu mencari metode untuk melakukannya.

Di sinilah letak kesalahan serius lainnya. Sebuah kesalahan yang mengubah banyak proyek dari yang ditulis dengan baik (bisa lebih baik, tetapi semuanya berfungsi dan mudah diselesaikan) menjadi sebuah kengerian yang bahkan penulisnya tidak dapat memahaminya. Itu berhasil, tetapi Tuhan melarang Anda mengubah apa pun.

Kesalahannya adalah: peran adalah fungsi perpustakaan. Analogi ini telah menghancurkan begitu banyak awal yang baik sehingga sungguh menyedihkan untuk ditonton. Peran tersebut bukan fungsi perpustakaan. Dia tidak bisa melakukan perhitungan dan dia tidak bisa membuat keputusan level permainan. Ingatkan saya keputusan apa yang diambil oleh permainan?

Terima kasih, kamu benar. Permainan membuat keputusan (lebih tepatnya, berisi informasi) tentang tugas dan peran apa yang harus dilakukan pada host mana.

Jika Anda mendelegasikan keputusan ini ke suatu peran, dan bahkan dengan perhitungan, Anda akan membuat diri Anda sendiri (dan orang yang akan mencoba menguraikan kode Anda) mengalami kehidupan yang menyedihkan. Peran tersebut tidak menentukan di mana peran tersebut dilakukan. Keputusan ini dibuat melalui permainan. Peran melakukan apa yang diperintahkan, di tempat yang diperintahkan.

Mengapa berbahaya untuk memprogram di Ansible dan mengapa COBOL lebih baik daripada Ansible, kita akan membahasnya di bab tentang variabel dan jinja. Untuk saat ini, katakanlah satu hal - setiap perhitungan Anda meninggalkan jejak perubahan variabel global yang tak terhapuskan, dan Anda tidak dapat berbuat apa-apa. Begitu kedua “jejak” itu berpotongan, semuanya hilang.

Catatan bagi yang mudah tersinggung: peran tersebut tentu saja dapat memengaruhi aliran kontrol. Makan delegate_to dan itu memiliki kegunaan yang masuk akal. Makan meta: end host/play. Tetapi! Ingat kita mengajarkan dasar-dasarnya? Lupa tentang delegate_to. Kita berbicara tentang kode Ansible yang paling sederhana dan terindah. Yang mudah dibaca, mudah ditulis, mudah di-debug, mudah diuji, dan mudah diselesaikan. Jadi, sekali lagi:

play dan only play memutuskan host mana yang dieksekusi.

Pada bagian ini, kita membahas pertentangan antara permainan dan peran. Sekarang mari kita bicara tentang tugas vs hubungan peran.

Tugas dan Peran

Pertimbangkan bermain:

- hosts: somegroup
  pre_tasks:
    - some_tasks1:
  roles:
     - role1
     - role2
  post_tasks:
     - some_task2:
     - some_task3:

Katakanlah Anda perlu melakukan foo. Dan sepertinya foo: name=foobar state=present. Di mana saya harus menulis ini? di pra? pos? Buat peran?

...Dan kemana perginya tugas-tugas itu?

Kami memulai lagi dengan dasar-dasarnya - perangkat bermain. Jika Anda terpaku pada masalah ini, Anda tidak dapat menggunakan permainan sebagai dasar untuk segala hal lainnya, dan hasil Anda akan "goyah".

Perangkat bermain: arahan host, pengaturan untuk permainan itu sendiri dan bagian pra_tugas, tugas, peran, pasca_tugas. Parameter permainan lainnya tidak penting bagi kami sekarang.

Urutan bagiannya beserta tugas dan perannya: pre_tasks, roles, tasks, post_tasks. Karena secara semantik urutan eksekusinya adalah antara tasks и roles tidak jelas, maka praktik terbaik mengatakan bahwa kami menambahkan satu bagian tasks, hanya jika tidak roles... Jika ada roles, lalu semua tugas terlampir ditempatkan di beberapa bagian pre_tasks/post_tasks.

Yang tersisa hanyalah semuanya jelas secara semantik: pertama pre_tasks, lalu roles, lalu post_tasks.

Namun kami masih belum menjawab pertanyaan: di mana pemanggilan modulnya? foo menulis? Apakah kita perlu menulis seluruh peran untuk setiap modul? Atau lebih baik punya peran yang kental untuk semuanya? Dan jika bukan sebuah peran, lalu di mana saya harus menulis - sebelum atau sesudahnya?

Jika tidak ada jawaban yang masuk akal untuk pertanyaan-pertanyaan ini, maka ini adalah tanda kurangnya intuisi, yaitu “fondasi yang goyah”. Mari kita cari tahu. Pertama, pertanyaan keamanan: Jika play punya pre_tasks и post_tasks (dan tidak ada tugas atau peran), apakah ada yang rusak jika saya melakukan tugas pertama post_tasks Saya akan memindahkannya sampai akhir pre_tasks?

Tentu saja, kata-kata dari pertanyaan itu mengisyaratkan bahwa pertanyaan itu akan rusak. Tapi apa sebenarnya?

... Penangan. Membaca dasar-dasarnya mengungkapkan fakta penting: semua penangan di-flush secara otomatis setelah setiap bagian. Itu. semua tugas dari pre_tasks, lalu semua penangan yang diberitahu. Kemudian semua peran dan semua penangan yang diberitahukan dalam peran tersebut dieksekusi. Setelah post_tasks dan penangannya.

Jadi, jika Anda menyeret tugas dari post_tasks в pre_tasks, maka kemungkinan besar Anda akan mengeksekusinya sebelum handler dijalankan. misalnya jika di pre_tasks server web diinstal dan dikonfigurasi, dan post_tasks sesuatu dikirim ke sana, lalu transfer tugas ini ke bagian tersebut pre_tasks akan mengarah pada fakta bahwa pada saat "mengirim" server belum berjalan dan semuanya akan rusak.

Sekarang mari kita pikirkan lagi mengapa kita membutuhkannya pre_tasks и post_tasks? Misalnya, untuk menyelesaikan semua yang diperlukan (termasuk penangan) sebelum memenuhi peran tersebut. A post_tasks akan memungkinkan kita bekerja dengan hasil menjalankan peran (termasuk penangan).

Seorang ahli Ansible yang cerdik akan memberi tahu kita apa itu. meta: flush_handlers, tetapi mengapa kita memerlukan flush_handlers jika kita dapat mengandalkan urutan eksekusi bagian yang sedang dimainkan? Selain itu, penggunaan meta: flush_handlers dapat memberi kita hal-hal yang tidak terduga dengan penangan duplikat, memberi kita peringatan aneh saat digunakan when у block dll. Semakin baik Anda mengetahui kemungkinannya, semakin banyak nuansa yang dapat Anda sebutkan untuk solusi yang “rumit”. Dan solusi sederhana - menggunakan pembagian alami antara pra/peran/pasca - tidak menimbulkan perbedaan.

Dan, kembali ke 'foo' kami. Di mana saya harus meletakkannya? Di pra, pasca, atau peran? Jelasnya, ini tergantung pada apakah kita memerlukan hasil dari handler untuk foo. Jika tidak ada, maka foo tidak perlu ditempatkan di sebelum atau sesudah - bagian ini memiliki arti khusus - menjalankan tugas sebelum dan sesudah bagian utama kode.

Sekarang jawaban atas pertanyaan "peran atau tugas" tergantung pada apa yang sudah ada - jika ada tugas di sana, maka Anda perlu menambahkannya ke tugas. Jika ada peran, Anda perlu membuat peran (bahkan dari satu tugas). Izinkan saya mengingatkan Anda bahwa tugas dan peran tidak digunakan secara bersamaan.

Memahami dasar-dasar Ansible memberikan jawaban yang masuk akal atas pertanyaan selera.

Tugas dan peran (bagian kedua)

Sekarang mari kita bahas situasi ketika Anda baru mulai menulis buku pedoman. Anda perlu membuat foo, bar dan baz. Apakah ketiga tugas ini, satu peran atau tiga peran? Untuk meringkas pertanyaannya: pada titik manakah Anda sebaiknya mulai menulis peran? Apa gunanya menulis peran ketika Anda bisa menulis tugas?... Apa itu peran?

Salah satu kesalahan terbesar (saya sudah membicarakan hal ini) adalah berpikir bahwa peran itu seperti fungsi di perpustakaan program. Seperti apa deskripsi fungsi generiknya? Ia menerima argumen masukan, berinteraksi dengan penyebab samping, melakukan efek samping, dan mengembalikan nilai.

Sekarang, perhatian. Apa yang dapat dilakukan dari peran ini? Anda selalu dapat menyebutkan efek samping, inilah inti dari keseluruhan Ansible - untuk menciptakan efek samping. Punya penyebab sampingan? Dasar. Namun dengan "memberikan nilai dan mengembalikannya" - di situlah hal itu tidak berhasil. Pertama, Anda tidak bisa memberikan nilai ke suatu peran. Anda dapat mengatur variabel global dengan ukuran permainan seumur hidup di bagian vars untuk peran tersebut. Anda dapat mengatur variabel global yang dimainkan seumur hidup di dalam peran tersebut. Atau bahkan dengan buku pedoman seumur hidup (set_fact/register). Tapi Anda tidak bisa memiliki "variabel lokal". Anda tidak dapat "mengambil nilai" dan "mengembalikannya".

Hal utama berikut ini: Anda tidak dapat menulis sesuatu di Ansible tanpa menimbulkan efek samping. Mengubah variabel global selalu merupakan efek samping bagi suatu fungsi. Di Rust, misalnya, mengubah variabel global adalah hal yang mudah unsafe. Dan di Ansible, ini adalah satu-satunya metode untuk memengaruhi nilai-nilai suatu peran. Perhatikan kata-kata yang digunakan: bukan “memberikan nilai pada peran”, tetapi “mengubah nilai yang digunakan peran”. Tidak ada isolasi antar peran. Tidak ada isolasi antara tugas dan peran.

Total: peran bukanlah suatu fungsi.

Apa bagusnya peran itu? Pertama, peran tersebut memiliki nilai default (/default/main.yaml), kedua, peran tersebut memiliki direktori tambahan untuk menyimpan file.

Apa manfaat dari nilai default? Karena dalam piramida Maslow, tabel prioritas variabel Ansible yang agak menyimpang, default peran adalah prioritas paling rendah (dikurangi parameter baris perintah Ansible). Artinya, jika Anda perlu memberikan nilai default dan tidak khawatir nilai tersebut akan menggantikan nilai dari variabel inventaris atau grup, maka default peran adalah satu-satunya tempat yang tepat untuk Anda. (Saya sedikit berbohong - masih ada lagi |d(your_default_here), tetapi jika kita berbicara tentang tempat yang tidak bergerak, maka hanya peran defaultnya).

Apa lagi yang hebat dari peran-peran tersebut? Karena mereka punya katalog sendiri. Ini adalah direktori untuk variabel, baik konstan (yaitu dihitung berdasarkan peran) dan dinamis (ada pola atau anti-pola - include_vars dengan {{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml.). Ini adalah direktori untuk files/, templates/. Selain itu, ini memungkinkan Anda memiliki modul dan plugin sendiri (library/). Namun, dibandingkan dengan tugas-tugas dalam buku pedoman (yang juga dapat memiliki semua ini), satu-satunya keuntungan di sini adalah bahwa file-file tersebut tidak dibuang ke dalam satu tumpukan, tetapi beberapa tumpukan terpisah.

Satu detail lagi: Anda dapat mencoba membuat peran yang tersedia untuk digunakan kembali (melalui galaksi). Dengan munculnya koleksi, pembagian peran bisa dianggap hampir terlupakan.

Oleh karena itu, peran memiliki dua fitur penting: peran memiliki default (fitur unik) dan peran memungkinkan Anda menyusun kode.

Kembali ke pertanyaan awal: kapan melakukan tugas dan kapan melakukan peran? Tugas dalam buku pedoman paling sering digunakan sebagai “perekat” sebelum/sesudah peran, atau sebagai elemen pembangun independen (maka tidak boleh ada peran dalam kode). Tumpukan tugas normal yang bercampur dengan peran adalah kecerobohan yang jelas. Anda harus mengikuti gaya tertentu - baik tugas atau peran. Peran memberikan pemisahan entitas dan default, tugas memungkinkan Anda membaca kode lebih cepat. Biasanya, kode yang lebih “stasioner” (penting dan kompleks) dimasukkan ke dalam peran, dan skrip tambahan ditulis dalam gaya tugas.

Dimungkinkan untuk melakukan import_role sebagai tugas, tetapi jika Anda menulis ini, bersiaplah untuk menjelaskan kepada rasa keindahan Anda sendiri mengapa Anda ingin melakukan ini.

Pembaca yang cerdik mungkin mengatakan bahwa peran dapat mengimpor peran, peran dapat memiliki ketergantungan melalui galaxy.yml, dan ada juga yang mengerikan dan mengerikan include_role — Saya mengingatkan Anda bahwa kami meningkatkan keterampilan dalam Ansible dasar, dan bukan dalam senam figur.

Penangan dan tugas

Mari kita bahas hal lain yang jelas: penangan. Mengetahui cara menggunakannya dengan benar hampir merupakan sebuah seni. Apa perbedaan antara handler dan drag?

Karena kita mengingat dasar-dasarnya, berikut ini contohnya:

- hosts: group1
  tasks:
    - foo:
      notify: handler1
  handlers:
     - name: handler1
       bar:

Penangan peran terletak di rolename/handlers/main.yaml. Penangan mencari-cari di antara semua peserta permainan: pre/post_tasks dapat menarik pengendali peran, dan sebuah peran dapat menarik pengendali dari permainan. Namun, panggilan "lintas peran" ke penangan menyebabkan lebih banyak masalah daripada mengulangi penangan yang sepele. (Elemen praktik terbaik lainnya adalah mencoba untuk tidak mengulangi nama penangan).

Perbedaan utamanya adalah tugas selalu dijalankan (secara idempoten) (tag plus/minus dan when), dan pawang - berdasarkan perubahan status (beri tahu kebakaran hanya jika sudah diubah). Apa artinya ini? Misalnya saja ketika di-restart, jika tidak ada perubahan, maka tidak akan ada handler. Mengapa kita perlu mengeksekusi handler ketika tidak ada perubahan dalam tugas pembangkitan? Misalnya karena ada yang rusak dan berubah, namun eksekusi tidak sampai ke handler. Misalnya karena jaringan sedang down untuk sementara waktu. Konfigurasi telah berubah, layanan belum dimulai ulang. Saat berikutnya Anda memulainya, konfigurasi tidak lagi berubah, dan layanan tetap menggunakan konfigurasi versi lama.

Situasi dengan konfigurasi tidak dapat diselesaikan (lebih tepatnya, Anda dapat membuat sendiri protokol restart khusus dengan flag file, dll., tetapi ini tidak lagi 'mungkin dasar' dalam bentuk apa pun). Namun ada cerita umum lainnya: kami menginstal aplikasi, merekamnya .service-file, dan sekarang kami menginginkannya daemon_reload и state=started. Dan tempat yang wajar untuk hal ini sepertinya adalah sang pawang. Namun jika Anda menjadikannya bukan penangan melainkan tugas di akhir daftar tugas atau peran, maka tugas tersebut akan dieksekusi secara idempoten setiap saat. Sekalipun pedomannya pecah di tengah-tengah. Ini tidak menyelesaikan masalah restart sama sekali (Anda tidak dapat melakukan tugas dengan atribut restarted, karena idempotensi hilang), tetapi hal ini layak dilakukan state=started, stabilitas keseluruhan playbook meningkat, karena jumlah koneksi dan keadaan dinamis berkurang.

Properti positif lainnya dari handler adalah tidak menyumbat output. Tidak ada perubahan - tidak ada tambahan yang dilewati atau oke pada output - lebih mudah dibaca. Ini juga merupakan properti negatif - jika Anda menemukan kesalahan ketik dalam tugas yang dijalankan secara linier saat pertama kali dijalankan, maka penangan akan dieksekusi hanya ketika diubah, mis. dalam beberapa kondisi - sangat jarang. Misalnya, untuk pertama kali dalam hidup saya lima tahun kemudian. Dan tentu saja akan ada kesalahan ketik pada nama dan semuanya akan rusak. Dan jika Anda tidak menjalankannya untuk kedua kalinya, tidak ada perubahan.

Secara terpisah, kita perlu membicarakan tentang ketersediaan variabel. Misalnya, jika Anda memberi tahu tugas dengan perulangan, apa yang ada di variabelnya? Anda bisa menebak secara analitis, namun tidak selalu sepele, apalagi jika variabelnya berasal dari tempat yang berbeda.

... Jadi penangan kurang berguna dan lebih bermasalah daripada yang terlihat. Jika Anda bisa menulis sesuatu dengan indah (tanpa embel-embel) tanpa penangan, lebih baik melakukannya tanpa penangan. Jika tidak berhasil dengan baik, lebih baik bersama mereka.

Pembaca yang korosif dengan tepat menunjukkan bahwa kita belum membahasnya listenbahwa seorang handler dapat memanggil notify untuk handler lain, bahwa seorang handler dapat menyertakan import_tasks (yang dapat melakukan include_role dengan with_items), bahwa sistem handler di Ansible adalah Turing-complete, bahwa handler dari include_role berpotongan dengan cara yang aneh dengan handler dari play, dll..d. - semua ini jelas bukan “dasar”).

Meskipun ada satu WTF spesifik yang sebenarnya merupakan fitur yang perlu Anda ingat. Jika tugas Anda dijalankan dengan delegate_to dan telah memberi tahu, maka penangan yang sesuai dijalankan tanpa delegate_to, yaitu. pada tuan rumah tempat permainan ditugaskan. (Meskipun pawangnya, tentu saja, mungkin melakukannya delegate_to Sama).

Secara terpisah, saya ingin menyampaikan beberapa patah kata tentang peran yang dapat digunakan kembali. Sebelum koleksi muncul, ada gagasan bahwa Anda bisa membuat peran universal ansible-galaxy install dan pergi. Bekerja pada semua OS dari semua varian dalam semua situasi. Jadi menurut saya: tidak berhasil. Peran apa pun dengan massa include_vars, yang mendukung 100500 kasus, pasti akan mengalami banyak bug kasus sudut. Mereka dapat dicakup dengan pengujian besar-besaran, tetapi seperti halnya pengujian apa pun, Anda memiliki produk Cartesian dari nilai input dan fungsi total, atau Anda memiliki “skenario individual yang tercakup”. Pendapat saya jauh lebih baik jika perannya linier (kompleksitas siklomatik 1).

Semakin sedikit jika (eksplisit atau deklaratif - dalam bentuk when atau bentuk include_vars berdasarkan kumpulan variabel), semakin baik perannya. Kadang-kadang Anda harus membuat cabang, tapi, saya ulangi, semakin sedikit cabangnya, semakin baik. Jadi sepertinya peran yang bagus dengan galaxy (berhasil!) dengan banyak when mungkin kurang disukai dibandingkan peran “sendiri” dari lima tugas. Saat ketika peran galaksi lebih baik adalah ketika Anda mulai menulis sesuatu. Saat yang lebih buruk adalah ketika ada sesuatu yang rusak dan Anda curiga itu karena “peran dengan galaksi”. Anda membukanya, dan ada lima inklusi, delapan lembar tugas dan satu tumpukan when'ov... Dan kita perlu memikirkan hal ini. Alih-alih 5 tugas, daftar linier di mana tidak ada yang perlu dipecahkan.

Di bagian berikut

  • Sedikit tentang inventaris, variabel grup, plugin host_group_vars, hostvars. Cara mengikat simpul Gordian dengan spageti. Variabel cakupan dan prioritas, Model memori yang memungkinkan. “Jadi di mana kita menyimpan nama pengguna untuk database?”
  • jinja: {{ jinja }} — plastisin lunak nosql notype noseense. Itu ada di mana-mana, bahkan di tempat yang tidak Anda duga. Sedikit tentang !!unsafe dan yaml yang enak.

Sumber: www.habr.com

Tambah komentar