
Pendekatan IaC (Infrastructure as Code) tidak hanya terdiri dari kode yang disimpan dalam repositori, tetapi juga orang-orang dan proses yang mengelilingi kode ini. Apakah mungkin untuk menggunakan kembali pendekatan dari pengembangan perangkat lunak hingga manajemen dan deskripsi infrastruktur? Ini tidak akan berlebihan untuk mengingat ide ini saat Anda membaca artikel.
Versi Rusia
Ini adalah transkrip kinerja saya di DevopsConf 2019-05-28 .
Infrastruktur sebagai bash history

Misalkan Anda datang ke proyek baru, dan mereka berkata kepada Anda: "kami memiliki Infrastruktur sebagai Kode ." Pada kenyataannya, ternyata, Infrastruktur sebagai bash history atau misalnya Dokumentasi sebagai bash history . Ini adalah situasi yang sangat nyata, misalnya, kasus serupa dijelaskan oleh Denis Lysenko dalam pidatonya Bagaimana cara mengganti seluruh infrastruktur dan mulai tidur nyenyak , ia mengatakan bagaimana dari bash history mereka mendapatkan infrastruktur ramping pada proyek tersebut.
Jika mau, Anda dapat mengatakan bahwa Infrastruktur sebagai bash history seperti kode:
- reproduktifitas : Anda dapat mengambil bash history, menjalankan perintah dari sana, mungkin, omong-omong, Anda akan mendapatkan konfigurasi yang berfungsi di output.
- versi : Anda tahu siapa yang masuk dan apa yang dilakukan, sekali lagi, bukan fakta bahwa ini akan mengarahkan Anda ke konfigurasi yang berfungsi pada output.
- sejarah : sejarah siapa yang melakukan apa. hanya Anda yang tidak dapat menggunakannya jika Anda kehilangan server.
Apa yang harus dilakukan
Infrastruktur sebagai kode

Bahkan kasus aneh seperti Infrastruktur seperti bash history dapat ditarik oleh Telinga ke Infrastruktur sebagai Kode , tetapi ketika kita ingin melakukan sesuatu yang lebih rumit daripada server LAMP lama yang baik, kita akan sampai pada kesimpulan bahwa kode ini perlu dimodifikasi, dimodifikasi, dimodifikasi entah bagaimana . Selanjutnya, kami ingin mempertimbangkan paralel antara Infrastruktur sebagai Kode dan pengembangan perangkat lunak.
KERING

Pada proyek untuk pengembangan sistem penyimpanan, ada sub-tugas untuk mengkonfigurasi SDS secara berkala : kami merilis rilis baru - perlu diluncurkan untuk pengujian lebih lanjut. Tugasnya sangat sederhana:
- datang ke sini dengan ssh dan jalankan perintah.
- salin file di sana.
- di sini adalah tweak untuk konfigurasi.
- mulai layanan di sana
- ...
- KEUNTUNGAN!
Bash lebih dari cukup untuk logika yang dijelaskan, terutama pada tahap awal proyek ketika baru saja dimulai. Ini tidak buruk bahwa Anda menggunakan bash , tetapi seiring waktu Anda diminta untuk menyebarkan sesuatu yang serupa, tetapi sedikit berbeda. Hal pertama yang terlintas dalam pikiran: copy-paste. Dan sekarang kami memiliki dua skrip yang sangat mirip yang melakukan hal yang hampir sama. Seiring waktu, jumlah skrip telah tumbuh, dan kami dihadapkan dengan kenyataan bahwa ada semacam logika bisnis untuk menggunakan instalasi, yang harus disinkronkan di antara skrip yang berbeda, itu cukup sulit.

Ternyata ada semacam latihan KERING (Jangan Ulangi Diri Sendiri). Idenya adalah untuk menggunakan kembali kode yang ada. Kedengarannya sederhana, tetapi tidak langsung sampai ke sini. Dalam kasus kami, itu adalah ide yang lumrah: untuk memisahkan konfigurasi dari skrip. Yaitu logika bisnis bagaimana instalasi digunakan secara terpisah, konfigurasi secara terpisah.
SOLID untuk CFM

