Pendekatan sistem terhadap variabel di Ansible

kemungkinan gaya kode devops

Hai! Nama saya adalah Denis Kalyuzhny Saya bekerja sebagai insinyur di departemen otomasi proses pengembangan. Setiap hari, pembuatan aplikasi baru diluncurkan di ratusan server kampanye. Dan pada artikel kali ini saya membagikan pengalaman saya menggunakan Ansible untuk tujuan tersebut.

Panduan ini menawarkan cara untuk mengatur variabel dalam penerapan. Panduan ini ditujukan bagi mereka yang telah menggunakan peran dalam buku pedomannya dan telah membaca Praktik terbaik, tetapi menghadapi masalah serupa:

  • Setelah menemukan variabel dalam kode, tidak mungkin untuk segera memahami apa yang menjadi tanggung jawabnya;
  • Ada beberapa peran, dan variabelnya perlu dikaitkan dengan satu nilai, tetapi itu tidak berhasil;
  • Mengalami kesulitan menjelaskan kepada orang lain bagaimana logika variabel dalam buku pedoman Anda bekerja

Kami mengalami masalah ini pada proyek-proyek di perusahaan kami, sebagai akibatnya kami sampai pada aturan untuk merancang variabel dalam buku pedoman kami, yang sampai batas tertentu memecahkan masalah ini.

Pendekatan sistem terhadap variabel di Ansible

Variabel dalam peran

Peran adalah Objek terpisah dari sistem penerapan. Seperti objek sistem lainnya, objek tersebut harus memiliki antarmuka untuk berinteraksi dengan seluruh sistem. Antarmuka seperti itu adalah variabel peran.

Mari kita ambil contoh, peran tersebut api, yang menginstal aplikasi Java di server. Variabel apa yang mungkin dimilikinya?

Pendekatan sistem terhadap variabel di Ansible

Peran variabel dapat dibagi menjadi 2 jenis menurut jenisnya:

1. Свойства
    a) независимые от среды
    б) зависимые от среды
2. Связи
    a) слушатели 
    б) запросы внутри системы
    в) запросы в среду

Properti variabel adalah variabel yang menentukan perilaku suatu peran.

Variabel Kueri - ini adalah variabel yang nilainya digunakan untuk menunjuk sumber daya di luar peran tersebut.

Pendengar variabel - ini adalah variabel yang nilainya digunakan untuk membentuk variabel permintaan.

Di sisi lain, 1a, 2a, 2b adalah variabel yang tidak bergantung pada lingkungan (perangkat keras, sumber daya eksternal, dll.) dan dapat diisi dengan nilai default pada peran default. Namun, tidak mungkin untuk mengisi variabel tipe 1.b dan 2.c dengan nilai selain 'contoh', karena variabel tersebut akan berubah dari satu stand ke stand lainnya tergantung pada lingkungan.

Gaya kode

  • Nama variabel harus diawali dengan nama peran. Hal ini akan memudahkan untuk mengetahui di masa depan apa peran variabel tersebut dan apa tanggung jawabnya.
  • Saat menggunakan variabel dalam peran, Anda harus mengikuti prinsip enkapsulasi dan menggunakan variabel yang ditentukan baik dalam peran itu sendiri atau dalam peran yang bergantung pada peran saat ini.
  • Hindari menggunakan kamus untuk variabel. Ansible tidak mengizinkan Anda dengan mudah mengganti nilai individual dalam kamus.

    Contoh variabel buruk:

    myrole_user:
        login: admin
        password: admin

    Di sini login adalah variabel independen, dan password adalah variabel dependen. Tetapi
    karena digabungkan ke dalam kamus, Anda harus menentukannya secara lengkap
    Selalu. Itu sangat merepotkan. Lebih baik begini:

    myrole_user_login: admin
    myrole_user_password: admin

Variabel dalam buku pedoman penerapan

