Membuat struktur Deployment Manager untuk digunakan dalam skala besar

Jika sistem "Infrastructure as code" Anda berkembang melampaui contoh "Hello World" tanpa perencanaan, kode cenderung menjadi tidak terstruktur. Konfigurasi yang tidak direncanakan dikodekan secara permanen. Kemudahan pemeliharaan menurun drastis.

Gunakan dokumen ini untuk menyusun deployment Anda secara lebih efisien dan dalam skala besar.

Selain itu, terapkan konvensi penamaan dan praktik terbaik internal di seluruh tim Anda. Dokumen ini ditujukan untuk audiens yang memiliki pengetahuan teknis tingkat lanjut, dan mengasumsikan bahwa Anda memiliki pemahaman dasar tentang Python, Google Cloudinfrastruktur, Deployment Manager, dan, secara umum, infrastruktur sebagai kode.

Sebelum memulai

  • Jika Anda ingin menggunakan contoh command line dalam panduan ini, instal alat command line`gcloud`.
  • Jika Anda ingin menggunakan contoh API dalam panduan ini, siapkan akses API.

Beberapa lingkungan dengan satu codebase

Untuk deployment besar dengan lebih dari selusin resource, praktik terbaik standar mengharuskan Anda menggunakan sejumlah besar properti eksternal (parameter konfigurasi), sehingga Anda dapat menghindari string dan logika hardcode ke template generik. Banyak properti ini diduplikasi sebagian karena lingkungan yang serupa, seperti lingkungan pengembangan, pengujian, atau produksi, dan layanan yang serupa. Misalnya, semua layanan standar berjalan di stack LAMP yang serupa. Mengikuti praktik terbaik ini akan menghasilkan sekumpulan besar properti konfigurasi dengan duplikasi yang tinggi sehingga sulit dikelola, dan meningkatkan kemungkinan terjadinya kesalahan manusia.

Tabel berikut adalah contoh kode untuk mengilustrasikan perbedaan antara hierarki versus konfigurasi tunggal per deployment. Tabel ini menandai duplikasi umum dalam satu konfigurasi. Dengan menggunakan konfigurasi hierarkis, tabel menunjukkan cara memindahkan bagian yang berulang ke tingkat yang lebih tinggi dalam hierarki untuk menghindari pengulangan dan mengurangi kemungkinan kesalahan manusia.

Template Konfigurasi hierarkis tanpa redundansi Konfigurasi tunggal dengan redundansi

project_config.py

config = { 'ProjectId': 'qwerty123456', 'ProjectOwner': 'Bob', 'ProjectAbbrevation': 'SNP' }

T/A

frontend_config.py

config = {'ServiceName': 'frontend'}

config = { 'ProjectId': 'qwerty123456', 'ProjectOwner': 'Bob', 'ProjectAbbrevation': 'SNP', 'ServiceName': 'frontend' }

backend_config.py

config = {'ServiceName': 'backend'}

config = { 'ProjectId': 'qwerty123456', 'ProjectOwner': 'Bob', 'ProjectAbbrevation': 'SNP', 'ServiceName': 'backend' }

db_config.py

config = {'ServiceName': 'db'}

config = { 'ProjectId': 'qwerty123456', 'ProjectOwner': 'Bob', 'ProjectAbbrevation': 'SNP', 'ServiceName': 'db' }

Untuk menangani codebase besar dengan lebih baik, gunakan tata letak hierarkis terstruktur dengan penggabungan properti konfigurasi berjenjang. Untuk melakukannya, Anda menggunakan beberapa file untuk konfigurasi, bukan hanya satu. Selain itu, Anda akan bekerja dengan fungsi pembantu dan membagikan sebagian codebase di seluruh organisasi Anda.

