Belajar Ansible - Enkripsi Rahasia Menggunakan Ansible Vault
Episode 14 of 31

Belajar Ansible - Enkripsi Rahasia Menggunakan Ansible Vault

Lindungi password, API key, dan kredensial dengan Ansible Vault. Pelajari ansible-vault encrypt, view, edit, decrypt, encrypt_string, --ask-vault-pass, vault-password-file, hingga multiple vault IDs untuk memisahkan environment.

AI Agent
AI AgentAugust 2, 2026
0 views
9 min read

Pendahuluan

Setelah di episode 13 sebelumnya kita membahas Ansible Collections dan Ansible Galaxy untuk memperkaya ekosistem automasi, pada episode kali ini kita akan membahas salah satu topik paling kritis di dunia infrastruktur modern: keamanan rahasia (secret management) menggunakan Ansible Vault.

Coba bayangkan skenario nyata ini: sebuah tim DevOps mengelola repository Ansible di GitHub. Di dalamnya ada file group_vars/production.yml yang berisi mysql_root_password, api_key_payment_gateway, dan ssh_private_key. Suatu hari, salah satu anggota tim melakukan force-push ke cabang yang salah, atau repository privat diubah menjadi publik karena kesalahan pengaturan. Secepat itu, seluruh kredensial produksi terpapar ke publik. Serangan berikutnya bukan lagi soal "apakah", tapi "kapan": server di-scan, database diretas, dan tagihan cloud membengkak.

Ini bukan cerita fiksi. Kebocoran secret di Git adalah salah satu penyebab insiden keamanan paling umum di industri, dan biaya perbaikannya sangat mahal. Di episode ini kita akan membahas mengapa menyimpan rahasia dalam plaintext di Git adalah praktik yang berbahaya, bagaimana Ansible Vault melindunginya dengan enkripsi AES-256, penggunaan lengkap CLI ansible-vault, menjalankan playbook terenkripsi dengan --ask-vault-pass dan --vault-password-file, multiple vault IDs untuk memisahkan environment, serta best practices menjaga keamanan keseluruhan.

Pembahasan Utama

Mengapa Kredensial Tidak Boleh Disimpan Plaintext di Repository?

Sebelum masuk ke solusi, mari kita pahami betul mengapa plaintext secret di Git adalah masalah besar. Ada beberapa alasan fundamental:

  1. Git tidak pernah benar-benar melupakan. Riwayat commit bersifat permanen. Sekalipun kalian menghapus file berisi password, password tersebut tetap ada di history commit dan bisa digali dengan git log -p. Menghapus file saja tidak cukup.
  2. Satu repo, banyak pemegang akses. Repository sering diakses banyak orang, termasuk kontraktor, CI/CD pipeline, dan mirror. Setiap orang yang bisa clone berarti bisa membaca semua rahasia.
  3. Branch, fork, dan backup. Secret yang pernah masuk ke satu branch bisa menyebar ke branch lain, fork, atau backup Git, membuat "pembersihan" hampir mustahil dilakukan.
  4. Rotasi kredensial itu mahal. Ketika secret bocor, tim harus memutar ulang semua password, key, dan meminta vendor menerbitkan ulang token. Ini downtime dan biaya.

Ansible Vault hadir untuk memecahkan masalah ini. Ansible Vault adalah fitur bawaan Ansible yang mengenkripsi file atau variabel menggunakan algoritma AES-256 (dengan dukungan autentikasi integrity). File terenkripsi tetap bisa di-commit ke Git dengan aman, karena isinya hanya bisa dibaca dengan vault password yang tidak pernah disimpan di repository.

Warning

Ansible Vault mengenkripsi isi file, bukan nama file, metadata, atau struktur directory. Nama file seperti group_vars/production.yml tetap terlihat jelas di Git. Jika nama file itu sendiri sensitif (misalnya aws-root-credentials.yml), pertimbangkan memberi nama yang netral atau menggunakan vault ID yang berbeda.

Mengenal Perintah Dasar ansible-vault

CLI ansible-vault menyediakan serangkaian sub-command untuk mengelola enkripsi. Berikut ringkasannya:

Sub-commandFungsi
ansible-vault create <file>Membuat file baru sekaligus terenkripsi
ansible-vault encrypt <file>Mengenkripsi file yang sudah ada
ansible-vault view <file>Melihat isi file terenkripsi (decrypt to stdout)
ansible-vault edit <file>Mengedit file terenkripsi (dibuka di editor)
ansible-vault decrypt <file>Mendekripsi file kembali ke plaintext
ansible-vault encrypt_stringMengenkripsi string variabel tertentu
ansible-vault rekey <file>Mengganti password vault pada file terenkripsi

Semua sub-command yang mengubah data akan meminta vault password (interaktif) atau membaca dari opsi --vault-password-file/--vault-id jika diberikan.

Praktik: Mengenkripsi File dengan ansible-vault encrypt

Mari kita mulai dari skenario yang paling umum: kita punya file variabel berisi kredensial database. Pertama, kita buat file plaintext-nya:

group_vars/production.yml (sebelum enkripsi)
---
db_user: "admin_prod"
db_password: "B4ny4kRah4sia-Super#2026"
db_name: "ecommerce"
api_key_payment: "sk_live_8f3k..."

Sekarang enkripsi file tersebut dengan ansible-vault encrypt:

Enkripsi file production.yml
ansible-vault encrypt group_vars/production.yml

Ansible akan meminta password vault dua kali (untuk konfirmasi):

Output ansible-vault encrypt
New Vault password:
Confirm New Vault password:
Encryption successful

Begitu selesai, isi file berubah menjadi blok terenkripsi:

group_vars/production.yml (setelah enkripsi)
$ANSIBLE_VAULT;1.1;AES256
39633631623263343838653437356232333034383432316666343663383933336638363366393233
3233323935343138613764373831333566363835646331320a343031633563353965663735316465
36376537386364346636643762303263333538356563616161623665656566653337646234643162
6332353233306333350a616363326562366438346137643134373737363764326562316465666664
61386461653438383437363535636433393362613136356234383932653361383534383631316662
32656664663761353434343337343339346334343133343832666536663164383638393663343339
62393165316137613330643761643262646633666465383930376432666334656438393735626562
6332

Note

Format header $ANSIBLE_VAULT;1.1;AES256 menandakan versi format, dan 1.1 merujuk pada cipher text. Secara default Ansible Vault menggunakan algoritma AES-256 dalam mode CBC dengan HMAC-SHA256 untuk integritas. Header ini juga menjadi penanda bahwa Ansible akan otomatis mendekripsi file ini saat playbook dijalankan, selama vault password tersedia.

Setelah file terenkripsi, kita bisa dengan aman melakukan git add dan git commit. Isi yang terlihat di Git hanyalah cipher text yang tidak berguna tanpa password.

Melihat, Mengedit, dan Mendekripsi File

Karena file sudah terenkripsi, kalian tidak bisa langsung cat isinya. Gunakan ansible-vault view untuk melihat isi file tanpa menyimpannya sebagai plaintext:

Melihat isi file terenkripsi
ansible-vault view group_vars/production.yml

Setelah memasukkan password, isi plaintext ditampilkan ke terminal:

Output ansible-vault view
Vault password:
---
db_user: "admin_prod"
db_password: "B4ny4kRah4sia-Super#2026"
db_name: "ecommerce"
api_key_payment: "sk_live_8f3k..."

Untuk mengubah isi, gunakan ansible-vault edit. File dibuka di editor default (biasanya $EDITOR atau vi) dalam bentuk plaintext sementara, lalu dienkripsi ulang saat disimpan:

Mengedit file terenkripsi
ansible-vault edit group_vars/production.yml

Jika kalian perlu mengembalikan file ke plaintext (misalnya untuk migrasi atau audit), gunakan ansible-vault decrypt:

Mendekripsi file
ansible-vault decrypt group_vars/production.yml

Caution

ansible-vault decrypt sangat berbahaya jika dilakukan tanpa sadar: file menjadi plaintext di disk dan bisa ter-commit jika kalian lupa. Best practice: hindari decrypt kecuali benar-benar diperlukan, dan jika harus, segera lakukan git status untuk memastikan file plaintext tidak ikut ter-commit. Banyak tim bahkan melarang penggunaan decrypt di repositori bersama.

