Mengkonfigurasi server untuk menggunakan aplikasi Rails menggunakan Ansible

Belum lama ini, saya perlu menulis beberapa buku pedoman yang mungkin untuk mempersiapkan server untuk menyebarkan aplikasi rel. Dan, yang mengejutkan, saya tidak menemukan petunjuk langkah demi langkah yang sederhana. Saya tidak ingin menyalin buku pedoman orang lain tanpa memahami apa yang terjadi dan akibatnya saya harus membaca dokumentasi, mengumpulkan semuanya sendiri. Mungkin seseorang yang bisa saya bantu mempercepat proses ini dengan artikel ini.


Hal pertama yang harus dipahami adalah memungkinkan menyediakan Anda dengan antarmuka yang nyaman untuk melakukan daftar tindakan yang telah ditentukan pada server jauh melalui SSH. Tidak ada keajaiban di sini, Anda tidak dapat menginstal plugin dan keluar dari kotak nol downtime penyebaran aplikasi Anda dengan buruh pelabuhan, pemantauan dan barang lainnya. Untuk menulis buku pedoman, Anda harus tahu apa sebenarnya yang ingin Anda lakukan dan bagaimana melakukannya. Karenanya, saya tidak suka buku pedoman yang sudah jadi dari github, atau artikel seperti: "Salin dan jalankan, itu akan berhasil."


Apa yang kita butuhkan


Seperti yang saya katakan, untuk menulis buku pedoman, Anda harus tahu apa yang ingin Anda lakukan dan bagaimana melakukannya. Mari kita putuskan apa yang kita butuhkan. Untuk aplikasi Rails, kita memerlukan beberapa paket sistem: nginx, postgresql (redis, dll). Selain itu, kita perlu ruby ​​versi tertentu. Yang terbaik adalah menginstalnya melalui rbenv (rvm, asdf ...). Menjalankan semua ini dari root pengguna selalu merupakan ide yang buruk, jadi Anda perlu membuat pengguna yang terpisah dan mengkonfigurasi hak untuknya. Setelah itu, Anda perlu mengunggah kode kami ke server, menyalin konfigurasi untuk nginx, postgres, dll dan menjalankan semua layanan ini.


Akibatnya, urutan tindakan adalah sebagai berikut:


  1. Masuk sebagai root
  2. instal paket sistem
  3. buat pengguna baru, konfigurasikan hak, kunci ssh
  4. konfigurasikan paket sistem (nginx dll) dan jalankan
  5. Buat pengguna di basis data (Anda dapat langsung membuat basis data)
  6. Masuk sebagai pengguna baru
  7. Instal rbenv dan ruby
  8. Instal bundler
  9. Isi kode aplikasi
  10. Kami memulai server Puma

Selain itu, langkah-langkah terakhir dapat dilakukan dengan menggunakan capistrano, setidaknya dia dapat menyalin kode ke direktori rilis dari kotak, beralih rilis dengan symlink pada penyebaran yang sukses, salin konfigurasi dari direktori bersama, restart puma, dll. Semua ini bisa dilakukan dengan Ansible, tetapi mengapa?


Struktur file


Ansible memiliki struktur file yang ketat untuk semua file-nya, jadi yang terbaik adalah menyimpannya dalam direktori yang terpisah. Dan tidak begitu penting apakah akan di aplikasi rel itu sendiri, atau secara terpisah. Anda dapat menyimpan file dalam repositori git yang terpisah. Secara pribadi, itu paling nyaman bagi saya untuk membuat direktori yang mungkin di / config dari direktori rel aplikasi dan menyimpan semuanya dalam satu repositori.


Buku pedoman sederhana


Playbook adalah file yml yang menjelaskan apa dan bagaimana seharusnya dilakukan dengan menggunakan sintaks khusus. Mari kita buat buku pedoman pertama yang tidak melakukan apa-apa:


--- - name: Simple playbook hosts: all 