Menyusun dan mengalirkan kode Anda secara hierarkis memberikan beberapa manfaat:

  • Saat memisahkan konfigurasi menjadi beberapa file, Anda meningkatkan struktur dan keterbacaan properti. Anda juga menghindari duplikasinya.
  • Anda mendesain penggabungan hierarkis untuk mengalirkan nilai secara logis, membuat file konfigurasi tingkat atas yang dapat digunakan kembali di seluruh project atau komponen.
  • Anda hanya menentukan setiap properti satu kali (selain penimpaan), sehingga tidak perlu menangani namespace dalam nama properti.
  • Template Anda tidak perlu mengetahui lingkungan sebenarnya, karena konfigurasi yang sesuai dimuat berdasarkan variabel yang sesuai.

Menyusun codebase Anda secara hierarkis

Deployment Deployment Manager berisi konfigurasi YAML atau file skema, beserta beberapa file Python. Bersama-sama, file ini membentuk basis kode deployment. File Python dapat digunakan untuk berbagai tujuan. Anda dapat menggunakan file Python sebagai template deployment, sebagai file kode umum (class pembantu), atau sebagai file kode yang menyimpan properti konfigurasi.

Untuk menyusun codebase secara hierarkis, Anda menggunakan beberapa file Python sebagai file konfigurasi, bukan file konfigurasi standar. Pendekatan ini memberi Anda fleksibilitas yang lebih besar daripada menautkan deployment ke satu file YAML.

Memperlakukan infrastruktur Anda sebagai kode nyata

Prinsip penting untuk kode bersih adalah Jangan Mengulangi Diri Sendiri (DRY)). Tentukan semuanya hanya sekali. Pendekatan ini membuat codebase lebih rapi, lebih mudah ditinjau dan divalidasi, serta lebih mudah dikelola. Jika properti hanya perlu diubah di satu tempat, risiko kesalahan manusia akan berkurang.

Untuk codebase yang lebih ringan dengan file konfigurasi yang lebih kecil dan duplikasi minimal, gunakan panduan ini untuk menyusun konfigurasi Anda agar mengikuti prinsip DRY.

Organisasi, departemen, lingkungan, dan modul

Prinsip dasar untuk menyusun codebase Anda secara bersih dan hierarkis adalah dengan menggunakan organisasi, departemen, lingkungan, dan modul. Prinsip ini bersifat opsional dan dapat diperluas. Untuk diagram hierarki contoh codebase, yang mengikuti prinsip-prinsip ini, lihat hierarki konfigurasi.

Dalam diagram berikut, modul di-deploy di lingkungan. Penggabung konfigurasi memilih file konfigurasi yang sesuai di setiap level berdasarkan konteks tempat file tersebut digunakan. Kolom ini juga otomatis menentukan sistem dan departemen.

Modul yang di-deploy dalam lingkungan

