Ansible ile ciddi bir şey otomatikleştirmeye başladığınız anda bir ikilemle karşılaşırsınız: veritabanı parolası, API anahtarı, TLS özel anahtarı ve SSH şifresi gibi değerler playbook'un çalışması için gereklidir, ama bunları düz metin olarak Git deposuna koymak kabul edilemez. Depoya bir kez giren sır, siz dosyayı silseniz bile geçmişte kalır ve depoya erişimi olan herkesin eline geçer. Ansible Vault, tam olarak bu ikilemi çözmek için Ansible'ın içine gömülmüş bir şifreleme katmanıdır.
Bu rehberde Vault'un ne yapıp ne yapmadığını, tam dosya şifrelemeyi, tek bir değişkeni satır içinde şifrelemeyi (encrypt_string), parolanın kendisini nasıl yöneteceğinizi, birden fazla ortam için vault-id kullanımını ve deponuzu "hangi dosya şifreli, hangisi değil" konusunda net tutan bir düzeni anlatacağım. Sonunda da parola kaybı, yanlış dosya şifreleme ve CI entegrasyonu gibi konularda yaşanan gerçek tuzaklara değineceğim.
Ansible Vault Ne Yapar, Ne Yapmaz#
Vault, dosyaları ya da tek tek değişken değerlerini simetrik şifreleme ile korur. Bir parola belirlersiniz, Vault o paroladan bir anahtar türetir ve içeriği şifreler; sonuç, deponuza rahatça koyabileceğiniz bir metin bloğudur. Playbook çalışırken aynı parolayı sağlarsınız, Ansible dosyayı bellekte çözer ve kullanır. Çözülmüş içerik hiçbir zaman diske yazılmaz.
Şifrelenmiş bir dosyanın başı şöyle görünür; ilk satır biçim sürümünü, şifreleme yöntemini ve varsa vault kimliğini taşır:
$ANSIBLE_VAULT;1.1;AES256
33633864396266383866323964326564613664643263346130363130653632346166636139
36336165343139373636326633383763383762633233633966623037633638383839323533
...
Vault'un yapmadığı şeyleri bilmek de en az yaptıkları kadar önemlidir. Vault bir anahtar kasası (secret manager) değildir: erişim kaydı tutmaz, sırları döndürmez, kim ne zaman okudu diye izlemez, kullanıcı bazlı yetkilendirme sunmaz. Parolayı bilen herkes tüm içeriği açar. Ayrıca dosya adlarını ve dizin yapısını gizlemez; şifrelediğiniz dosyanın adı veritabani_parolalari.yml ise bu ad herkese görünür.
| İhtiyaç | Vault uygun mu | Alternatif |
|---|---|---|
| Küçük/orta ekipte parola saklama | Evet | — |
| Depoya güvenle commit'leme | Evet | — |
| Sır döndürme ve erişim kaydı | Hayır | Merkezî kasa çözümleri |
| Kullanıcı bazlı yetkilendirme | Hayır | Kasa + rol tabanlı erişim |
| Çalışma anında dinamik kimlik | Hayır | Kasa entegrasyonu / eklenti |
Yani Vault, "sırlarım düz metin olarak Git'te durmasın" sorununu çok iyi çözer; kurumsal ölçekte sır yaşam döngüsü yönetimi ise ayrı bir konudur. Küçük ve orta ölçekli altyapıların büyük bölümü için Vault fazlasıyla yeterlidir.
Şifreli Dosya Oluşturma ve Düzenleme#
En yaygın kullanım, tüm bir değişken dosyasını şifrelemektir. Yeni bir şifreli dosya oluşturmak için:
# Yeni şifreli dosya oluştur (editör açılır, kaydedince şifrelenir)
ansible-vault create group_vars/uretim/vault.yml
# Var olan düz dosyayı şifrele (yerinde değiştirir)
ansible-vault encrypt group_vars/uretim/vault.yml
# İçeriği düzenle (geçici olarak çözer, kaydedince tekrar şifreler)
ansible-vault edit group_vars/uretim/vault.yml
# Sadece oku, değiştirme
ansible-vault view group_vars/uretim/vault.yml
# Kalıcı olarak çöz (dikkat: dosya artık düz metin)
ansible-vault decrypt group_vars/uretim/vault.yml
# Parolayı değiştir
ansible-vault rekey group_vars/uretim/vault.yml
edit komutunun davranışına dikkat edin: dosyayı geçici bir konumda çözer, editörünüzü açar, siz kaydedip çıkınca tekrar şifreler. decrypt ile çözüp elle düzenleyip tekrar encrypt yapmaktan çok daha güvenlidir, çünkü arada düz metin hâlde bir dosya bırakma riski ortadan kalkar.
Dosyanın içeriği sıradan bir YAML'dır:
# group_vars/uretim/vault.yml (şifreli hâlde saklanır)
---
vault_db_parolasi: "K7#mQ2vX9pL4nR8t"
vault_api_anahtari: "sk_live_a1b2c3d4e5f6g7h8"
vault_smtp_parolasi: "Zr5@wT1yE6uI3oP0"
Güçlü ve rastgele parolalar üretmek için şifre üretici aracımızı kullanabilirsiniz; elle uydurulan parolalar tahmin edilebilir kalıplara düşme eğilimindedir. Playbook temelleri ve değişken dosyalarının nasıl yüklendiği konusunda tazelenmek isterseniz Ansible kurulumu ve ilk playbook yazısına bakabilirsiniz.
Tek Değişkeni Şifrelemek: encrypt_string#
Tüm dosyayı şifrelemenin bir dezavantajı var: dosyanın içinde ne olduğunu görmek için her seferinde çözmek gerekir, git diff çıktısı anlamsız hâle gelir ve kod incelemesi zorlaşır. Yalnızca birkaç değer gizliyse, o değerleri satır içinde şifrelemek çok daha kullanışlıdır:
# Tek bir değeri şifrele ve değişken adıyla birlikte bas
ansible-vault encrypt_string 'K7#mQ2vX9pL4nR8t' --name 'db_parolasi'
Çıktı doğrudan YAML dosyanıza yapıştırabileceğiniz bir bloktur:
db_parolasi: !vault |
$ANSIBLE_VAULT;1.1;AES256
62313365396662343061393464336163383438323166333334626263373463656232
35646538393134313564306331623036316331303434313361373732336564663130
3131303162396463610a
Bu yöntemin güzelliği, aynı dosyada şifreli ve şifresiz değişkenlerin bir arada durabilmesidir:
# group_vars/uretim/main.yml — açık okunabilir, sadece sırlar şifreli
---
uygulama_adi: firmaniz-panel
uygulama_ortami: uretim
db_host: 185.12.34.60
db_kullanici: panel_user
db_parolasi: !vault |
$ANSIBLE_VAULT;1.1;AES256
62313365396662343061393464336163383438323166333334626263373463656232
3131303162396463610a
Artık git diff çıktısında "veritabanı kullanıcısı değişti" bilgisini görebilirsiniz, sadece parola satırı okunmaz kalır. Kod incelemesi yapan kişi neyin değiştiğini anlar.
⚠️ Parolayı komut satırına yazmak, kabuk geçmişinize düşmesine yol açar. Bunu önlemek için değeri komuttan değil standart girişten okutun:
# Parolayı terminale yazmadan, girdi olarak ver (Ctrl+D ile bitir)
ansible-vault encrypt_string --stdin-name 'db_parolasi'
# Reading plaintext input from stdin...
Bir de kabuk geçmişini kirletmemek için komutu boşlukla başlatmak (HISTCONTROL=ignorespace ayarlıysa) işe yarar; ama kalıcı çözüm --stdin-name kullanmaktır.
Vault Parolasını Yönetmek#
Vault'un tüm güvenliği tek bir şeye dayanır: vault parolasının kendisi. Onu nasıl sağladığınız, kurulumunuzun güvenli mi yoksa yalnızca güvenli görünen bir şey mi olduğunu belirler.
Üç yöntem vardır. Birincisi her çalıştırmada sormaktır; en güvenli, en zahmetli olanıdır:
ansible-playbook site.yml --ask-vault-pass
İkincisi bir parola dosyası kullanmaktır. Bu dosya asla depoya girmemeli, izinleri kısıtlı olmalıdır:
# Parola dosyasını depo dışında tut
echo 'cok-uzun-ve-rastgele-bir-vault-parolasi' > ~/.ansible/vault_uretim
chmod 600 ~/.ansible/vault_uretim
ansible-playbook site.yml --vault-password-file ~/.ansible/vault_uretim
Üçüncüsü ise çalıştırılabilir bir betik vermektir; Ansible dosyanın çalıştırma izni varsa onu çalıştırır ve standart çıktısını parola olarak alır. Bu, parolayı bir sistem anahtarlığından ya da ortam değişkeninden çekmek için kullanılır:
#!/usr/bin/env bash
# ~/.ansible/vault_pass.sh (chmod +x)
# Parolayı ortam değişkeninden veya bir kasa aracından al
if [ -n "${ANSIBLE_VAULT_PAROLA:-}" ]; then
printf '%s' "$ANSIBLE_VAULT_PAROLA"
else
# Örnek: sistem anahtarlığından oku
secret-tool lookup servis ansible ortam uretim
fi
Bu ayarları her komutta yazmamak için ansible.cfg içine koyun:
; ansible.cfg
[defaults]
vault_password_file = ~/.ansible/vault_pass.sh
; Birden fazla ortam için:
; vault_identity_list = test@~/.ansible/vault_test, uretim@~/.ansible/vault_uretim
Farklı ortamlar için farklı parolalar kullanmak, vault-id mekanizmasıyla mümkündür. Test ortamının parolasını bilen bir stajyerin üretim sırlarını açamaması gerekir:
# Şifrelerken kimliği belirt
ansible-vault encrypt --vault-id uretim@prompt group_vars/uretim/vault.yml
ansible-vault encrypt --vault-id test@prompt group_vars/test/vault.yml
# Çalıştırırken ikisini birden ver; Ansible doğru olanı eşleştirir
ansible-playbook site.yml \
--vault-id test@~/.ansible/vault_test \
--vault-id uretim@~/.ansible/vault_uretim
| Yöntem | Güvenlik | Otomasyona uygun | Ne zaman |
|---|---|---|---|
--ask-vault-pass | Yüksek | Hayır | Elle çalıştırma, hassas işler |
Parola dosyası (0600) | Orta | Evet | Kişisel iş istasyonu |
| Parola betiği | Orta-yüksek | Evet | Kasa/anahtarlık entegrasyonu |
| Ortam değişkeni | Düşük-orta | Evet | CI ortamı (maskeleme ile) |
Depo Düzeni: Şifreli ve Açık Değişkenleri Ayırmak#
En sürdürülebilir düzen, sırları ayrı dosyalarda tutup açık değişkenlerden isimlendirme ile ayırmaktır. Yaygın ve iyi çalışan yapı şudur:
proje/
├── ansible.cfg
├── inventory.ini
├── site.yml
├── group_vars/
│ ├── all/
│ │ ├── main.yml # açık: ortak ayarlar
│ │ └── vault.yml # ŞİFRELİ: ortak sırlar
│ ├── uretim/
│ │ ├── main.yml # açık
│ │ └── vault.yml # ŞİFRELİ
│ └── test/
│ ├── main.yml
│ └── vault.yml # ŞİFRELİ
└── roles/
Buradaki püf nokta, şifreli dosyadaki değişkenleri vault_ önekiyle adlandırıp açık dosyada onlara işaret etmektir:
# group_vars/uretim/vault.yml (şifreli)
vault_db_parolasi: "K7#mQ2vX9pL4nR8t"
# group_vars/uretim/main.yml (açık)
db_kullanici: panel_user
db_parolasi: "{{ vault_db_parolasi }}"
Bu dolaylı bağlama iki şey kazandırır. Birincisi, açık dosyaya bakan biri hangi sırların var olduğunu ve nerede kullanıldığını görebilir, ama değerleri göremez. İkincisi, rol ve şablonlarınız hep db_parolasi adını kullanır; sırrın nereden geldiğini bilmeleri gerekmez, bu da rolleri Vault'tan bağımsız kılar. Rollerin ayarlanabilir arayüzünü nasıl tasarlayacağınız konusunda Ansible rol yapısı yazısı ayrıntılı bilgi veriyor.
Deponuza şu güvenlik ağlarını da ekleyin. .gitignore dosyasına parola dosyalarını yazın:
# .gitignore
.vault_pass
*.vault_pass
vault_pass.sh
*.decrypted.yml
Ve bir pre-commit kancasıyla, yanlışlıkla çözülmüş bir vault dosyasının commit edilmesini engelleyin:
#!/usr/bin/env bash
# .githooks/pre-commit
FAIL=0
for f in $(git diff --cached --name-only --diff-filter=ACM | grep -E 'vault\.yml$'); do
head -n1 "$f" | grep -q '^\$ANSIBLE_VAULT' || {
echo "HATA: $f şifreli değil! ansible-vault encrypt çalıştırın."
FAIL=1
}
done
exit $FAIL
Kancaları ekiple paylaşma yöntemini Git hooks ile otomasyon yazısında anlattım. Bir sırrın depoya girmesinin gerçekte ne kadar pahalı olabileceğini görmek için .git klasörü ve .env ifşası yazısına da göz atmanızı öneririm.
Playbook'ta Kullanım ve CI Entegrasyonu#
Şifreli group_vars dosyaları hiçbir ek işlem gerektirmez; Ansible envanter yüklerken onları otomatik olarak çözer. Tek yapmanız gereken parolayı sağlamaktır. Playbook içinde şifreli bir dosyayı açıkça yüklemek isterseniz include_vars da çalışır:
---
- name: Uygulama dağıtımı
hosts: uretim
become: true
tasks:
- name: Sırları yükle
ansible.builtin.include_vars:
file: secrets/uretim.yml
no_log: true
- name: Uygulama ortam dosyasını yaz
ansible.builtin.template:
src: env.j2
dest: /opt/uygulama/.env
owner: uygulama
group: uygulama
mode: "0600"
no_log: true
notify: uygulamayı yeniden başlat
no_log: true parametresi kritik öneme sahiptir. Onsuz, -v ile çalıştırdığınızda ya da bir görev hata verdiğinde Ansible değişken içeriğini ekrana ve loglara basar; şifrelediğiniz parola düz metin olarak CI çıktısında görünür. Sır işleyen her görevde no_log kullanın. Hata ayıklarken geçici olarak kapatmanız gerekirse, o çıktının nereye gittiğine dikkat edin.
CI ortamında parola bir ortam değişkeni ile taşınır. Boru hattı yapılandırmanızda değişkeni gizli/maskeli olarak tanımlayın ve çalıştırma adımını şöyle kurun:
# CI adımı
set -euo pipefail
umask 077
printf '%s' "$ANSIBLE_VAULT_PAROLA" > "$RUNNER_TEMP/vault_pass"
trap 'rm -f "$RUNNER_TEMP/vault_pass"' EXIT
ansible-playbook site.yml \
--vault-password-file "$RUNNER_TEMP/vault_pass" \
--limit uretim
umask 077 dosyanın yalnızca sahibi tarafından okunabilmesini sağlar, trap ise adım nasıl biterse bitsin dosyayı siler. Bu iki satır olmadan parola dosyası çalıştırıcının diskinde kalabilir.
Sık Yapılan Hatalar ve Tuzaklar#
Vault parolasını kaybetmek. Vault'ta parola kurtarma diye bir şey yoktur. Parolayı kaybederseniz şifreli dosyaların içeriği kalıcı olarak erişilemez hâle gelir; tek çözüm sırları sıfırdan üretip yeniden şifrelemektir. Bu yüzden parolayı en az iki güvenli yerde saklayın (örneğin bir parola yöneticisi ve ekip kasası) ve ekip içinde tek kişiye bağımlı bırakmayın.
Yanlışlıkla decrypt çalıştırıp commit etmek. ansible-vault decrypt dosyayı yerinde düz metne çevirir. Bunu yapıp unutursanız bir sonraki commit sırrı depoya sokar. Düzenleme için her zaman edit kullanın ve yukarıdaki pre-commit kancasını kurun.
no_log kullanmamak. Şifrelemenin tek amacı sırrın görünmemesiyse, onu ilk hata çıktısında ekrana basmak tüm çabayı boşa çıkarır. Özellikle CI logları uzun süre saklanır ve genellikle daha geniş bir kitleye açıktır.
Tüm dosyayı şifreleyip inceleme yapamaz hâle gelmek. Yüz satırlık bir yapılandırma dosyasını sırf içinde iki parola var diye tamamen şifrelerseniz, hiç kimse o dosyadaki değişiklikleri gözden geçiremez. Sırları ayrı vault.yml dosyasına alın ya da encrypt_string ile yalnızca değerleri şifreleyin.
Aynı parolayı tüm ortamlar için kullanmak. Test ortamının vault parolası daha çok kişide bulunur ve daha çok yerde dolaşır. Üretim sırları için ayrı bir vault-id kullanmak, tek bir sızıntının her şeyi açmasını önler.
Şifrelenmiş içerikte satır sonu ve girinti bozmak. encrypt_string çıktısını elle düzenlemeyin; blok girintisi bozulursa YAML ayrıştırma hatası ya da "Vault format unhexlify error" alırsınız. Çıktıyı olduğu gibi kopyalayın.
| Hata mesajı | Anlamı | Çözüm |
|---|---|---|
Decryption failed | Yanlış parola veya yanlış vault-id | Doğru kimliği verin |
Attempting to decrypt but no vault secrets found | Parola hiç sağlanmamış | --vault-password-file ekleyin |
Vault format unhexlify error | Blok bozulmuş / elle düzenlenmiş | Değeri yeniden şifreleyin |
input is not vault encrypted data | Dosya aslında düz metin | ansible-vault encrypt çalıştırın |
Sıkça Sorulan Sorular#
Ansible Vault parolamı unuttum, kurtarabilir miyim#
Hayır. Vault simetrik şifreleme kullanır ve parolanın bir kopyasını hiçbir yerde saklamaz; kurtarma mekanizması bilinçli olarak yoktur. Parolayı kaybettiyseniz şifreli dosyalardaki verilere ulaşmanın yolu yoktur, dolayısıyla ilgili sırları (veritabanı parolası, API anahtarı) sıfırdan üretip yeni bir parolayla yeniden şifrelemeniz gerekir. Bu riski önlemek için parolayı ekip kasasında ve bir yedek konumda saklayın.
Tüm dosyayı mı yoksa tek tek değişkenleri mi şifrelemeliyim#
Dosyada sadece sırlar varsa tüm dosyayı şifrelemek daha temizdir; açık değişkenlerle karışık bir dosyada ise encrypt_string çok daha kullanışlıdır. Karışık dosyayı tamamen şifrelemek, kod incelemesini ve git diff okumayı imkânsız hâle getirir. En yaygın ve dengeli düzen, sırları ayrı bir vault.yml dosyasında toplayıp açık dosyalardan değişken referansıyla çağırmaktır.
Vault şifreli dosya Git'te güvenle saklanabilir mi#
Evet, Vault'un varlık sebebi tam olarak budur. Dosya AES tabanlı simetrik şifrelemeyle korunur ve parolayı bilmeyen biri için anlamsız bir metin bloğudur. Ancak iki noktaya dikkat edin: vault parolasının kendisi asla depoya girmemelidir, ve dosya adları görünür kaldığı için "burada üretim veritabanı sırları var" bilgisi gizlenmez. Ayrıca zayıf bir vault parolası, şifrelemeyi kaba kuvvet saldırısına açık bırakır.
Ansible Vault ile merkezî bir sır kasası arasında nasıl seçim yaparım#
Vault, küçük ve orta ölçekli ekiplerde, sır sayısı sınırlı ve değişim sıklığı düşükken mükemmel çalışır: ek altyapı gerektirmez, öğrenmesi yarım saat sürer. Merkezî bir kasaya ihtiyaç duyduğunuz nokta, kim hangi sırra ne zaman eriştiğini kaydetmeniz gerektiği, sırların otomatik döndürülmesini istediğiniz ya da uygulamaların çalışma anında dinamik kimlik alması gerektiği andır. Geçiş kararını denetim ve uyumluluk gereksinimleriniz belirler.
Aynı playbook'ta iki farklı vault parolası kullanabilir miyim#
Evet, vault-id mekanizması tam olarak bunun için vardır. Dosyaları şifrelerken --vault-id uretim@prompt gibi bir kimlik verirsiniz, çalıştırırken de birden fazla --vault-id parametresi geçersiniz; Ansible her dosyanın başlığındaki kimliğe bakıp doğru parolayı eşleştirir. Bu, test ve üretim sırlarını farklı parolalarla korumanın ve erişimi ekip içinde ayırmanın standart yoludur.
Şifreli değişkenin loglara düşmesini nasıl engellerim#
Sır kullanan görevlere no_log: true ekleyin. Bu parametre olmadan, ayrıntılı çıktı modunda ya da görev hata verdiğinde Ansible değişkenin çözülmüş değerini ekrana basar ve CI logunda kalıcı olarak saklanır. Ayrıca debug modülüyle sır içeren bir değişkeni yazdırmaktan kaçının; hata ayıklarken gerçekten gerekiyorsa değerin uzunluğunu ya da bir özetini basmak daha güvenlidir.
Vault dosyasının şifreli olup olmadığını nasıl kontrol ederim#
Dosyanın ilk satırına bakmanız yeterlidir: şifreli bir dosya $ANSIBLE_VAULT;1.1;AES256 ile başlar. Komut satırından head -n1 group_vars/uretim/vault.yml çalıştırarak hızlıca doğrulayabilirsiniz. Bu kontrolü bir pre-commit kancasına koyup tüm vault.yml dosyaları için otomatik hâle getirmek, yanlışlıkla çözülmüş bir dosyanın depoya girmesini yapısal olarak engeller.
Kapanış#
Ansible Vault, sırları depodan uzak tutmak ile playbook'un çalışabilmesi arasındaki gerilimi basit ve yeterli bir çözümle kapatır. Aklınızda kalması gereken dört alışkanlık şunlar: sırları vault_ önekli ayrı dosyalarda toplayın ve açık dosyalardan referansla çağırın; parolayı asla depoya koymayın, ortam başına ayrı vault-id kullanın; sır işleyen her görevde no_log: true yazın; ve vault parolasını iki ayrı güvenli yerde yedekleyin, çünkü kaybederseniz geri dönüşü yok. Bir de pre-commit kancası kurun, çünkü tek bir dikkatsiz decrypt bütün düzeni bozabilir.
Bu yapılandırmaları uygulayacağınız altyapı için tam root erişimli VDS ve sanal sunucu paketlerimize bakabilirsiniz. Sunucularınızın güvenlik sertleştirmesini ve düzenli bakımını bize devretmek isterseniz sunucu yönetimi hizmetimiz bu yükü üstlenir; sır ve yapılandırma değişikliklerinden önce geri dönebileceğiniz bir nokta oluşturmak için yedekleme çözümlerimizi, güçlü parola üretimi için şifre üretici aracımızı kullanabilirsiniz.