Seiring waktu, proyek tumbuh dan perpanjangan alami adalah munculnya Ansible. Alasan utama penampilannya adalah kehadiran keahlian dalam tim dan bahwa bash tidak dimaksudkan untuk logika yang kompleks. Ansible juga mulai mengandung logika yang kompleks. Agar logika yang kompleks tidak berubah menjadi kekacauan, ada prinsip-prinsip pengorganisasian kode SOLID dalam pengembangan perangkat lunak. Misalnya, Grigory Petrov dalam laporannya "Mengapa TI membutuhkan merek pribadi" menimbulkan pertanyaan bahwa seseorang dirancang sedemikian rupa sehingga lebih mudah dioperasikan dengan beberapa entitas sosial, dalam pengembangan perangkat lunak, ini adalah objek. Jika Anda menggabungkan kedua ide ini dan terus mengembangkannya, Anda akan melihat bahwa Anda juga dapat menggunakan SOLID dalam deskripsi infrastruktur sehingga akan lebih mudah untuk mempertahankan dan memodifikasi logika ini di masa mendatang.
Prinsip Tanggung Jawab Tunggal

Setiap kelas hanya melakukan satu tugas.
Tidak perlu mencampur kode dan membuat monster pasta ilahi monolitik. Infrastruktur harus terdiri dari batu bata sederhana. Ternyata jika Anda membagi buku pedoman Ansible menjadi potongan-potongan kecil, baca peran Ansible, maka itu lebih mudah untuk dipertahankan.
Prinsip tertutup terbuka

Prinsip keterbukaan / penutupan.
- Terbuka untuk ekspansi: berarti perilaku suatu entitas dapat diperluas dengan menciptakan jenis entitas baru.
- Ditutup untuk perubahan: sebagai hasil dari perluasan perilaku suatu entitas, tidak ada perubahan yang harus dilakukan pada kode yang menggunakan entitas ini.
Awalnya, kami menggunakan infrastruktur uji pada mesin virtual, tetapi karena fakta bahwa logika bisnis penyebaran terpisah dari implementasi, kami dengan mudah menambahkan rolling ke bare-metal.
Prinsip Substitusi Liskov

Prinsip substitusi Barbara Liskov. objek dalam program harus dapat diganti dengan instance subtipe mereka tanpa mengubah kebenaran program
Jika Anda melihat lebih luas, ini bukan fitur dari proyek tertentu yang dapat Anda terapkan SOLID , umumnya tentang CFM, misalnya, pada proyek lain Anda perlu menggunakan aplikasi Java kotak di atas berbagai Jawa, server aplikasi, database, OS, dll. Untuk contoh ini, saya akan mempertimbangkan prinsip-prinsip SOLID lebih lanjut.
Dalam kasus kami, sebagai bagian dari tim infrastruktur, ada kesepakatan bahwa jika kami memasang peran imbjava atau oraclejava, maka kami memiliki binary java executable. Ini perlu karena peran yang lebih tinggi tergantung pada perilaku ini, mereka berharap java akan hadir. Pada saat yang sama, ini memungkinkan kita untuk mengganti satu implementasi / versi java dengan yang lain tanpa mengubah logika penerapan aplikasi.
Masalahnya di sini terletak pada kenyataan bahwa dalam Ansible tidak mungkin untuk mengimplementasikan seperti itu, sebagai akibatnya, beberapa perjanjian muncul dalam tim.
Prinsip Pemisahan Antarmuka

Prinsip pemisahan antarmuka βbanyak antarmuka yang dirancang khusus untuk pelanggan lebih baik daripada antarmuka tujuan umum tunggal.
Awalnya, kami mencoba untuk menempatkan semua variasi dalam menyebarkan aplikasi ke dalam satu buku pedoman Ansible, tetapi sulit untuk mendukung, dan pendekatan ketika kami memiliki antarmuka keluar (klien mengharapkan port 443) ditentukan, maka untuk implementasi tertentu Anda dapat membangun infrastruktur dari batu bata yang terpisah.
Prinsip Pembalikan Ketergantungan

Prinsip inversi ketergantungan. Modul tingkat atas tidak harus bergantung pada modul tingkat bawah. Kedua jenis modul harus bergantung pada abstraksi. Abstraksi tidak harus bergantung pada detail. Rinciannya harus bergantung pada abstraksi.
Di sini contohnya akan didasarkan pada antipattern.
- Salah satu pelanggan memiliki cloud pribadi.
- Di dalam cloud, kami memesan mesin virtual.
- Tetapi mengingat fitur cloud, penyebaran aplikasi terkait dengan hypervisor yang digunakan VM.
Yaitu logika penyebaran aplikasi tingkat tinggi, dependensi mengalir ke tingkat hypervisor yang lebih rendah, dan ini berarti masalah ketika menggunakan kembali logika ini. Jangan lakukan itu.
Interaksi