Di sini, kami hanya mengatakan bahwa playbook kami disebut Simple Playbook dan isinya harus dijalankan untuk semua host. Kita dapat menyimpannya di direktori / ansible dengan nama playbook.yml dan mencoba menjalankannya:


 ansible-playbook ./playbook.yml PLAY [Simple Playbook] ************************************************************************************************************************************ skipping: no hosts matched 

Ansible mengatakan tidak tahu host yang cocok dengan semua daftar. Mereka harus terdaftar dalam file inventaris khusus.


Mari kita buat di direktori yang sama:


 123.123.123.123 

Jadi cukup tentukan host (idealnya, host VPS Anda untuk tes, atau Anda dapat mendaftarkan localhost) dan simpan di bawah inventory nama.
Anda dapat mencoba menjalankan ansible dengan file invetory:


 ansible-playbook ./playbook.yml -i inventory PLAY [Simple Playbook] ************************************************************************************************************************************ TASK [Gathering Facts] ************************************************************************************************************************************ PLAY RECAP ************************************************************************************************************************************ 

Jika Anda memiliki akses ssh ke host yang ditentukan, maka ansible akan menghubungkan dan mengumpulkan informasi tentang sistem jarak jauh. (TUGAS default [Fakta Berkumpul]) setelah itu akan memberikan laporan kemajuan singkat (MAINKAN KEMBALI).


Secara default, nama pengguna tempat Anda masuk ke sistem digunakan untuk koneksi. Kemungkinan besar tidak akan berada di host. Dalam file playbook, Anda dapat menentukan pengguna mana yang akan digunakan untuk terhubung menggunakan arahan remote_user. Selain itu, informasi tentang sistem jarak jauh seringkali tidak perlu bagi Anda dan Anda tidak perlu membuang waktu untuk mengumpulkannya. Anda juga dapat mematikan tugas ini:


 --- - name: Simple playbook hosts: all remote_user: root become: true gather_facts: no 

Coba jalankan playbook lagi dan pastikan koneksi berfungsi. (Jika Anda menentukan root dari pengguna, Anda juga harus menentukan menjadi: arahan benar untuk mendapatkan hak-hak yang ditinggikan. Seperti yang disebutkan dalam dokumentasi: become set to 'true'/'yes' to activate privilege escalation. Meskipun tidak jelas mengapa) .


Mungkin Anda mendapatkan kesalahan yang disebabkan oleh kemungkinan yang tidak dapat ditentukan oleh penerjemah python, maka Anda dapat menentukannya secara manual:


 ansible_python_interpreter: /usr/bin/python3 

di mana Anda memiliki python dapat ditemukan dengan perintah whereis python .


Instal paket sistem


Ansible hadir dengan banyak modul untuk bekerja dengan berbagai paket sistem, jadi kami tidak perlu menulis skrip bash dengan alasan apa pun. Sekarang kita memerlukan salah satu modul ini untuk memperbarui sistem dan menginstal paket sistem. Saya memiliki Ubuntu Linux di VPS, masing-masing, untuk menginstal paket, saya menggunakan apt-get dan modul untuk itu . Jika Anda menggunakan sistem operasi yang berbeda, maka Anda mungkin memerlukan modul yang berbeda (ingat, saya katakan di awal bahwa kita perlu tahu sebelumnya apa dan bagaimana yang akan kita lakukan). Namun, sintaksisnya cenderung serupa.


Kami melengkapi buku pedoman kami dengan tugas pertama:


 --- - name: Simple playbook hosts: all remote_user: root become: true gather_facts: no tasks: - name: Update system apt: update_cache=yes - name: Install system dependencies apt: name: git,nginx,redis,postgresql,postgresql-contrib state: present 

