Apa cara yang disukai untuk menyimpan konfigurasi aplikasi?

38

Sebagian besar waktu, saya menyimpan konfigurasi aplikasi pengembangan di direktori root proyek, seperti ini:

app
|-- config.json

Tapi itu tampaknya bukan pendekatan terbaik, karena konfigurasi ini akhirnya disimpan dalam sistem kontrol versi - mungkin mengakibatkan nama pengguna, kata sandi, dan hal-hal sensitif lainnya bocor.

12 Panduan Faktor Aplikasi merekomendasikan untuk menjatuhkan file konfigurasi sekaligus dan menggunakan variabel lingkungan untuk pengaturan konfigurasi:

... menyimpan config dalam variabel lingkungan. Env vars mudah untuk diubah di antara penyebaran tanpa mengubah kode apa pun; tidak seperti file config, ada sedikit kemungkinan mereka diperiksa ke dalam kode repo secara tidak sengaja; dan tidak seperti file konfigurasi khusus, atau mekanisme konfigurasi lainnya seperti Java System Properties, mereka adalah bahasa-dan OS-standar agnostik.

Kedengarannya sangat bagus bagi saya, tetapi di mana satu toko mengatakan variabel lingkungan, tanpa memeriksa mereka ke dalam kontrol sumber? Dan alat apa yang bisa saya gunakan untuk meneruskan variabel ke aplikasi? Mungkin ada puluhan opsi konfigurasi, dan mengetiknya dengan tangan setiap kali Anda meluncurkan aplikasi tidak bagus - jadi mereka harus disimpan dalam beberapa jenis file di suatu tempat. Dengan demikian file tersebut akan berakhir di kontrol sumber, dan kami kembali ke tempat kami mulai.

Apakah ada cara penanganan opsi konfigurasi yang diterima secara universal, yang tidak memiliki risiko menyimpan konfigurasi lokal dalam kontrol sumber?

Rogach
sumber
1
Yah, git setidaknya memiliki sesuatu seperti di .gitignoremana saya dapat mendefinisikan file atau folder yang tidak boleh diperiksa ke dalam kontrol versi. Seperti yang Anda katakan saya tidak melihat di mana Env vars benar-benar harus membantu, dengan Anda memiliki skrip untuk mengaturnya dan harus disimpan bersama dengan proyek atau Anda memilikinya 'di suatu tempat' di sistem Anda (direktori home atau bahkan di permulaan mesin skrip) yang tampaknya membuat banyak masalah sendiri, terutama jika banyak konfigurasi diperlukan. Bagaimanapun saya akan membagi file konfigurasi sehingga informasi rahasia masuk dalam file yang berbeda.
thorsten müller
@ thorstenmüller - satu-satunya masalah dengan .gitignore bahwa konfigurasi dasar / template masih harus disimpan, yang berarti aplikasi harus membaca dua konfigurasi - basis, dengan opsi default (disimpan dalam scm), dan lokal, yang menimpa basis (dan tidak disimpan dalam scm). Dengan env vars, saya membayangkan bahwa penyebaran massal menjadi lebih mudah - lebih mudah untuk menentukan variabel lingkungan untuk pengaturan mesin virtual baru daripada menulis sesuatu ke beberapa file non-standar.
Rogach
Pertanyaan bagus, Setelah saya mulai menggunakan penyimpanan data aplikasi khusus pengguna normal untuk ini, hidup menjadi lebih mudah ;-)
Wolf
1
Sudahkah Anda mencoba "Redis" redis.io . Ini dimaksudkan khusus untuk penyimpanan struktur nilai kunci saja.
Karan
2
@ jporcenaluk - Saya suka penyimpanan nilai kunci, tetapi menambahkan redis lengkap ke aplikasi hanya untuk menangani manajemen konfigurasi terasa seperti sedikit berlebihan. Di sisi lain, mungkin saya tidak pernah mengerjakan proyek yang cukup besar.
Rogach

Jawaban:

16

