Ansible Vault ile Hassas Değişken Yönetimi
Production ortamında çalışan bir Ansible playbook’unda veritabanı şifrelerini, API anahtarlarını ya da SSL sertifikalarını düz metin olarak tutmak, adeta kapının önüne altın külçesi bırakmak gibidir. Versiyon kontrol sistemlerine giden bu hassas veriler, bir gün mutlaka yanlış ellere geçer. İşte tam bu noktada Ansible Vault devreye giriyor: şifreleme tabanlı, entegre ve kullanımı son derece pratik bir gizli veri yönetim sistemi.
Ansible Vault Nedir ve Neden Kullanmalısınız?
Ansible Vault, Ansible’ın yerleşik şifreleme aracıdır. AES-256 algoritmasıyla çalışır ve hassas değişkenleri, tüm dosyaları ya da playbook içindeki tek bir string’i şifreleyebilir. Git reponuza commit edebileceğiniz, yani kaynak kodunuzla birlikte güvenle saklayabileceğiniz şifreli dosyalar üretir.
Peki gerçek dünyada ne işe yarar? Düşünün ki bir e-ticaret sitesi için CI/CD pipeline’ı kuruyorsunuz. Jenkins ya da GitLab CI üzerinden otomatik deploy çalışıyor. Bu süreçte:
- Veritabanı kullanıcı adı ve şifresi
- Redis auth token’ı
- Üçüncü parti ödeme sistemi API anahtarları
- SMTP sunucu kimlik bilgileri
- AWS/GCP/Azure servis hesabı credential’ları
…gibi onlarca hassas bilgi playbook’larınızda yer alıyor. Bunları düz metin bırakmak hem güvenlik açığı hem de KVKK/GDPR açısından ciddi risk demektir. Vault bu problemi zarif biçimde çözer.
Vault Kurulumu ve İlk Adımlar
Ansible zaten kuruluysa Vault için ayrı bir kurulum gerekmez, doğrudan kullanıma hazırdır. Ancak şifreli dosyaların yönetimi için sisteminizde bir parola yöneticisi ya da en azından güvenli bir parola saklama stratejinizin olması gerekir.
Vault’u kullanmadan önce temel komut yapısını tanıyalım:
# Yeni şifreli dosya oluştur
ansible-vault create secrets.yml
# Mevcut dosyayı şifrele
ansible-vault encrypt vars/production.yml
# Şifreli dosyanın içeriğini görüntüle
ansible-vault view secrets.yml
# Şifreli dosyayı düzenle
ansible-vault edit secrets.yml
# Dosyayı çöz (şifrelemeyi kaldır)
ansible-vault decrypt vars/production.yml
# Vault parolasını değiştir
ansible-vault rekey secrets.yml
İlk ansible-vault create secrets.yml komutunu çalıştırdığınızda sistem sizden bir parola ister. Bu parolayı belirlediğinizde editörünüz açılır (genellikle vi), değişkenlerinizi yazarsınız ve kaydedip çıktığınızda dosya otomatik olarak şifrelenir.
Vault ile Değişken Dosyaları Oluşturmak
Gerçek bir senaryo üzerinden gidelim. Bir Django uygulaması deploy ediyoruz ve production ortamı için hassas değişkenlere ihtiyacımız var.
ansible-vault create group_vars/production/vault.yml
Editör açıldığında şu içeriği yazıyoruz:
# Bu dosyanın içeriği şifreli saklanır
vault_db_password: "Sup3rS3cur3P@ssw0rd!"
vault_secret_key: "django-insecure-bu-keyi-degistirin-abc123xyz"
vault_redis_password: "R3d1sAuth#2024"
vault_smtp_password: "mailpassword456"
vault_aws_secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
vault_stripe_api_key: "sk_live_51abc123def456ghi789"
Kaydedip çıktığınızda dosya artık şifreli haldedir. Git’e commit edebilirsiniz. Şimdi bu vault değişkenlerini normal değişken dosyanızda kullanacaksınız:
# group_vars/production/vars.yml - Bu dosya şifrelenmemiştir
db_name: "myapp_production"
db_user: "myapp_user"
db_password: "{{ vault_db_password }}"
django_secret_key: "{{ vault_secret_key }}"
redis_password: "{{ vault_redis_password }}"
smtp_host: "mail.example.com"
smtp_port: 587
smtp_password: "{{ vault_smtp_password }}"
Bu yaklaşımın güzelliği şu: hangi değişkenlerin olduğunu vars.yml‘den görebilirsiniz, ama gerçek değerlere sadece vault parolasıyla ulaşabilirsiniz. Kod reviewları sırasında değişken isimleri görünür kalır, hassas değerler görünmez.
Playbook’u Vault ile Çalıştırmak
Şifreli dosya içeren bir playbook’u çalıştırmanın birkaç yolu vardır:
# Parola sormak için --ask-vault-pass parametresi
ansible-playbook deploy.yml --ask-vault-pass
# Parola dosyasından okumak için --vault-password-file
ansible-playbook deploy.yml --vault-password-file ~/.vault_pass
# Ortam değişkeni kullanımı (CI/CD için ideal)
export ANSIBLE_VAULT_PASSWORD_FILE=~/.vault_pass
ansible-playbook deploy.yml
CI/CD ortamında etkileşimli parola girişi mümkün olmadığından parola dosyası ya da ortam değişkeni yöntemini kullanmanız gerekir. Parola dosyası yaklaşımında dikkat edilmesi gereken bazı noktalar var:
# Parola dosyasını oluşturun
echo "gizliparolaniz" > ~/.vault_pass
# İzinleri kısıtlayın - sadece sahibi okuyabilsin
chmod 600 ~/.vault_pass
# .gitignore'a ekleyin - asla commit etmeyin!
echo "~/.vault_pass" >> .gitignore
echo ".vault_pass" >> .gitignore
Tek Değer Şifreleme: encrypt_string
Bazen tüm dosyayı şifrelemek yerine, mevcut bir vars dosyasındaki tek bir değeri şifrelemek istersiniz. encrypt_string komutu tam bunun için tasarlanmıştır:
# Tek bir string'i şifrele
ansible-vault encrypt_string 'gizliSifre123!' --name 'db_password'
Bu komut şuna benzer bir çıktı verir:
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
38313133623562656433316361623561326139316566623661303730366637346662613065666238
6565663737306638643961316336636163343964643865630a363763653665336635303333633866
37346165363932353965666137373730376437613932666130653930333831663234636232363837
3436363365343036620a363764613930353831366634663266363461633534373935313338316566
6663
Bu çıktıyı doğrudan vars.yml dosyanıza yapıştırabilirsiniz. Playbook çalışırken Ansible bu değeri otomatik olarak çözecektir.
Çoklu Vault ID Kullanımı
Büyük organizasyonlarda farklı ekiplerin farklı parolalarla korunan vault’lara ihtiyacı olabilir. Örneğin dev ekibi production şifrelerine erişememelidir. Vault ID özelliği bu senaryoyu ele alır:
# Development vault'u oluştur
ansible-vault create --vault-id dev@prompt group_vars/dev/vault.yml
# Production vault'u ayrı parolayla oluştur
ansible-vault create --vault-id prod@prompt group_vars/production/vault.yml
# Her iki vault'u kullanan playbook'u çalıştır
ansible-playbook site.yml
--vault-id dev@dev_pass.txt
--vault-id prod@prod_pass.txt
Şifreli dosyaların başlığına bakarsanız vault ID’yi görebilirsiniz:
head -1 group_vars/production/vault.yml
# $ANSIBLE_VAULT;1.2;AES256;prod
Bu yaklaşımla dev ortam parolasına sahip biri prod dosyalarını çözemez. Production credential’ları sadece production erişimi olan kişilerde kalır.
GitLab CI/CD ile Entegrasyon
Pek çok ekip GitLab CI üzerinde Ansible playbook’larını otomatik çalıştırır. Vault parolasını güvenli biçimde CI pipeline’a aktarmak için GitLab’ın “Protected Variables” özelliğini kullanabilirsiniz.
GitLab projenizde Settings > CI/CD > Variables bölümüne gidin ve ANSIBLE_VAULT_PASSWORD adında, protected ve masked olarak işaretlenmiş bir değişken ekleyin.
Ardından .gitlab-ci.yml dosyanızı şöyle yapılandırın:
# .gitlab-ci.yml
stages:
- deploy
deploy_production:
stage: deploy
image: cytopia/ansible:latest
before_script:
# Vault parolasını geçici dosyaya yaz
- echo "$ANSIBLE_VAULT_PASSWORD" > /tmp/vault_pass
- chmod 600 /tmp/vault_pass
script:
- ansible-playbook -i inventory/production site.yml
--vault-password-file /tmp/vault_pass
--extra-vars "deploy_env=production"
after_script:
# Parolayı temizle
- rm -f /tmp/vault_pass
only:
- main
environment:
name: production
after_script bloğu script başarısız olsa bile çalışır, yani parola dosyası her durumda temizlenir. Bu küçük ama önemli bir güvenlik detayıdır.
Jenkins Pipeline Entegrasyonu
Jenkins kullanıyorsanız Credentials özelliği ile vault parolasını yönetebilirsiniz. Jenkins’e Manage Jenkins > Credentials üzerinden “Secret text” türünde bir credential ekleyin, ID olarak ansible-vault-password verin.
// Jenkinsfile
pipeline {
agent any
environment {
ANSIBLE_HOST_KEY_CHECKING = 'False'
}
stages {
stage('Deploy') {
steps {
withCredentials([string(
credentialsId: 'ansible-vault-password',
variable: 'VAULT_PASS'
)]) {
sh '''
# Vault parolasını geçici dosyaya yaz
echo "$VAULT_PASS" > /tmp/.vault_pass
chmod 600 /tmp/.vault_pass
# Playbook'u çalıştır
ansible-playbook
-i inventory/production
--vault-password-file /tmp/.vault_pass
site.yml
# Temizlik
rm -f /tmp/.vault_pass
'''
}
}
}
}
post {
always {
sh 'rm -f /tmp/.vault_pass || true'
}
}
}
Vault Parola Sağlayıcı Script Kullanımı
Parola dosyasını statik bir metin dosyasında tutmak yerine, parolayı dinamik olarak bir secret yöneticisinden (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault) çeken bir script kullanabilirsiniz. Bu kurumsal ortamlar için çok daha güvenli bir yaklaşımdır.
#!/usr/bin/env python3
# vault_pass_script.py
# HashiCorp Vault'tan Ansible Vault parolasını çeker
import hvac
import sys
import os
def get_vault_password():
client = hvac.Client(
url=os.environ.get('VAULT_ADDR', 'https://vault.company.com'),
token=os.environ.get('VAULT_TOKEN')
)
if not client.is_authenticated():
sys.stderr.write("HashiCorp Vault kimlik dogrulama hatasin")
sys.exit(1)
secret = client.secrets.kv.v2.read_secret_version(
path='ansible/vault-password',
mount_point='secret'
)
password = secret['data']['data']['password']
print(password)
if __name__ == '__main__':
get_vault_password()
# Script'e çalıştırma izni ver
chmod +x vault_pass_script.py
# Ansible'a bu scripti parola sağlayıcı olarak kullandır
ansible-playbook site.yml --vault-password-file vault_pass_script.py
Bu yaklaşımla Ansible Vault parolası hiçbir zaman disk üzerinde saklanmaz, her çalıştırmada HashiCorp Vault’tan anlık olarak alınır.
Vault Dosyalarını Debug Etmek
Production’da bir şeyler ters gittiğinde şifreli değişkenlerin doğru yüklenip yüklenmediğini kontrol etmeniz gerekebilir. Bunun için birkaç kullanışlı yöntem:
# Vault değişkenlerinin doğru çözümlendiğini kontrol et
ansible -i inventory/production webservers -m debug
-a "var=db_password"
--vault-password-file ~/.vault_pass
# Tüm değişkenleri listele (hassas ortamlarda dikkatli kullanın)
ansible -i inventory/production webservers -m setup
--vault-password-file ~/.vault_pass | grep -A2 "db_"
# Playbook'u dry-run modunda çalıştır
ansible-playbook site.yml
--vault-password-file ~/.vault_pass
--check
--diff
Bir sorunla karşılaştığınızda vault dosyasının doğru şifrelenip şifrelenmediğini şöyle doğrulayabilirsiniz:
# Dosyanın vault formatında olduğunu doğrula
head -1 group_vars/production/vault.yml
# Çıktı: $ANSIBLE_VAULT;1.1;AES256 olmalı
# Dosyayı geçici olarak çöz ve içeriğine bak
ansible-vault view group_vars/production/vault.yml
Sık Yapılan Hatalar ve Çözümleri
Hata 1: Vault dosyasını Git’e şifresiz commit etmek
Bunu önlemek için Git pre-commit hook kullanabilirsiniz:
#!/bin/bash
# .git/hooks/pre-commit
# Vault şifrelenmemiş dosyaları engelle
for file in $(git diff --cached --name-only); do
if [[ "$file" == *"vault"* ]] || [[ "$file" == *"secrets"* ]]; then
if ! head -1 "$file" | grep -q "ANSIBLE_VAULT"; then
echo "HATA: $file dosyasi sifrelenmemis gorünüyor!"
echo "Önce 'ansible-vault encrypt $file' komutunu çalistirin."
exit 1
fi
fi
done
chmod +x .git/hooks/pre-commit
Hata 2: Vault parolasını environment variable’a yazarken history’e düşürmek
# YANLIS - bash history'e düser
export ANSIBLE_VAULT_PASSWORD="parolam"
# DOGRU - Önce dosyaya yaz, sonra oku
read -s -p "Vault parolasi: " VAULT_PASS
echo "$VAULT_PASS" > ~/.vault_pass
unset VAULT_PASS
chmod 600 ~/.vault_pass
Hata 3: Farklı Vault parolalarıyla şifrelenmiş dosyaları karıştırmak
Vault ID kullanmayan projelerde bu çok yaygın bir sorundur. Tüm vault dosyalarınızın aynı parolayla şifrelendiğinden emin olmak için:
# Tüm vault dosyalarını yeniden şifrele (parola degisikliginde)
find . -name "vault.yml" -exec ansible-vault rekey {} ;
Organize Bir Vault Yapısı Kurmak
Büyüyen projelerde vault dosyalarını düzenli tutmak kritik önem taşır. Önerilen dizin yapısı:
# Proje dizin yapisi
inventories/
production/
group_vars/
all/
vars.yml # Düz değişkenler
vault.yml # Şifreli değişkenler
webservers/
vars.yml
vault.yml
databases/
vars.yml
vault.yml
staging/
group_vars/
all/
vars.yml
vault.yml
Bu yapıda her ortamın kendi vault’u vardır ve farklı parolalarla korunabilir. Staging vault’unu daha geniş ekiple paylaşırken production vault’unu sadece senior sysadmin/DevOps ekibiyle sınırlı tutabilirsiniz.
Vault Rotasyonu ve Periyodik Bakım
Güvenlik politikanızın bir parçası olarak vault parolalarını periyodik olarak değiştirmeniz gerekir. Bu işlemi otomatize edebilirsiniz:
#!/bin/bash
# rotate_vault.sh
# Tüm vault dosyalarının parolasını değiştir
OLD_PASS_FILE="$1"
NEW_PASS_FILE="$2"
if [ -z "$OLD_PASS_FILE" ] || [ -z "$NEW_PASS_FILE" ]; then
echo "Kullanim: $0 eski_parola_dosyasi yeni_parola_dosyasi"
exit 1
fi
# Tüm vault dosyalarını bul ve parolayı değiştir
find . -name "vault.yml" | while read vault_file; do
echo "Isleniyor: $vault_file"
ansible-vault rekey
--vault-password-file "$OLD_PASS_FILE"
--new-vault-password-file "$NEW_PASS_FILE"
"$vault_file"
if [ $? -eq 0 ]; then
echo "Basarili: $vault_file"
else
echo "HATA: $vault_file rotasyonu basarisiz!"
exit 1
fi
done
echo "Tüm vault dosyalari basariyla güncellendi."
Sonuç
Ansible Vault, doğru kullanıldığında CI/CD pipeline’larınızda güvenlik ile pratiklik arasındaki dengeyi mükemmel kuran bir araçtır. Özetlemek gerekirse dikkat etmeniz gereken ana noktalar şunlardır:
- Vault dosyalarını ve normal değişken dosyalarını ayırın,
vault_prefix’iyle isimlendirme convention’ı benimseyin - Vault parolasını asla kaynak koduna commit etmeyin,
.gitignorekurallarınızı pre-commit hook’larla zorunlu hale getirin - CI/CD sistemlerinde parola dosyası yerine secret manager entegrasyonu tercih edin, en azından platform’un native secret storage’ını kullanın
- Farklı ortamlar için farklı vault parolaları kullanın, böylece dev erişimini production’dan izole edersiniz
- Vault parolalarını periyodik olarak rotate edin ve bu süreci script’lerle otomatize edin
- Ekip üyesi ayrılmalarında hemen rekey yapın, bu güvenlik hijyeninin zorunlu bir parçasıdır
Başlangıçta fazla karmaşık gelebilir, ama bir kez oturduğunda Ansible Vault ekibin günlük iş akışına doğal biçimde entegre olur. Artık “bu şifreyi nereye yazsam?” sorusuyla uğraşmak yerine, enerjinizi gerçek mühendislik problemlerine harcarsınız.