Tugas hanyalah tugas yang mungkin dilakukan pada server jarak jauh. Kami memberi nama tugas untuk melacak kemajuannya dalam log. Dan kami menjelaskan, menggunakan sintaks modul tertentu, apa yang perlu dilakukan. Dalam hal ini, apt: update_cache=yes - mengatakan perbarui paket sistem menggunakan modul apt. Tim kedua sedikit lebih rumit. Kami meneruskan daftar paket ke modul apt, dan mengatakan bahwa state mereka harus present , yaitu, kami katakan untuk menginstal paket-paket ini. Demikian pula, kami dapat memberitahu mereka untuk dihapus, atau diperbarui, hanya dengan mengubah state . Harap dicatat bahwa agar rel dapat bekerja dengan postgresql, kita memerlukan paket postgresql-contrib yang sedang kita instal. Ini lagi perlu diketahui dan dilakukan, mungkin dengan sendirinya tidak akan melakukan ini.


Coba jalankan lagi playbook dan verifikasi bahwa paket sudah diinstal.


Pembuatan pengguna baru.


Untuk bekerja dengan pengguna, Ansible juga memiliki modul - pengguna. Tambahkan tugas lain (saya menyembunyikan bagian yang sudah diketahui dari buku pedoman di belakang komentar, agar tidak menyalinnya sepenuhnya setiap waktu):


 --- - name: Simple playbook # ... tasks: # ... - name: Add a new user user: name: my_user shell: /bin/bash password: "{{ 123qweasd | password_hash('sha512') }}" 

Kami membuat pengguna baru, memberinya skema dan kata sandi. Dan kemudian kita dihadapkan dengan beberapa masalah. Bagaimana jika nama pengguna harus berbeda untuk host yang berbeda? Ya, dan membiarkan kata sandi terbuka di buku pedoman adalah ide yang sangat buruk. Untuk memulainya, kita akan memasukkan nama pengguna dan kata sandi ke dalam variabel, dan di akhir artikel saya akan menunjukkan cara mengenkripsi kata sandi.


 --- - name: Simple playbook # ... tasks: # ... - name: Add a new user user: name: "{{ user }}" shell: /bin/bash password: "{{ user_password | password_hash('sha512') }}" 

Variabel diatur menggunakan kurung keriting ganda di buku pedoman.


Kami akan menunjukkan nilai-nilai variabel dalam file inventaris:


 123.123.123.123 [all:vars] user=my_user user_password=123qweasd 

Perhatikan arahan [all:vars] - ia mengatakan bahwa blok teks berikutnya adalah variabel (vars) dan mereka berlaku untuk semua host (semua).


Konstruksi "{{ user_password | password_hash('sha512') }}" juga menarik. Faktanya adalah bahwa ansible tidak mengatur pengguna melalui user_add seperti yang Anda lakukan secara manual. Dan itu menyimpan semua data secara langsung, itulah sebabnya kita juga harus mengonversi kata sandi menjadi hash terlebih dahulu, yang dilakukan perintah ini.


Mari tambahkan pengguna kami ke grup sudo. Namun, sebelum ini, Anda perlu memastikan bahwa grup tersebut ada karena tidak ada yang akan melakukan ini untuk kami:


 --- - name: Simple playbook # ... tasks: # ... - name: Ensure a 'sudo' group group: name: sudo state: present - name: Add a new user user: name: "{{ user }}" shell: /bin/bash password: "{{ user_password | password_hash('sha512') }}" groups: "sudo" 

Cukup sederhana, kami juga memiliki modul grup untuk membuat grup, dengan sintaks yang sangat mirip dengan apt. Maka cukup mendaftarkan grup ini ke pengguna ( groups: "sudo" ).
Juga berguna untuk menambahkan kunci ssh ke pengguna ini sehingga kami dapat masuk di bawahnya tanpa kata sandi:


 --- - name: Simple playbook # ... tasks: # ... - name: Ensure a 'sudo' group group: name: sudo state: present - name: Add a new user user: name: "{{ user }}" shell: /bin/bash password: "{{ user_password | password_hash('sha512') }}" groups: "sudo" - name: Deploy SSH Key authorized_key: user: "{{ user }}" key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" state: present 

Dalam kasus ini, konstruk "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" menarik - ini menyalin isi file id_rsa.pub (nama Anda mungkin berbeda), yaitu, bagian publik dari kunci ssh dan mengunggahnya ke daftar kunci resmi untuk pengguna di server.