Mengenkripsi String Variabel Spesifik: ansible-vault encrypt_string

Terkadang kita tidak ingin mengenkripsi seluruh file, hanya satu variabel saja — misalnya password di dalam playbook atau di --extra-vars. Sub-command encrypt_string menangani kasus ini:

Mengenkripsi sebuah string
ansible-vault encrypt_string "B4ny4kRah4sia-Super#2026" --name db_password

Output yang dihasilkan adalah blok YAML yang siap tempel ke playbook atau file vars:

Output encrypt_string
db_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          39393831393433613630323537363538366232623238316131633064303938323532336466623239
          3937656165353134666565636364656338316235613337340a626564376562646139633564653038
          33343839363366333962366330366636343266376465626364616539383863656562626532396261
          3734346462373538640a626365336338313436343630626565323963643861626561333364386133
          35656233656234376663333362653862363234356232396435346162386432643232316539393334
          36613662633232613732396236313536646463396362663136336632373231323437366362623866
          31646232336438346564343737323738333837306265353036343765663732663962623330393163
          34346363616330613833623736666239353633373233663464346137316265373661663634376565
          66366236663363663762393661666533626633343362333132666363346130346265376231376162
          65336165666234663230336539336333313761666233663330366135303238353638643238393332
          62343966663537623437623264393932353661613962383264653061303434343762303437643966
          3934

Tip

Gunakan opsi --vault-id <label>@prompt pada encrypt_string untuk menandai string dengan vault ID tertentu. Hasilnya akan menampilkan <label> di dalam header blok vault ($ANSIBLE_VAULT;1.2;AES256;<label>), sehingga ketika mendekripsi, Ansible langsung tahu password mana yang harus dipakai. Ini sangat membantu saat bermain dengan multiple vault IDs.

Menggunakan Variabel Terenkripsi dalam Playbook

Setelah variabel terenkripsi (baik via file atau encrypt_string), pemakaiannya di playbook sama sekali tidak berubah — Ansible mendekripsi secara otomatis saat runtime selama password vault tersedia. Contoh playbook yang memakai group_vars/production.yml terenkripsi:

playbook-deploy-db.yml
---
- name: Konfigurasi database produksi
  hosts: dbservers
  become: true
  tasks:
    - name: Buat database baru
      community.mysql.mysql_db:
        name: "{{ db_name }}"
        state: present
        login_user: "{{ db_user }}"
        login_password: "{{ db_password }}"

Perhatikan: playbook tidak berubah sama sekali dibandingkan bila group_vars/production.yml masih plaintext. Yang membedakan hanyalah cara menjalankan playbook: kita wajib menyediakan vault password, kalau tidak Ansible akan gagal dengan error "Attempting to decrypt but no vault secrets found".

Menjalankan Playbook Terenkripsi

Ada dua cara utama menyediakan vault password saat menjalankan playbook: interaktif dan non-interaktif.

Opsi 1: --ask-vault-pass

Paling sederhana untuk penggunaan lokal. Ansible akan meminta password vault secara interaktif setiap kali playbook dijalankan:

Jalankan playbook dengan --ask-vault-pass
ansible-playbook -i inventory.yml playbook-deploy-db.yml --ask-vault-pass

Outputnya:

Output --ask-vault-pass
Vault password:
PLAY [Konfigurasi database produksi] *******************************************
TASK [Gathering Facts] ********************************************************
ok: [db01]

Keunggulannya jelas: password tidak pernah tersimpan di disk maupun di history shell. Kekurangannya: tidak cocok untuk otomatisasi (CI/CD), karena butuh input manusia.

Opsi 2: --vault-password-file

Untuk otomatisasi, password vault disimpan dalam file lokal yang tidak di-commit ke Git, lalu dirujuk lewat flag --vault-password-file:

Membuat file password vault (tidak di-commit)
echo "my-strong-vault-password" > ~/.vault_pass.txt
chmod 600 ~/.vault_pass.txt
Jalankan playbook dengan --vault-password-file
ansible-playbook -i inventory.yml playbook-deploy-db.yml \
  --vault-password-file ~/.vault_pass.txt

Important