Mungkin tidak ada jawaban yang bagus untuk ini. Tampaknya Anda perlu menyimpan data ini di tempat yang aman, karena akan diperlukan untuk keperluan pemulihan bencana suatu hari. Ini berlaku sama untuk properti file dan skrip yang mengatur variabel lingkungan.

  • Dengan kode sumber (dalam SVN / GIT dll) adalah ide yang sangat buruk, karena data ini akan berisi kata sandi basis data produksi dan sejenisnya.
  • Pencadangan malam perusahaan Anda mungkin cukup, tetapi tidak mungkin menyimpan riwayat perubahan yang mudah diakses.
  • Data perlu diversi secara terpisah ke perangkat lunak yang digunakan. Dalam sistem kami saat ini, perubahan konfigurasi mengarah ke pembuatan aplikasi baru, dan ini benar-benar salah.

Kami sedang mencari solusi untuk masalah ini, dan condong ke repositori kode dengan akses terbatas. Repositori ini hanya akan berisi data konfigurasi. Apakah orang lain memiliki pengalaman untuk dibagikan?

kiwiron
sumber
2
Memiliki dua repositori yang terpisah untuk satu proyek sepertinya bukan ide yang bagus - Anda tidak dapat melakukan rollback bersih atau bekerja dengan cabang, karena Anda harus memanipulasi dua repositori secara bersamaan (misalnya cabang lain memerlukan beberapa opsi konfigurasi baru, dan ketika Anda beralih ke cabang baru itu tanpa juga berpindah dalam repositori config, hal-hal pecah dengan cara yang aneh).
Rogach
2
@Rogach, saya mengerti maksud Anda. Ada alasan yang sah untuk menyimpan beberapa konfigurasi dengan kode, tetapi seperti yang Anda katakan dalam pertanyaan Anda, hal-hal sensitif perlu dibawa ke tempat lain. Jadi dua repositori tampaknya tidak dapat dihindari. Juga, saya tidak menyebutkan bahwa server aplikasi sering membantu di sini. Sumber data dan variabel JNDI dapat diatur oleh administrator dan tidak akan dipublikasikan.
kiwiron
Toko kedua masuk akal. Mungkin ada jenis data lain, juga rahasia, yang dapat disimpan bersama dengan konfigurasi (misalnya data produksi yang sedang dianalisis untuk memperbaiki masalah pelanggan).
Wolf
1
@Rogach Mereka tampaknya menarik banyak kebencian, tetapi git submodules akan menangani ini dengan baik, saya pikir - jika yang utama diatur dengan benar, dan repo akses terbatas hanya bisa hidup di dalamnya.
SeldomNeedy
9

Dalam memeriksa masalah dan kemungkinan solusi, ada baiknya saya menggunakan metode yang dipopulerkan oleh Jeff Atwood : Jika Tuhan menciptakan cara untuk menyimpan informasi konfigurasi yang sensitif, bagaimana dia akan melakukannya?

Yah, dia akan tahu siapa yang membutuhkan informasi konfigurasi dan hanya memberikannya kepada orang-orang itu, dan informasi itu tidak akan pernah bisa diakses oleh orang lain.

Bagian pertama harus sudah dijaga: sistem kontrol sumber Anda harus mengotentikasi pengguna. Dan pendekatan ini juga diberikan validitas menurut # 10 di 10 Perintah Hunt Source Control Troy , "dependensi harus dalam kontrol sumber".

Tapi bagaimana cara mengamankannya jika bocor? Yah, itu tidak perlu disimpan di sana dalam teks biasa! Gunakan enkripsi. Di .NET, ada langkah-langkah yang dapat Anda lakukan untuk mengenkripsi data string koneksi dalam file konfigurasi Anda . Anda harus menemukan metode yang setara untuk melakukannya dengan teknologi pilihan Anda.

jporcenaluk
sumber
3
Hanya ingin mengklarifikasi - bagaimana konfigurasi enkripsi akan membantu? Seperti yang saya pahami, Anda akan diminta untuk membagikan kata sandi dekripsi yang sama antara semua pengembang, dan itu terdengar seperti menyerukan masalah.
Rogach
Jika seseorang di luar perusahaan Anda mendapatkan akses ke repositori Anda, kata sandi Anda dikaburkan. Jika seseorang menyalin file dari proyek ke drive USB dan meninggalkannya di suatu tempat, hal yang sama. Tentu akan lebih banyak pekerjaan untuk dipertahankan. Lebih banyak keamanan biasanya datang dengan harga kenyamanan. Solusi ini agak berat, saya akan memberi Anda itu. Saya terbuka untuk cara yang lebih baik untuk menyelesaikan pertanyaan OP!
jporcenaluk
5