Peran


Ketiga tugas untuk pembuatan dapat dengan mudah digunakan sebagai satu kelompok tugas, dan alangkah baiknya untuk memisahkan kelompok ini dari buku pedoman utama sehingga tidak tumbuh terlalu banyak. Ada beberapa peran untuk hal ini.
Menurut struktur file yang ditunjukkan di bagian paling awal, peran harus diletakkan dalam direktori peran terpisah, untuk setiap peran - direktori terpisah dengan nama yang sama, di dalam tugas, file, template, direktori dll
Mari kita buat struktur file: ./ansible/roles/user/tasks/main.yml (utama adalah file utama yang akan dimuat dan dieksekusi ketika peran terhubung ke playbook, file peran lainnya dapat dihubungkan di dalamnya). Sekarang Anda dapat mentransfer ke file ini semua tugas yang terkait dengan pengguna:


 # Create user and add him to groups - name: Ensure a 'sudo' group group: name: sudo state: present - name: Add a new user user: name: "{{ user }}" shell: /bin/bash password: "{{ user_password | password_hash('sha512') }}" groups: "sudo" - name: Deploy SSH Key authorized_key: user: "{{ user }}" key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" state: present 

Di buku pedoman utama, Anda harus menentukan untuk menggunakan peran pengguna:


 --- - name: Simple playbook hosts: all remote_user: root gather_facts: no tasks: - name: Update system apt: update_cache=yes - name: Install system dependencies apt: name: git,nginx,redis,postgresql,postgresql-contrib state: present roles: - user 

Juga, mungkin masuk akal untuk melakukan pembaruan sistem sebelum semua tugas lain, untuk ini Anda dapat mengganti nama blok tasks yang didefinisikan dalam pre_tasks .


Pengaturan nginx


Nginx seharusnya sudah diinstal bersama kami, Anda perlu mengkonfigurasi dan menjalankannya. Mari kita lakukan segera dalam peran itu. Buat struktur file:


 - ansible - roles - nginx - files - tasks - main.yml - templates 

Sekarang kita membutuhkan file dan templat. Perbedaan antara keduanya adalah bahwa file yang mungkin disalin disalin secara langsung, sebagaimana adanya. Dan templat harus memiliki ekstensi j2 dan mereka dapat menggunakan nilai variabel menggunakan kurung keriting ganda yang sama.


Mari kita sertakan nginx dalam file main.yml . Untuk ini, kami memiliki modul systemd:


 # Copy nginx configs and start it - name: enable service nginx and start systemd: name: nginx state: started enabled: yes 

Di sini kita tidak hanya mengatakan bahwa nginx harus dimulai (mis., Jalankan), tetapi segera katakan bahwa itu harus diaktifkan.
Sekarang salin file konfigurasi:


 # Copy nginx configs and start it - name: enable service nginx and start systemd: name: nginx state: started enabled: yes - name: Copy the nginx.conf copy: src: nginx.conf dest: /etc/nginx/nginx.conf owner: root group: root mode: '0644' backup: yes - name: Copy template my_app.conf template: src: my_app_conf.j2 dest: /etc/nginx/sites-available/my_app.conf owner: root group: root mode: '0644' 

Kami membuat file konfigurasi nginx utama (Anda dapat mengambilnya langsung dari server, atau menulisnya sendiri). Dan juga file konfigurasi untuk aplikasi kita di direktori sites_available (ini tidak perlu tetapi berguna). Dalam kasus pertama, kami menggunakan modul salin untuk menyalin file (file tersebut harus di /ansible/roles/nginx/files/nginx.conf ). Dalam kedua - salin templat, gantikan nilai-nilai variabel. Template harus di /ansible/roles/nginx/templates/my_app.j2 ). Dan mungkin terlihat seperti ini:


 upstream {{ app_name }} { server unix:{{ app_path }}/shared/tmp/sockets/puma.sock; } server { listen 80; server_name {{ server_name }} {{ inventory_hostname }}; root {{ app_path }}/current/public; try_files $uri/index.html $uri.html $uri @{{ app_name }}; .... } 