Infrastruktur sebagai kode tidak hanya tentang kode, tetapi juga tentang hubungan antara kode dan seseorang, tentang interaksi antara pengembang infrastruktur.
Faktor bus

Misalkan Anda memiliki Vasya di proyek tersebut. Vasya tahu segalanya tentang infrastruktur Anda, apa yang akan terjadi jika Vasya tiba-tiba menghilang? Ini adalah situasi yang sangat nyata, karena bisa ditabrak bus. Terkadang ini terjadi. Jika ini terjadi dan pengetahuan tentang kode, strukturnya, cara kerjanya, penampilan, dan kata sandi tidak didistribusikan di tim, maka Anda mungkin menghadapi sejumlah situasi yang tidak menyenangkan. Berbagai pendekatan dapat digunakan untuk meminimalkan risiko ini dan mendistribusikan pengetahuan dalam tim.
Berpasangan dengan pasangan

Ini tidak seperti lelucon yang admin minum bir, mengubah kata sandi, tetapi analog pemrograman pasangan. Yaitu dua insinyur duduk di satu komputer, satu keyboard dan mulai mengkonfigurasi infrastruktur Anda bersama-sama: mengkonfigurasi server, menulis peran yang mungkin, dll. Kedengarannya bagus, tetapi itu tidak berhasil bagi kami. Tetapi kasus-kasus khusus dari praktik ini berhasil. Seorang karyawan baru telah datang, mentornya mengambil tugas nyata bersamanya, bekerja, mentransfer pengetahuan.
Kasus khusus lainnya adalah panggilan insiden. Selama masalah, sekelompok orang yang bertugas dan terlibat mengumpulkan, satu pemimpin ditunjuk, yang berbagi layarnya dan menyuarakan kereta pemikiran. Peserta lain mengikuti pemikiran pemimpin, memata-matai trik dari konsol, memeriksa apakah mereka tidak melewatkan satu baris pun dalam log, mempelajari hal-hal baru tentang sistem. Pendekatan ini berhasil daripada tidak.
Ulasan kode

Secara subyektif, lebih efisien, penyebaran pengetahuan tentang infrastruktur dan bagaimana hal itu dilakukan dengan menggunakan tinjauan kode:
- Infrastruktur dijelaskan oleh kode dalam repositori.
- Perubahan terjadi di cabang terpisah.
- Dengan permintaan penggabungan, Anda dapat melihat delta perubahan infrastruktur.
Sorotan di sini adalah bahwa pengulas dipilih pada gilirannya, sesuai dengan jadwal, yaitu dengan beberapa kemungkinan Anda akan naik ke infrastruktur baru.
Gaya Kode

Seiring waktu, pertengkaran mulai muncul selama peninjauan, sebagai pengulas memiliki gaya mereka sendiri dan rotatability pengulas menumpuk mereka dengan gaya yang berbeda: 2 spasi atau 4, camelCase atau snake_case. Implementasi ini tidak berhasil segera.
- Gagasan pertama adalah merekomendasikan penggunaan linter, karena semua insinyur yang sama, semuanya pintar. Tetapi editor yang berbeda, OS, tidak nyaman
- Ini berkembang menjadi bot, yang untuk masing-masing komit berkomitmen untuk yang bermasalah ditulis dalam slack, dan menerapkan output linter. Tetapi dalam kebanyakan kasus, hal-hal yang lebih penting ditemukan dan kode tetap tidak diperbaiki.
Tuan bangunan hijau

Waktu berlalu, dan kami sampai pada kesimpulan bahwa Anda tidak boleh membiarkan komitmen yang tidak lulus tes tertentu ke master. Voila! kami menemukan Green Build Master, yang telah lama dipraktikkan dalam pengembangan perangkat lunak:
- Pengembangan adalah cabang yang terpisah.
- Tes dijalankan di utas ini.
- Jika tes gagal, kode tidak akan masuk ke panduan.
Membuat keputusan ini sangat menyakitkan karena menyebabkan banyak kontroversi, tetapi itu layak, karena permintaan untuk merger mulai datang ke tinjauan tanpa perselisihan dalam gaya dan seiring waktu, jumlah bidang masalah mulai berkurang.
Pengujian IaC