Banyak orang mengkritik menyimpan konfigurasi dalam file biasa bersama dengan kode sumber Anda, tetapi menurut pengalaman saya, ini sebenarnya solusi yang cukup bagus:

  • Mudah diterapkan dalam bahasa apa pun. Di banyak, Anda mendapatkan dukungan untuk file konfigurasi yang kompleks di luar kotak. Misalnya dalam kasus Java dengan Spring Boot, Anda mendapatkan dukungan YAML yang dapat mengekspresikan struktur seperti pohon, dan mudah untuk memiliki file konfigurasi yang terpisah untuk lingkungan yang berbeda serta konfigurasi dasar dari mana file khusus lingkungan dapat mewarisi.
  • Konfigurasi diperlukan untuk menjalankan perangkat lunak Anda, dan perubahan kode sering kali memerlukan pengaturan konfigurasi untuk ditambahkan / dimodifikasi, sehingga wajar untuk menjaga konfigurasi dan kode bersama-sama.
  • Menyimpan konfigurasi dengan sumber memberi Anda semua keuntungan dari kontrol sumber, seperti mengetahui siapa yang memodifikasi pengaturan dan kapan atau dapat memeriksa konfigurasi selama tinjauan kode reguler.
  • Kecuali Anda bekerja untuk CIA, argumen keamanan sepertinya terlalu berlebihan bagi saya. Jadi kata sandi basis data Anda disimpan dalam file di mesin tempat aplikasi Anda berjalan. Nah, jika seseorang mendapatkan akses ke mesin dengan aplikasi Anda, Anda mungkin sudah dalam banyak masalah - misalnya mereka dapat menghapus aplikasi Anda dan memulai aplikasi mereka sendiri di tempatnya pada port yang sama. Dalam skenario seperti itu, memiliki akses ke kata sandi DB mungkin bukan masalah besar. Kecuali jika semua koneksi Anda sepenuhnya terenkripsi, memiliki akses ke mesin Anda, mereka bisa mengendus banyak data menarik dari antarmuka jaringan.
  • Anda dapat menggunakan alat seperti Hiera untuk memiliki file konfigurasi tekstual tetapi tidak menyimpan kata sandi atau data sensitif lainnya di dalamnya.

Jadi, untuk banyak kasus, konfigurasi tekstual yang disimpan dalam kontrol sumber bersama dengan kode adalah awal yang baik.

Jika Anda tertarik dengan sistem terdistribusi atau ingin dapat menukar hot-swap konfigurasi Anda tanpa menggunakan kembali aplikasi Anda, Anda mungkin menemukan solusi yang berbasis di sekitar server konfigurasi yang lebih baik. Spring Cloud memiliki dukungan untuk mekanisme tersebut , dan konfigurasi penyajian backend dapat berupa repositori git atau Eureka . Anda juga dapat menggulung sendiri menggunakan mis . Zookeeper . Salah satu dari pendekatan ini akan membuatnya lebih mudah untuk mengelola konfigurasi yang konsisten pada banyak server untuk memperbarui konfigurasi tanpa harus membangun kembali dan memindahkan kembali perangkat lunak Anda. Ini tentu saja biayanya, yaitu mempelajari server konfigurasi dan cara menggunakannya dari aplikasi Anda serta sistem lain untuk digunakan dan dipelihara.

Michał Kosmulski
sumber
Tetapi kode berpindah tangan ke seseorang yang tidak memiliki rahasia dalam file konfigurasi, akan ada kekacauan nyata.
Tim Ludwinski
@TimLudwinski Kunci / rahasia adalah milik perusahaan, bukan pengembang individu, jadi mereka harus dijaga sedemikian rupa sehingga mereka tidak tersesat jika ada individu yang pergi. Mereka mungkin masalah dan dikelola oleh admin / tim keamanan misalnya, sehingga ada pusat registri.
Michał Kosmulski
5

Kami menghadapi masalah yang sama di tempat saya bekerja. Saat ini semua konfigurasi kami berbasis file dan sumber dikontrol dengan masing-masing aplikasi yang menggunakannya. Ini mengarah pada duplikasi dan pengembang memiliki akses ke kata sandi produksi / qa alih-alih hanya pengembangan.