Perhatikan sisipan {{ app_name }} , {{ app_path }} , {{ server_name }} , {{ inventory_hostname }} - ini semua variabel yang nilainya tidak akan diganti dalam templat sebelum disalin. Ini berguna jika Anda menggunakan buku pedoman untuk grup host yang berbeda. Misalnya, kami dapat melengkapi file inventaris kami:


 [production] 123.123.123.123 [staging] 231.231.231.231 [all:vars] user=my_user user_password=123qweasd [production:vars] server_name=production app_path=/home/www/my_app app_name=my_app [staging:vars] server_name=staging app_path=/home/www/my_stage app_name=my_stage_app 

Jika kami menjalankan buku pedoman kami sekarang, itu akan melakukan tugas yang ditentukan untuk kedua host. Tetapi pada saat yang sama, untuk host panggung, variabel-variabel akan berbeda dari produksi, dan tidak hanya dalam peran dan buku pedoman, tetapi juga dalam konfigurasi nginx. {{ inventory_hostname }} tidak perlu ditentukan dalam file inventaris - ini adalah variabel khusus yang dimungkinkan dan host yang sedang dijalankan playbook disimpan di sana.
Jika Anda ingin memiliki file inventaris untuk beberapa host, dan dijalankan hanya untuk satu grup, ini dapat dilakukan dengan perintah berikut:


 ansible-playbook -i inventory ./playbook.yml -l "staging" 

Pilihan lain adalah memiliki file inventaris terpisah untuk grup yang berbeda. Atau Anda dapat menggabungkan dua pendekatan jika Anda memiliki banyak host yang berbeda.


Mari kita kembali ke konfigurasi nginx. Setelah menyalin file konfigurasi, kita perlu membuat symlink di sitest_enabled di my_app.conf dari sites_available. Dan restart nginx.


 ... # old code in mail.yml - name: Create symlink to sites-enabled file: src: /etc/nginx/sites-available/my_app.conf dest: /etc/nginx/sites-enabled/my_app.conf state: link - name: restart nginx service: name: nginx state: restarted 

Semuanya sederhana di sini - sekali lagi, modul yang memungkinkan dengan sintaksis yang cukup standar. Tetapi ada satu poin. Memulai ulang nginx setiap kali tidak masuk akal. Anda perhatikan bahwa kami tidak menulis perintah dalam bentuk: "lakukan ini seperti ini", sintaksisnya lebih mirip "ini seharusnya memiliki keadaan ini". Dan paling sering ini adalah cara kerja yang memungkinkan. Jika grup sudah ada atau paket sistem sudah diinstal, maka ansible akan memeriksa ini dan melewatkan tugas. Selain itu, file tidak akan disalin jika benar-benar bertepatan dengan apa yang sudah ada di server. Kita dapat memanfaatkan ini dan memulai ulang nginx hanya jika file konfigurasi telah diubah. Ada arahan register untuk ini:


 # Copy nginx configs and start it - name: enable service nginx and start systemd: name: nginx state: started enabled: yes - name: Copy the nginx.conf copy: src: nginx.conf dest: /etc/nginx/nginx.conf owner: root group: root mode: '0644' backup: yes register: restart_nginx - name: Copy template my_app.conf template: src: my_app_conf.j2 dest: /etc/nginx/sites-available/my_app.conf owner: root group: root mode: '0644' register: restart_nginx - name: Create symlink to sites-enabled file: src: /etc/nginx/sites-available/my_app.conf dest: /etc/nginx/sites-enabled/my_app.conf state: link - name: restart nginx service: name: nginx state: restarted when: restart_nginx.changed 

Jika salah satu file konfigurasi berubah, maka salin akan dilakukan dan variabel restart_nginx akan terdaftar. Dan hanya jika variabel ini telah terdaftar, layanan akan restart.