Saat menyusun buku pedoman penerapan (selanjutnya disebut sebagai buku pedoman), kami mematuhi aturan bahwa buku pedoman tersebut harus ditempatkan di repositori terpisah. Sama dengan peran: masing-masing dalam repositori gitnya sendiri. Hal ini memungkinkan Anda memahami bahwa peran dan pedoman adalah objek independen yang berbeda dari sistem penerapan, dan perubahan pada satu objek tidak boleh memengaruhi pengoperasian objek lainnya. Hal ini dicapai dengan mengubah nilai default variabel.

Saat menyusun buku pedoman, untuk meringkas, dimungkinkan untuk mengganti nilai default variabel peran di dua tempat: di variabel buku pedoman dan di variabel inventaris.

mydeploy                        # Каталог деплоя
├── deploy.yml                  # Плейбук деплоя
├── group_vars                  # Каталог переменных плейбука
│   ├── all.yml                 # Файл для переменных связи всей системы
│   └── myapi.yml               # Файл переменных свойств группы myapi
└── inventories                 #
    └── prod                    # Каталог окружения prod
        ├── prod.ini            # Инвентори файл
        └── group_vars          # Каталог для переменных инвентори
            └── myapi           #
                ├── vars.yml    # Средозависимые переменные группы myapi
                └── vault.yml   # Секреты (всегда средозависимы) *

* - Variabel dan Vault

Perbedaannya adalah variabel playbook selalu digunakan saat memanggil playbook yang terletak pada level yang sama dengannya. Artinya, variabel-variabel ini bagus untuk mengubah nilai default variabel yang tidak bergantung pada lingkungan. Sebaliknya, variabel inventaris hanya akan digunakan untuk lingkungan tertentu, yang ideal untuk variabel lingkungan tertentu.

Penting untuk dicatat bahwa prioritas variabel tidak akan memungkinkan Anda untuk mengganti variabel terlebih dahulu dalam variabel pedoman dan kemudian secara terpisah dalam satu inventaris.

Artinya sudah pada tahap ini perlu diputuskan apakah variabel tersebut bergantung pada lingkungan atau tidak dan menempatkannya pada tempat yang tepat.

Misalnya, dalam satu proyek, variabel yang bertanggung jawab untuk mengaktifkan SSL bergantung pada lingkungan untuk waktu yang lama, karena kami tidak dapat mengaktifkan SSL karena alasan di luar kendali kami di salah satu stand. Setelah kami memperbaiki masalah ini, masalah ini menjadi tidak bergantung pada lingkungan dan dipindahkan ke variabel pedoman.

Variabel Properti untuk Grup

Mari kita perluas model kita pada Gambar 1 dengan menambahkan 2 grup server dengan aplikasi Java berbeda, namun dengan pengaturan berbeda.

Pendekatan sistem terhadap variabel di Ansible

Mari kita bayangkan seperti apa pedomannya dalam kasus ini:

- hosts: myapi
  roles:
    - api

- hosts: bbauth
  roles:
    - auth

- hosts: ghauth
  roles:
    - auth

Kami memiliki tiga grup di buku pedoman, jadi disarankan untuk segera membuat jumlah file grup yang sama dalam variabel inventaris group_vars dan variabel pedoman. Satu file grup dalam hal ini adalah deskripsi salah satu komponen aplikasi di atas dalam playbook. Saat Anda membuka file grup di variabel playbook, Anda segera melihat semua perbedaan dari perilaku default peran yang diinstal pada grup. Dalam variabel inventaris: perbedaan perilaku kelompok dari stand ke stand.

Gaya Kode

  • Usahakan untuk tidak menggunakan variabel host_vars sama sekali, karena tidak menggambarkan sistem, melainkan hanya kasus khusus, yang nantinya akan menimbulkan pertanyaan: “Mengapa host ini berbeda dari yang lain?”, yang jawabannya tidak selalu mudah ditemukan.

Variabel Komunikasi