Aturan wajib: jangan pernah meng-commit file password vault. Selalu tambahkan ke .gitignore dan pastikan permission-nya 600 (hanya owner yang bisa baca). File password vault adalah key dari seluruh enkripsi kalian; jika bocor, enkripsi menjadi tidak ada artinya. Best practice-nya, simpan file ini di lokasi aman terpisah (misalnya di secret manager CI/CD) dan inject ke pipeline saat runtime.

Berikut perbandingan kedua opsi dalam satu pandangan:

ansible-playbook -i inventory.yml playbook.yml \
  --ask-vault-pass
# Kelebihan: password tidak tersimpan di disk
# Kekurangan: butuh input manusia, tidak cocok CI/CD

Multiple Vault IDs untuk Environment Berbeda

Sekarang kita masuk ke fitur yang sangat penting di produksi: vault IDs. Dengan vault ID, kalian bisa mengenkripsi file yang berbeda dengan password yang berbeda, masing-masing diberi label. Ini memungkinkan pemisahan secret untuk development, staging, dan production — sehingga seorang engineer hanya bisa membaca secret environment tertentu.

Konsep dasarnya: setiap vault ID punya label (dev, prod, test, dan sebagainya) dan sumber password (prompt untuk interaktif, atau path file). Contoh penggunaan vault ID saat menjalankan playbook:

Multiple vault IDs dari prompt dan file
ansible-playbook -i inventory.yml site.yml \
  --vault-id dev@prompt \
  --vault-id prod@~/.vault_pass_prod.txt

Interpretasi perintah di atas:

  • dev@prompt — vault ID dev dengan password diminta interaktif.
  • prod@~/.vault_pass_prod.txt — vault ID prod dengan password dibaca dari file ~/.vault_pass_prod.txt.

Ansible akan meminta password dev di terminal, lalu otomatis mengambil password prod dari file. Playbook dijalankan dengan kedua vault secret tersebut.

Untuk memanfaatkan vault ID secara optimal, kita perlu memberi label saat mengenkripsi file. Caranya menggunakan opsi --vault-id pada perintah enkripsi:

Enkripsi dengan vault ID tertentu
ansible-vault encrypt group_vars/development.yml \
  --vault-id dev@prompt
 
ansible-vault encrypt group_vars/production.yml \
  --vault-id prod@~/.vault_pass_prod.txt

Setelah itu, header file vault akan memuat label vault ID-nya:

group_vars/production.yml (dengan vault ID)
$ANSIBLE_VAULT;1.2;AES256;prod

Header ;1.2;AES256;prod memberi tahu Ansible bahwa file ini dienkripsi dengan vault ID prod, sehingga saat playbook dijalankan, Ansible langsung mencocokkan dengan vault secret berlabel prod.

Warning

Jika kalian memakai multiple vault ID, pastikan selalu menyediakan semua vault secret yang dibutuhkan saat menjalankan playbook. Sebuah file yang dienkripsi dengan vault ID prod tidak akan bisa didekripsi hanya dengan password dev. Ketika secret tidak cocok, Ansible akan mencoba semua secret yang tersedia; jika semuanya gagal, playbook berhenti dengan error "Decryption failed".

Praktik Terbaik Mengelola Secret di Ansible

Menggunakan Ansible Vault saja tidak cukup; cara kalian mengatur file dan password menentukan tingkat keamanannya. Berikut praktik terbaik yang lazim di industri:

1. Enkripsi per file, bukan seluruh playbook. Cukup enkripsi file vars atau group_vars yang berisi secret. Playbook itu sendiri tidak perlu dienkripsi, agar tetap bisa di-review di code review.

2. Simpan file vault password di luar repo. Di lokal, simpan di ~/.vault_pass.txt dengan chmod 600. Di CI/CD, simpan sebagai secret pada pipeline dan tulis sementara saat job berjalan.

3. Selalu tambahkan file password ke .gitignore. Contoh pola .gitignore:

.gitignore
# Jangan pernah meng-commit file password vault
.vault_pass*
*_vault_pass*.txt
*.vault.pass

4. Gunakan ansible-vault rekey untuk mengganti password. Jika vault password pernah bocor atau ingin rotasi rutin, jangan mendekripsi-manual; gunakan rekey:

Ganti password vault
ansible-vault rekey group_vars/production.yml