Selain pemeriksaan gaya, Anda dapat menggunakan hal-hal lain, misalnya, untuk memverifikasi bahwa infrastruktur Anda benar-benar dapat digunakan. Atau periksa apakah perubahan infrastruktur tidak akan mengakibatkan kehilangan uang. Mengapa ini diperlukan? Pertanyaannya kompleks dan filosofis, lebih baik untuk menjawab dengan kisah bahwa entah bagaimana ada scaler otomatis pada Powershell yang tidak memeriksa kondisi batas => lebih banyak VM dibuat dari yang diperlukan => klien menghabiskan lebih banyak uang daripada yang direncanakan. Ini tidak cukup menyenangkan, tetapi akan cukup realistis untuk menangkap kesalahan ini pada tahap sebelumnya.
Orang mungkin bertanya, mengapa membuat infrastruktur yang kompleks semakin sulit? Tes untuk infrastruktur, serta untuk kode, bukan tentang penyederhanaan, tetapi tentang mengetahui bagaimana infrastruktur Anda harus bekerja.
IaC Menguji Piramida

Pengujian IaC: Analisis Statis
Jika Anda segera menggunakan seluruh infrastruktur dan memverifikasi bahwa itu berfungsi, maka itu mungkin membutuhkan banyak waktu dan membutuhkan banyak waktu. Karena itu, dasarnya haruslah sesuatu yang cepat berfungsi, banyak, dan mencakup banyak tempat primitif.
Bash itu rumit
Ini adalah contoh sepele. pilih semua file di direktori saat ini dan salin ke lokasi lain. Hal pertama yang terlintas dalam pikiran:
for i in * ; do cp $i /some/path/$i.bak done
Tetapi bagaimana jika ada spasi dalam nama file? Baiklah, kita pintar, kita bisa menggunakan tanda kutip:
for i in * ; do cp "$i" "/some/path/$i.bak" ; done
Dilakukan dengan baik? tidak! Bagaimana jika tidak ada apa pun di direktori, mis. Globbing tidak akan berhasil.
find . -type f -exec mv -v {} dst/{}.bak \;
Sekarang dilakukan dengan baik? not ... Lupa bahwa nama file mungkin \n
.
touch x mv x "$(printf "foo\nbar")" find . -type f -print0 | xargs -0 mv -t /path/to/target-dir
Masalah dari langkah sebelumnya bisa ditangkap ketika kita lupa tanda kutip, karena ini di alam ada banyak alat Shellcheck , ada banyak dari mereka, dan kemungkinan besar Anda dapat menemukan liner untuk tumpukan Anda di bawah IDE Anda.
Pengujian IaC: Tes Unit

Seperti yang kita lihat dari contoh sebelumnya, linter tidak mahakuasa dan tidak dapat menunjuk ke semua area masalah. Selanjutnya, dengan analogi dengan pengujian dalam pengembangan perangkat lunak, kita dapat memanggil unit test. Kemudian shunit , junit , rspec , pytest segera terlintas dalam pikiran. Tapi apa yang harus dilakukan dengan ansible, chef, saltstack dan yang lainnya seperti mereka?
Pada awalnya, kami berbicara tentang SOLID dan fakta bahwa infrastruktur kami harus terdiri dari batu bata kecil. Waktunya telah tiba.
- Infrastruktur dihancurkan menjadi batu bata kecil, misalnya, peran yang dimungkinkan.
- Beberapa jenis lingkungan sedang berlangsung, baik itu buruh pelabuhan atau VM.
- Kami menerapkan peran Ansible kami ke lingkungan pengujian ini.
- Kami memeriksa bahwa semuanya berfungsi seperti yang kami harapkan (jalankan tes).
- Kami memutuskan ok atau tidak ok.
Pertanyaannya adalah, apa tes untuk CFM? Anda dapat menjalankan skrip klise, atau Anda dapat menggunakan solusi yang sudah jadi untuk ini:
Contoh untuk testinfra, kami memverifikasi bahwa pengguna test1
, test2
ada dan berada di grup sshusers
:
def test_default_users(host): users = ['test1', 'test2' ] for login in users: assert host.user(login).exists assert 'sshusers' in host.user(login).groups
Apa yang harus dipilih? Pertanyaannya kompleks dan ambigu, berikut adalah contoh perubahan dalam proyek-proyek di github untuk 2018-2019:

Kerangka Pengujian IaC
Ada cara menyatukan dan menjalankannya? Anda dapat mengambil dan melakukan semuanya sendiri jika Anda memiliki jumlah insinyur yang memadai. Dan Anda dapat mengambil solusi yang sudah jadi, meskipun tidak terlalu banyak:
Contoh perubahan proyek pada github untuk 2018-2019:

Molekul vs Testkitchen

Awalnya, kami mencoba menggunakan testkitchen :
- Buat VM secara paralel.
- Terapkan Peran yang Mungkin.
- Usir inspec.
Untuk 25-35 peran, ini bekerja selama 40-70 menit, yang merupakan waktu yang lama.

Langkah selanjutnya adalah beralih ke jenkins / docker / ansible / molekul. Secara idiologis, semuanya sama
- Buku pedoman serat
- Untuk menumpahkan peran.
- Jalankan kontainer
- Terapkan Peran yang Mungkin.
- Usir testinfra.
- Periksa idempotensi.

Penguasa untuk 40 peran dan tes untuk selusin mulai memakan waktu sekitar 15 menit.

Apa yang harus dipilih tergantung pada banyak faktor, seperti tumpukan yang digunakan, keahlian dalam tim, dll. di sini setiap orang memutuskan cara menutup masalah pengujian Unit
Pengujian IaC: Tes Integrasi

Pada tahap berikutnya dari piramida pengujian infrastruktur, tes integrasi akan muncul. Mereka mirip dengan tes Unit:
- Infrastruktur dihancurkan menjadi batu bata kecil, seperti peran Ansible.
- Beberapa jenis lingkungan sedang berlangsung, baik itu buruh pelabuhan atau VM.
- Ada banyak peran yang mungkin diterapkan pada lingkungan pengujian ini.
- Kami memeriksa bahwa semuanya berfungsi seperti yang kami harapkan (jalankan tes).
- Kami memutuskan ok atau tidak ok.
Secara kasar, kami tidak memeriksa operabilitas elemen individu dari sistem seperti dalam pengujian unit, kami memeriksa bagaimana server dikonfigurasi secara keseluruhan.
Pengujian IaC: Tes ujung ke ujung

Di puncak piramida kita bertemu dengan tes ujung ke ujung. Yaitu kami tidak memeriksa operasi server yang terpisah, skrip yang terpisah, dan infrastruktur kami yang terpisah. Kami memeriksa bahwa banyak server digabungkan bersama, infrastruktur kami berfungsi seperti yang kami harapkan. Sayangnya, saya tidak melihat solusi kotak yang siap pakai, mungkin karena infrastruktur sering kali unik dan sulit untuk di-templat dan membuat kerangka kerja untuk mengujinya. Akibatnya, semua orang menciptakan solusi mereka sendiri. Ada permintaan, tetapi tidak ada jawaban. Oleh karena itu, saya akan memberi tahu Anda apa yang ada di sana untuk mendorong orang lain untuk menyuarakan pemikiran atau menyodok hidung saya, bahwa semuanya diciptakan jauh sebelum kita.

Sebuah proyek dengan sejarah yang kaya. Digunakan di organisasi besar dan mungkin Anda masing-masing secara tidak langsung berpotongan. Aplikasi ini mendukung banyak basis data, integrasi, dll., Dll. Mengetahui bagaimana infrastruktur bisa terlihat seperti ini adalah banyak file-file docker-compose, dan mengetahui tes mana yang harus dijalankan di mana jenkins berada.

Skema ini bekerja untuk waktu yang lama, sampai sebagai bagian dari penelitian kami mencoba mentransfernya ke Openshift. Kontainer tetap sama, tetapi lingkungan peluncuran telah berubah (halo KERING lagi).

Ide penelitian melangkah lebih jauh, dan dalam openhift ada hal APB (Ansible Playbook Bundle) yang memungkinkan Anda untuk mengemas pengetahuan dalam wadah bagaimana menggunakan infrastruktur. Yaitu Ada pengetahuan yang dapat direproduksi dan dapat diuji tentang cara menggunakan infrastruktur.

Semua ini terdengar bagus, sampai kami membenamkan diri dalam infrastruktur yang heterogen: kami membutuhkan Windows untuk tes. Akibatnya, pengetahuan tentang di mana akan digunakan dan diuji ada di jenkins.
Kesimpulan

Infrastruktur sebagai Kode
- Kode dalam repositori.
- Interaksi orang.
- Pengujian infrastruktur.