Namun, itulah yang dimaksud dengan variabel properti, tapi bagaimana dengan variabel komunikasi?
Perbedaannya adalah bahwa mereka harus memiliki arti yang sama dalam kelompok yang berbeda.

Pada awalnya memang begitu ide itu gunakan konstruksi mengerikan seperti:
hostvars[groups['bbauth'][0]]['auth_bind_port'], tapi mereka langsung menolaknya
karena mempunyai kelemahan. Pertama, besarnya. Kedua, ketergantungan pada host tertentu dalam kelompok. Ketiga, sebelum memulai penerapan, perlu mengumpulkan fakta dari semua host jika kita tidak ingin mendapatkan kesalahan variabel yang tidak ditentukan.

Oleh karena itu, diputuskan untuk menggunakan variabel komunikasi.

Variabel Komunikasi - ini adalah variabel milik pedoman dan diperlukan untuk menghubungkan objek sistem.

Variabel komunikasi diisi dalam variabel sistem umum group_vars/all/vars dan dibentuk dengan menghapus semua variabel pendengar dari setiap grup, dan menambahkan nama grup dari mana pendengarnya dihapus ke awal variabel.

Hal ini memastikan keseragaman dan tidak tumpang tindihnya nama.

Mari kita coba mengikat variabel dari contoh di atas:

Pendekatan sistem terhadap variabel di Ansible

Bayangkan kita memiliki variabel yang bergantung satu sama lain:

# roles/api/defaults:
# Переменная запроса
api_auth1_address: "http://example.com:80"
api_auth2_address: "http://example2.com:80"

# roles/auth/defaults:
# Переменная слушатель
auth_bind_port: "20000"

Mari kita masukkan ke dalam variabel umum group_vars/all/vars semua pendengar, dan tambahkan nama grup ke judul:

# group_vars/all/vars
bbauth_auth_bind_port: "20000"
ghauth_auth_bind_port: "30000"

# group_vars/bbauth/vars
auth_bind_port: "{{ bbauth_auth_bind_port }}"

# group_vars/ghauth/vars
auth_bind_port: "{{ ghauth_auth_bind_port }}"

# group_vars/myapi/vars
api_auth1_address: "http://{{ bbauth_auth_service_name }}:{{ bbauth_auth_bind_port }}"
api_auth2_address: "http://{{ ghauth_auth_service_name }}:{{ ghauth_auth_bind_port }}"

Sekarang, dengan mengubah nilai konektor, kami akan yakin bahwa permintaan akan diarahkan ke tempat yang sama di mana port tersebut berada.

Gaya Kode

  • Karena peran dan grup adalah objek sistem yang berbeda, maka keduanya harus memiliki nama yang berbeda, maka variabel tautan akan secara akurat menunjukkan bahwa peran dan grup tersebut milik grup server tertentu, dan bukan peran dalam sistem.

File yang bergantung pada lingkungan

Peran dapat menggunakan file yang berbeda dari satu lingkungan ke lingkungan lainnya.

Contoh file tersebut adalah sertifikat SSL. Simpan dalam bentuk teks
dalam suatu variabel sangat tidak nyaman. Tetapi akan lebih mudah untuk menyimpan jalur ke sana di dalam sebuah variabel.

Misalnya kita menggunakan variabel api_ssl_key_file: "/path/to/file".

Karena jelas bahwa sertifikat kunci akan berubah dari satu lingkungan ke lingkungan lain, ini adalah variabel yang bergantung pada lingkungan, yang berarti sertifikat tersebut harus ditempatkan di file
group_vars/myapi/vars inventarisasi variabel, dan berisi nilai 'misalnya'.

Cara paling mudah dalam hal ini adalah dengan meletakkan file kunci di repositori playbook di sepanjang jalur
files/prod/certs/myapi.key, maka nilai variabelnya adalah:
api_ssl_key_file: "prod/certs/myapi.key". Kenyamanannya terletak pada kenyataan bahwa orang-orang yang bertanggung jawab untuk menerapkan sistem pada stand tertentu juga memiliki ruang khusus di repositori untuk menyimpan file mereka. Pada saat yang sama, jalur absolut ke sertifikat tetap dapat ditentukan di server, jika sertifikat disediakan oleh sistem lain.