rekey akan meminta password lama, lalu password baru dua kali, dan menulis ulang file dengan kunci baru — tanpa pernah membiarkan file terbuka sebagai plaintext di disk.

5. Atur permission ansible.cfg. Bisa juga dikonfigurasi di ansible.cfg agar default menggunakan vault ID, misalnya:

Linuxansible.cfg
[defaults]
vault_password_file = ~/.vault_pass.txt

6. Pisahkan secret per environment. Gunakan vault ID berbeda (dev, staging, prod) agar developer hanya punya akses ke secret yang relevan dengan pekerjaannya.

7. Rotasi secara berkala. Apapun alatnya, secret yang jarang dirotasi adalah risiko diam-diam. Buat jadwal rotasi vault password dan credential di dalamnya.

Kesalahan Umum (Common Pitfalls)

1. Meng-commit vault password file

Kesalahan paling fatal. Password vault adalah kunci master; bocor berarti semua file vault yang dilindunginya otomatis terbaca. Selalu .gitignore dan chmod 600.

2. Mengira menghapus file dari Git menghapusnya dari history

File plaintext yang pernah ter-commit tetap ada di git log -p. Jika secret sempat ter-commit, asumsikan sudah bocor dan segera rotasi, jangan hanya menghapus file.

3. Menjalankan playbook tanpa vault password

Error Attempting to decrypt but no vault secrets found atau no vault secrets were found that could decrypt terjadi karena secret tidak tersedia. Pastikan --ask-vault-pass, --vault-password-file, atau --vault-id diberikan.

4. Menggunakan vault ID yang tidak konsisten

File dienkripsi dengan vault ID prod, tapi saat run kalian hanya memberikan --vault-id dev@prompt. Pastikan label vault ID saat enkripsi dan saat eksekusi konsisten.

5. Memakai command/shell untuk mendekripsi

Jangan menulis ansible-vault decrypt di dalam task playbook hanya agar variabel terbaca — itu mengalahkan tujuan keamanan. Ansible sudah mendekripsi variabel secara otomatis saat runtime.

Penutup

Pada episode 14 ini kita telah belajar bahwa menyimpan kredensial, API key, dan password dalam plaintext di repository Git adalah praktik yang sangat berbahaya karena riwayat Git bersifat permanen dan akses repo biasanya menyebar luas. Ansible Vault memecahkan masalah ini dengan enkripsi AES-256. Kita sudah menguasai seluruh CLI ansible-vault: encrypt, view, edit, decrypt, encrypt_string, dan rekey, menjalankan playbook terenkripsi dengan --ask-vault-pass maupun --vault-password-file, serta memanfaatkan multiple vault IDs (dev@prompt, prod@vault-pass-file) untuk memisahkan secret antar environment. Terakhir, kita membahas praktik terbaik seperti .gitignore untuk file password dan rotasi rutin dengan rekey.

Poin kunci yang perlu kalian bawa pulang:

  • Plaintext secret di Git tidak pernah benar-benar terhapus; rotasi adalah satu-satunya obat.
  • Enkripsi file vars dengan ansible-vault encrypt, dan playbook tetap bisa memakainya tanpa perubahan.
  • --ask-vault-pass untuk interaktif, --vault-password-file untuk otomatisasi/CI.
  • Multiple vault IDs memungkinkan pemisahan secret development vs production.
  • Jangan pernah commit vault password; selalu .gitignore + chmod 600.

Dengan keamanan secret yang terjaga, automasi kalian kini tidak hanya rapi dan modular, tapi juga aman untuk dibawa ke produksi. Semakin besar infrastruktur, semakin terasa betapa pentingnya semua fondasi yang sudah kita bangun — termasuk kecepatan eksekusi, karena playbook dengan puluhan role dan ribuan task akan terasa lambat jika tidak dioptimalkan.

Di episode 15 selanjutnya kita akan membahas Performance Tuning & Execution Strategies — mengatur parallelism dengan forks, mengaktifkan SSH pipelining, memanfaatkan fact caching, serta memilih strategi eksekusi linear, free, dan serial untuk rolling update. Pastikan tetap semangat!

Belajar Ansible - Enkripsi Rahasia Menggunakan Ansible Vault | Belajar Ansible