Yah, tentu saja, Anda perlu menambahkan peran nginx ke buku pedoman utama.


Penyiapan postgresql


Kita perlu mengaktifkan postgresql dengan systemd seperti yang kita lakukan dengan nginx, dan juga membuat pengguna yang akan kita gunakan untuk mengakses database dan database itu sendiri.
Buat peran /ansible/roles/postgresql/tasks/main.yml :


 # Create user in postgresql - name: enable postgresql and start systemd: name: postgresql state: started enabled: yes - name: Create database user become_user: postgres postgresql_user: name: "{{ db_user }}" password: "{{ db_password }}" role_attr_flags: SUPERUSER - name: Create database become_user: postgres postgresql_db: name: "{{ db_name }}" encoding: UTF-8 owner: "{{ db_user }}" 

Saya tidak akan menjelaskan cara menambahkan variabel ke inventaris, ini telah dilakukan berkali-kali, serta sintaks dari modul postgresql_db dan postgresql_user. Lebih banyak data dapat ditemukan dalam dokumentasi. Arahan become_user: postgres paling menarik di become_user: postgres . Faktanya adalah bahwa secara default hanya pengguna postgres yang memiliki akses ke database postgresql dan hanya secara lokal. Arahan ini memungkinkan kami untuk menjalankan perintah atas nama pengguna ini (kecuali tentu saja kami memiliki akses).
Juga, Anda mungkin harus menambahkan baris ke pg_hba.conf untuk membuka akses ke database untuk pengguna baru. Ini dapat dilakukan dengan cara yang sama seperti kita mengubah konfigurasi nginx.


Dan tentu saja Anda perlu menambahkan peran postgresql ke buku pedoman utama.


Instal ruby ​​melalui rbenv


Ansible tidak memiliki modul untuk bekerja dengan rbenv, tetapi diinstal dengan mengkloning repositori git. Karenanya, tugas ini menjadi yang paling non-standar. Mari kita buat peran /ansible/roles/ruby_rbenv/main.yml untuknya dan mulai mengisinya:


 # Install rbenv and ruby - name: Install rbenv become_user: "{{ user }}" git: repo=https://github.com/rbenv/rbenv.git dest=~/.rbenv 

Kami lagi menggunakan arahan be_user untuk bekerja dari bawah pengguna yang kami buat untuk tujuan ini. Karena rbenv diinstal di direktori home-nya, tidak secara global. Dan kami juga menggunakan modul git untuk mengkloning repositori dengan menentukan repo dan dest.


Selanjutnya, kita perlu mendaftarkan rbenv init di bashrc dan menambahkan rbenv ke PATH di tempat yang sama. Untuk ini, kami memiliki modul lineinfile:


 - name: Add rbenv to PATH become_user: "{{ user }}" lineinfile: path: ~/.bashrc state: present line: 'export PATH="${HOME}/.rbenv/bin:${PATH}"' - name: Add rbenv init to bashrc become_user: "{{ user }}" lineinfile: path: ~/.bashrc state: present line: 'eval "$(rbenv init -)"' 

Kemudian instal ruby_build:


 - name: Install ruby-build become_user: "{{ user }}" git: repo=https://github.com/rbenv/ruby-build.git dest=~/.rbenv/plugins/ruby-build 

Dan akhirnya instal ruby. Ini dilakukan melalui rbenv, yaitu, hanya perintah bash:


 - name: Install ruby become_user: "{{ user }}" shell: | export PATH="${HOME}/.rbenv/bin:${PATH}" eval "$(rbenv init -)" rbenv install {{ ruby_version }} args: executable: /bin/bash 

Kami mengatakan tim mana yang harus dieksekusi dan bagaimana caranya. Namun, di sini kita menemukan fakta bahwa ansible tidak menjalankan kode yang terkandung dalam bashrc sebelum menjalankan perintah. Jadi, rbenv harus didefinisikan secara langsung dalam skrip yang sama.