Beberapa stand dalam satu lingkungan

Seringkali ada kebutuhan untuk menyebarkan beberapa stand yang hampir identik di lingkungan yang sama dengan perbedaan yang minimal. Dalam hal ini, kami membagi variabel yang bergantung pada lingkungan menjadi variabel yang tidak berubah dalam lingkungan tertentu dan variabel yang berubah. Dan kami mentransfer yang terakhir langsung ke file inventaris itu sendiri. Setelah manipulasi ini, dimungkinkan untuk membuat inventaris lain langsung di direktori lingkungan.

Ini akan menggunakan kembali inventaris group_vars, dan juga akan dapat mendefinisikan ulang beberapa variabel secara langsung untuk dirinya sendiri.

Struktur direktori akhir untuk proyek penerapan:

mydeploy                        # Каталог деплоя
├── deploy.yml                  # Плейбук деплоя
├── files                       # Каталог для файлов деплоя
│   ├── prod                    # Католог для средозависимых файлов стенда prod
│   │   └── certs               # 
│   │       └── myapi.key       #
│   └── test1                   # Каталог для средозависимых файлов стенда test1
├── group_vars                  # Каталог переменных плейбука
│   ├── all.yml                 # Файл для переменных связи всей системы
│   ├── myapi.yml               # Файл переменных свойств группы myapi
│   ├── bbauth.yml              # 
│   └── ghauth.yml              #
└── inventories                 #
    ├── prod                    # Каталог окружения prod
    │   ├── group_vars          # Каталог для переменных инвентори
    │   │   ├── myapi           #
    │   │   │   ├── vars.yml    # Средозависимые переменные группы myapi
    │   │   │   └── vault.yml   # Секреты (всегда средозависимы)
    │   │   ├── bbauth          # 
    │   │   │   ├── vars.yml    #
    │   │   │   └── vault.yml   #
    │   │   └── ghauth          #
    │   │       ├── vars.yml    #
    │   │       └── vault.yml   #
    │   └── prod.ini            # Инвентори стенда prod
    └── test                    # Каталог окружения test
        ├── group_vars          #
        │   ├── myapi           #
        │   │   ├── vars.yml    #
        │   │   └── vault.yml   #
        │   ├── bbauth          #
        │   │   ├── vars.yml    #
        │   │   └── vault.yml   #
        │   └── ghauth          #
        │       ├── vars.yml    #
        │       └── vault.yml   #
        ├── test1.ini           # Инвентори стенда test1 в среде test
        └── test2.ini           # Инвентори стенда test2 в среде test

Menyimpulkan

Setelah mengatur variabel sesuai dengan artikel: setiap file variabel bertanggung jawab untuk tugas tertentu. Dan karena file tersebut memiliki tugas tertentu, menjadi mungkin untuk menugaskan seseorang yang bertanggung jawab atas kebenaran setiap file. Misalnya, pengembang penerapan sistem bertanggung jawab atas pengisian variabel pedoman dengan benar, sedangkan administrator yang pendiriannya dijelaskan dalam inventaris bertanggung jawab langsung untuk mengisi inventaris variabel.

Peran menjadi unit pengembangannya sendiri dengan antarmukanya sendiri, sehingga pengembang peran dapat mengembangkan kemampuan, bukan menyesuaikan peran dengan sistem. Masalah ini khususnya menyangkut peran umum semua sistem dalam kampanye.

Administrator sistem tidak perlu lagi memahami kode penerapan. Semua yang diperlukan dari mereka agar penerapan berhasil adalah mengisi file variabel yang bergantung pada lingkungan.

Literatur

  1. Документация

Penulis

Kalyuzhny Denis Alexandrovich

Sumber: www.habr.com

Tambah komentar