Dalam daftar berikut, angka mewakili urutan penimpaan:

  1. Properti organisasi

    Ini adalah tingkat tertinggi dalam struktur Anda. Di tingkat ini, Anda dapat menyimpan properti konfigurasi seperti organization_name, organization_abbreviation, yang Anda gunakan dalam konvensi penamaan, dan fungsi pembantu yang ingin Anda bagikan dan terapkan di semua tim.

  2. Properti departemen

    Organisasi berisi departemen, jika Anda memiliki departemen dalam struktur Anda. Dalam file konfigurasi setiap departemen, bagikan properti yang tidak digunakan oleh departemen lain, misalnya, department_name atau cost_center.

  3. Properti sistem (project)

    Setiap departemen berisi sistem. Sistem adalah stack software yang terdefinisi dengan baik, misalnya, platform e-commerce Anda. Ini bukan project Google Cloud , melainkan ekosistem layanan yang berfungsi.

    Di tingkat sistem, tim Anda memiliki lebih banyak otonomi daripada di tingkat di atasnya. Di sini, Anda dapat menentukan fungsi helper (seperti project_name_generator(), instance_name_generator(), atau instance_label_generator()) untuk parameter di seluruh tim dan sistem (misalnya, system_name, default_instance_size, atau naming_prefix).

  4. Properti lingkungan

    Sistem Anda kemungkinan memiliki beberapa lingkungan, seperti Dev, Test, atau Prod (dan, secara opsional, QA dan Staging), yang cukup mirip satu sama lain. Idealnya, keduanya menggunakan codebase yang sama, dan hanya berbeda di tingkat konfigurasi. Di tingkat lingkungan, Anda dapat mengganti properti seperti default_instance_size untuk konfigurasi Prod dan QA.

  5. Properti Modul

    Jika sistem Anda besar, bagi menjadi beberapa modul, bukan menjadikannya satu blok monolitik besar. Misalnya, Anda dapat memindahkan jaringan dan keamanan inti ke dalam blok terpisah. Anda juga dapat memisahkan lapisan backend, frontend, dan database ke dalam modul terpisah. Modul adalah template yang dikembangkan oleh pihak ketiga, yang hanya menambahkan konfigurasi yang sesuai. Di tingkat modul, Anda dapat menentukan properti yang hanya relevan untuk modul tertentu, termasuk properti yang dirancang untuk menggantikan properti tingkat sistem yang diwarisi. Tingkat lingkungan dan modul adalah pembagian paralel dalam sistem, tetapi modul mengikuti lingkungan dalam proses penggabungan.

  6. Properti modul khusus lingkungan

    Beberapa properti modul Anda juga mungkin bergantung pada lingkungan, misalnya, ukuran instance, gambar, endpoint. Properti modul khusus lingkungan adalah tingkat yang paling spesifik, dan titik terakhir dalam penggabungan berjenjang untuk menggantikan nilai yang ditentukan sebelumnya.

Class helper untuk menggabungkan konfigurasi

Class config_merger adalah class helper yang otomatis memuat file konfigurasi yang sesuai dan menggabungkan kontennya ke dalam satu kamus.

Untuk menggunakan class config_merger, Anda harus memberikan informasi berikut:

  • Nama modul.
  • Konteks global, yang berisi nama lingkungan.

Memanggil fungsi statis ConfigContext akan menampilkan kamus konfigurasi yang digabungkan.

Kode berikut menunjukkan cara menggunakan class ini:

  • module = "frontend" menentukan konteks, yang memuat file properti.
  • Lingkungan akan otomatis dipilih dari context.properties["envName"].
  • Konfigurasi global.

    cc = config_merger.ConfigContext(context.properties, module)
    
    print cc.configs['ServiceName']
    

Di balik layar, class helper ini harus selaras dengan struktur konfigurasi Anda, memuat semua level dalam urutan yang benar, dan mengganti nilai konfigurasi yang sesuai. Untuk mengubah level atau urutan penimpaan, Anda mengubah class penggabungan konfigurasi.

Dalam penggunaan sehari-hari dan rutin, Anda biasanya tidak perlu menyentuh class ini. Biasanya, Anda mengedit template dan file konfigurasi yang sesuai, lalu menggunakan kamus output dengan semua konfigurasi di dalamnya.

Contoh codebase berisi tiga file konfigurasi hardcode berikut:

  • org_config.py
  • department_config.py
  • system_config.py

Anda dapat membuat file konfigurasi organisasi dan departemen sebagai link simbolis selama inisiasi repositori. File ini dapat berada di repositori kode terpisah, karena secara logis bukan bagian dari codebase tim project, tetapi dibagikan ke seluruh organisasi dan departemen.

Penggabungan konfigurasi juga mencari file yang cocok dengan tingkat struktur yang tersisa:

  • envs/[environment name].py
  • [environment name]/[module name].py
  • modules/[module name].py

File konfigurasi

Deployment Manager menggunakan satu file konfigurasi, yang merupakan satu file untuk deployment tertentu. Tidak dapat dibagikan di seluruh deployment.