Masalah selanjutnya adalah bahwa perintah shell tidak memiliki status dalam hal ansible. Yaitu, pemeriksaan otomatis apakah versi ruby ​​ini diinstal atau tidak tidak. Kita bisa melakukannya sendiri:


 - name: Install ruby become_user: "{{ user }}" shell: | export PATH="${HOME}/.rbenv/bin:${PATH}" eval "$(rbenv init -)" if ! rbenv versions | grep -q {{ ruby_version }} then rbenv install {{ ruby_version }} && rbenv global {{ ruby_version }} fi args: executable: /bin/bash 

Dan masih menginstal bundler:


 - name: Install bundler become_user: "{{ user }}" shell: | export PATH="${HOME}/.rbenv/bin:${PATH}" eval "$(rbenv init -)" gem install bundler 

Dan lagi, tambahkan peran ruby_rbenv kami ke buku pedoman utama.


File bersama.


Secara umum, pengaturan ini dapat diselesaikan. Kemudian tetap menjalankan capistrano dan akan menyalin kode itu sendiri, membuat direktori yang diperlukan dan meluncurkan aplikasi (jika semuanya dikonfigurasi dengan benar). Namun, seringkali capistrano memerlukan file konfigurasi tambahan, seperti database.yml atau .env dapat menyalinnya seperti file dan templat untuk nginx. Hanya ada satu kehalusan. Sebelum menyalin file, Anda perlu membuat struktur direktori untuk mereka, sesuatu seperti ini:


 # Copy shared files for deploy - name: Ensure shared dir become_user: "{{ user }}" file: path: "{{ app_path }}/shared/config" state: directory 

kami menetapkan hanya satu direktori dan ansible akan secara otomatis membuat induk, jika perlu.


Lemari besi yang memungkinkan


Kami telah menemukan fakta bahwa data rahasia seperti kata sandi pengguna dapat muncul dalam variabel. Jika Anda membuat file .env untuk aplikasi, dan database.yml maka harus ada lebih banyak data penting seperti itu. Akan lebih baik menyembunyikan mereka dari mata yang mengintip. Lemari besi yang memungkinkan digunakan untuk ini.


Mari kita membuat file untuk variabel /ansible/vars/all.yml (di sini Anda dapat membuat file yang berbeda untuk berbagai kelompok host, seperti dalam file inventaris: production.yml, staging.yml, dll)
Dalam file ini, Anda perlu mentransfer semua variabel yang harus dienkripsi menggunakan sintaks yml standar:


 # System vars user_password: 123qweasd db_password: 123qweasd # ENV vars aws_access_key_id: xxxxx aws_secret_access_key: xxxxxx aws_bucket: bucket_name rails_secret_key_base: very_secret_key_base 

Maka file ini dapat dienkripsi dengan perintah:


 ansible-vault encrypt ./vars/all.yml 

Secara alami, selama enkripsi akan diperlukan untuk mengatur kata sandi untuk dekripsi. Anda dapat melihat apa yang muncul di dalam file setelah memanggil perintah ini.


Menggunakan ansible-vault decrypt file dapat didekripsi, dimodifikasi, dan kemudian dienkripsi lagi.


Untuk bekerja, dekripsi file tidak diperlukan. Anda menyimpannya dalam bentuk terenkripsi dan menjalankan playbook dengan argumen --ask-vault-pass . Ansible akan meminta kata sandi, mendapatkan variabel, dan menyelesaikan tugas. Semua data akan tetap terenkripsi.


Perintah lengkap untuk beberapa grup host dan vault yang dimungkinkan akan terlihat seperti ini:


 ansible-playbook -i inventory ./playbook.yml -l "staging" --ask-vault-pass 

Dan saya tidak akan memberi Anda teks lengkap buku pedoman dan peran, tulis sendiri. Karena hal yang mungkin adalah ini - jika Anda tidak mengerti apa yang perlu dilakukan, maka dia tidak akan melakukannya.

Source: https://habr.com/ru/post/id460769/


All Articles