Yang mengatakan saya pikir kami telah datang dengan solusi yang bagus untuk maju. Kami memindahkan file config kami ke repo git yang terpisah (dilabeli repo config). Kami kemudian menyiapkan server spring-cloud-config (java) yang hanya melayani file dari repo config berdasarkan profil yang diteruskan ke sana. Ini bagus untuk aplikasi Java yang dapat menggunakan klien dan mengunduhnya saat startup. Untuk aplikasi PHP / non-java, kami akan langsung menurunkan file. (Tidak ideal). Di masa depan kita dapat menulis sesuatu yang memungkinkan aplikasi PHP mengunduh konfigurasi itu sendiri dan menyimpannya di suatu tempat, tetapi itu bukan prioritas tinggi untuk dijalankan pertama kali. Saya menganggap solusi ini sebagai config-as-a-service yang tidak secara eksplisit melanggar rekomendasi aplikasi 12 faktor.

Saya percaya zookeeper dapat digunakan untuk hal yang sama (saya melihat setup dengan kubernetes + zookeeper) jadi saya tidak yakin mengapa jawaban itu mendapatkan -1 di atas.

Tautan:

https://spring.io/guides/gs/centralized-configuration/

https://cloud.spring.io/spring-cloud-config/

ssjcory
sumber
3

Alih-alih menyimpan seluruh konfigurasi dalam satu file, simpan dalam beberapa file.

  • Memiliki direktori konfigurasi . Semua file di sana ditafsirkan sebagai file konfigurasi, kecuali mungkin README*.
  • Semua nama file diurutkan berdasarkan abjad, dan file-file tersebut dimuat dalam urutan itu. Inilah sebabnya mengapa file dalam kasus-kasus seperti itu sering memulai dengan dua digit atau: 01-logging.json. 02-database.json, dll.
  • Data dari semua file dimuat ke dalam struktur konfigurasi yang sama yang tersedia untuk aplikasi. Ini adalah bagaimana beberapa file dapat melengkapi pengaturan masing-masing, dan bahkan menimpanya dengan cara yang dapat diprediksi.
  • Hanya simpan di VCS file konfigurasi dengan nilai yang aman untuk dilihat, atau nilai default. Tambahkan file konfigurasi dengan rahasia selama penyebaran, atau, lebih baik lagi, gunakan layanan penyimpanan rahasia yang diautentikasi.

Di kotak Linux terdekat, lihat /etc/sudoers.datau /etc/nginx/conf.d. Ini menunjukkan pola yang sama.

Manajemen rahasia adalah binatang yang berbeda. Anda dapat mengelolanya sebagai langkah manual saat Anda kecil. Anda dapat menggunakan hal-hal seperti Zookeeper. Anda bahkan dapat memeriksa rahasia menjadi VCS dalam bentuk terenkripsi , dan mendekripsi mereka sebagai langkah penyebaran. Sejumlah opsi lain ada.

(Juga, sebuah opini: JSON bukan format file config yang baik, karena tidak mengizinkan komentar; komentar sangat penting. Format TOML, YAML, dan bahkan INI lebih baik dalam penggunaan praktis.)

9000
sumber
2

Saya pikir opsi Anda agak ditentukan oleh OS yang Anda gunakan

Saya akan menyarankan, ya letakkan nilai-nilai dalam kontrol sumber. TAPI hanya versi 'dev'. Anda ingin kode sumber Anda dikompilasi DAN berfungsi! tidak termasuk langkah rahasia tambahan

Maka proses membangun dan menggunakan Anda harus menukar nilai-nilai ini per lingkungan selama penerapan. (Gurita memiliki model semacam ini)

Ewan
sumber
0

Apache zookeeper memberikan opsi bagus untuk menyimpan konfigurasi aplikasi untuk sistem terdistribusi. Perubahan yang dilakukan di zookeeper dapat ditangkap dan diproses dengan memiliki kurator atau pendengar zookeeper di ujung aplikasi.

Gmoney
sumber
6
Apa saja pilihannya? bagaimana cara kerjanya? Di mana itu menyimpannya? Apakah yang satu lebih disukai daripada yang lain? Apa saja berbagai kelebihan dan kekurangan dari setiap opsi? Bagaimana ini berinteraksi pada sistem operasi yang berbeda?
3
@ Gangz - Saya akan tertarik dengan jawaban yang lebih terperinci, tolong jangan berkecil hati dengan downvotes, dan tingkatkan jawaban Anda sehingga dapat membantu.
Jay Elston