Saat Anda menggunakan class config-merger, properti konfigurasi akan sepenuhnya terlepas dari file konfigurasi ini karena Anda tidak menggunakannya. Sebagai gantinya, Anda menggunakan kumpulan file Python, yang memberi Anda lebih banyak fleksibilitas dalam deployment. File ini juga dapat dibagikan di seluruh deployment.

File Python apa pun dapat berisi variabel, yang memungkinkan Anda menyimpan konfigurasi secara terstruktur, tetapi terdistribusi. Pendekatan terbaik adalah menggunakan kamus dengan struktur yang disepakati. Penggabung konfigurasi mencari kamus bernama configs di setiap file dalam rantai penggabungan. configs terpisah tersebut digabungkan menjadi satu.

Selama penggabungan, jika properti dengan jalur dan nama yang sama muncul di kamus beberapa kali, penggabungan konfigurasi akan menggantikan properti tersebut. Dalam beberapa kasus, perilaku ini berguna, seperti saat nilai default diganti dengan nilai khusus konteks. Namun, ada banyak kasus lain di mana Anda ingin menghindari penimpaan properti. Untuk mencegah penimpaan properti, tambahkan namespace terpisah ke properti tersebut agar menjadi unik. Dalam contoh berikut, Anda menambahkan namespace dengan membuat tingkat tambahan dalam kamus konfigurasi, yang membuat subkamus.

config = {
    'Zip_code': '1234'
    'Count': '3'
    'project_module': {
        'admin': 'Joe',
    }
}

config = {
    'Zip_code': '5555'
    'Count': '5'
    'project_module_prod': {
        'admin': 'Steve',
    }
}

Class helper dan konvensi penamaan

Konvensi penamaan adalah cara terbaik untuk menjaga infrastruktur Deployment Manager Anda tetap terkontrol. Anda tidak boleh menggunakan nama yang tidak jelas atau generik, seperti my project atau test instance.

Contoh berikut adalah konvensi penamaan di seluruh organisasi untuk instance:

def getInstanceName(self, name):
  return '-'.join(self.configs['Org_level_configs']['Org_Short_Name'],
                  self.configs['Department_level_configs']['Department_Short_Name'],
                  self.configs['System_short_name'],
                  name,
                  self.configs["envName"])

Menyediakan fungsi bantuan memudahkan penamaan setiap instance berdasarkan konvensi yang disepakati. Hal ini juga mempermudah peninjauan kode karena tidak ada nama instance yang berasal dari tempat lain selain fungsi ini. Fungsi ini otomatis mengambil nama dari konfigurasi tingkat yang lebih tinggi. Pendekatan ini membantu menghindari input yang tidak perlu.

Anda dapat menerapkan konvensi penamaan ini ke sebagian besar resource Google Cloud dan untuk label. Fungsi yang lebih kompleks bahkan dapat menghasilkan serangkaian label default.

Struktur folder contoh codebase

Struktur folder codebase contoh bersifat fleksibel dan dapat disesuaikan. Namun, sebagiannya dikodekan secara permanen ke penggabungan konfigurasi dan file skema Deployment Manager, yang berarti bahwa jika Anda melakukan modifikasi, Anda harus mencerminkan perubahan tersebut dalam penggabungan konfigurasi dan file skema.

├── global
│   ├── configs
│   └── helper
└── systems
    └── my_ecom_system
        ├── configs
        │   ├── dev
        │   ├── envs
        │   ├── modules
        │   ├── prod
        │   └── test
        ├── helper
        └── templates
    

Folder global berisi file yang dibagikan di berbagai tim project. Untuk mempermudah, folder konfigurasi berisi konfigurasi organisasi dan semua file konfigurasi departemen. Dalam contoh ini, tidak ada class helper terpisah untuk departemen. Anda dapat menambahkan class helper apa pun di tingkat organisasi atau sistem.

Folder global dapat berada di repositori Git terpisah. Anda dapat mereferensikan filenya dari masing-masing sistem. Anda juga dapat menggunakan link simbolik, tetapi link tersebut dapat menimbulkan kebingungan atau gangguan di sistem operasi tertentu.

├── configs
│   ├── Department_Data_config.py
│   ├── Department_Finance_config.py
│   ├── Department_RandD_config.py
│   └── org_config.py
└── helper
    ├── config_merger.py
    └── naming_helper.py

Folder sistem berisi satu atau beberapa sistem yang berbeda. Sistem dipisahkan satu sama lain dan tidak berbagi konfigurasi.

├── configs
│   ├── dev
│   ├── envs
│   ├── modules
│   ├── prod
│   └── test
├── helper
└── templates

Folder konfigurasi berisi semua file konfigurasi yang unik untuk sistem ini, juga mereferensikan konfigurasi global dengan link simbolis.

├── department_config.py -> ../../../global/configs/Department_Data_config.py
├── org_config.py -> ../../../global/configs/org_config.py
├── system_config.py
├── dev
│   ├── frontend.py
│   └── project.py
├── prod
│   ├── frontend.py
│   └── project.py
├── test
│   ├── frontend.py
│   └── project.py
├── envs
│   ├── dev.py
│   ├── prod.py
│   └── test.py
└── modules
    ├── frontend.py
    └── project.py

Org_config.py:

config = {
  'Org_level_configs': {
    'Org_Name': 'Sample Inc.',
    'Org_Short_Name': 'sampl',
    'HQ_Address': {
      'City': 'London',
      'Country': 'UK'
    }
  }
}

Di folder helper, Anda dapat menambahkan class helper lebih lanjut dan mereferensikan class global.

├── config_merger.py -> ../../../global/helper/config_merger.py
└── naming_helper.py -> ../../../global/helper/naming_helper.py

Di folder template, Anda dapat menyimpan atau mereferensikan template Deployment Manager. Link simbolis juga berfungsi di sini.

├── project_creation -> ../../../../../../examples/v2/project_creation
└── simple_frontend.py

Praktik terbaik

Praktik terbaik berikut dapat membantu Anda menyusun kode secara hierarkis.

File skema

Dalam file skema, Deployment Manager mewajibkan Anda mencantumkan setiap file yang Anda gunakan dengan cara apa pun selama deployment. Menambahkan seluruh folder membuat kode Anda lebih pendek dan lebih generik.

  • Class helper:
- path: helper/*.py
  • File konfigurasi:
- path: configs/*.py
- path: configs/*/*.py
  • Impor massal (gaya glob)
gcloud config set deployment_manager/glob_imports True

Beberapa deployment

Praktik terbaik untuk sistem adalah berisi beberapa deployment, yang berarti sistem tersebut menggunakan set konfigurasi yang sama, meskipun berupa modul yang berbeda, misalnya, jaringan, firewall, backend, frontend. Anda mungkin perlu mengakses output penerapan ini dari penerapan lain. Anda dapat membuat kueri output deployment setelah siap dan menyimpannya di folder konfigurasi. Anda dapat menambahkan file konfigurasi ini selama proses penggabungan.

Link simbolis didukung oleh perintah gcloud deployment-manager, dan file yang ditautkan dimuat dengan benar. Namun, link simbolis tidak didukung di setiap OS.

Hierarki konfigurasi

Diagram berikut adalah ringkasan berbagai tingkat dan hubungannya. Setiap persegi panjang mewakili file properti, seperti yang ditunjukkan oleh nama file berwarna merah.

Hierarki konfigurasi dengan berbagai tingkat dan hubungannya.

Urutan penggabungan kontekstual

Penggabung konfigurasi memilih file konfigurasi yang sesuai di setiap level berdasarkan konteks penggunaan setiap file. Konteks adalah modul yang Anda deploy di lingkungan. Konteks ini menentukan sistem dan departemen secara otomatis.

Dalam diagram berikut, angka menunjukkan urutan penimpaan dalam hierarki:

Diagram urutan penimpaan

Langkah berikutnya