Templating use cases
1) Statik Dosya Kopyalama vs. Dinamik Template
copy Modülü: Ansible’daki
copymodülü, yerel makinedeki bir dosyayı hedef sunucuya olduğu gibi kopyalar. Bu yöntem, dosyanın içeriğinde değişken kullanıp “sunucuya göre özelleştirme” yapmanıza izin vermez.template Modülü: İşte burada devreye “template” gelir. Dosyanız Jinja2 şablon formatında hazırlanır ve Ansible, o şablondaki değişkenleri hedef sunucuya ait değerlerle doldurur.
Örnek İhtiyaç:
Web sunucusuna yerleştireceğimiz index.html dosyasında, her sunucunun adını (hostname) dinamik olarak göstermek istiyoruz.
2) Jinja2 Şablonu Nedir?
Bir .j2 (veya .j2 uzantılı) dosyası düşünün. HTML, YAML, vb. herhangi bir metin formatında olabilir. İçinde Jinja2 sözdizimiyle değişken yerleştirebilirsiniz:
<!-- index.html.j2 -->
<!DOCTYPE html>
<html>
<body>
This is {{ inventory_hostname }} server.
</body>
</html>Burada {{ inventory_hostname }} Ansible’ın otomatik sağladığı bir değişkendir. Hostun adını (ör. “web1”) koyar.
3) Ansible’da Template Modülü Kullanmak
Playbook Örneği:
Açıklama:
src: index.html.j2→ Yereldeki Jinja2 şablonu (kaynak dosya).dest: /var/www/html/index.html→ Hedef sunucuda oluşacak gerçek dosyanın konumu.Ansible,
index.html.j2içindeki{{ inventory_hostname }}gibi değişkenleri uygun değerlerle interpole (değiştirir) edip kopyalar.
4) Nasıl Çalışır?
Playbook çalıştığında:
Envanter (inventory) veya diğer değişken kaynaklarından (vars, group_vars, vb.) host bilgileri okunur.
Jinja2 Motoru:
index.html.j2dosyasındaki{{ ... }}yerlerine host özelindeki değerler konur.Sonuç: Her sunucuya farklı içerik sahip bir
index.htmlkopyalanmış olur.Örnek: web1’de
This is web1 server., web2’deThis is web2 server.yazar.
Bu şekilde copy modülüyle ayrı ayrı “index_web1.html”, “index_web2.html” gibi dosyalar üretmek zorunda kalmazsınız. Tek bir şablon, tüm hostlar için uygun olacak şekilde değişkenlerle çalışır.
5) Biraz Daha Detay: Değişkenler, Filtreler, Koşullar
Jinja2 şablon içinde Ansible değişkenlerini kullanabilir, hatta Jinja2’ye ait filtreleri (| default, | upper vs.) veya if, for gibi yapıları kullanabilirsiniz.
a) Default Filtre Örneği
redis_porttanımlanmazsa varsayılan 6379 kullanılır.
b) Döngü Örneği: resolv.conf
nameserversbir liste olduğu varsayılırsa (ör.[ "8.8.8.8", "8.8.4.4" ]), döngü her eleman için birnameserversatırı ekler.
6) Şablon Dosyası Nereye Konur?
Basit projelerde, playbook’unuzla aynı dizinde veya “templates/” gibi klasörde tutabilirsiniz.
Roles kullanıyorsanız,
roles/myrole/templates/altında saklamak best practice’tir.
Dosya Adı: .j2 uzantısı kullanmak (örn. index.html.j2, nginx.conf.j2) en iyisidir. Hem siz hem Ansible, bunun bir Jinja2 şablonu olduğunu hemen anlarsınız.
7) Uygulama Senaryoları
Web Sunucu:
index.html.j2→ Her makinede farklı hostname görüntülemek.Nginx/Apache Config:
nginx.conf.j2→ Farklı domain adları, portlar, SSL ayarları.Redis/MySQL Config:
redis.conf.j2,my.cnf.j2→ Her database sunucusuna farklı bellek, port ayarları, IP adresleri atama.Network Ayar Dosyaları:
resolv.conf.j2ile dinamik DNS sunucuları ekleme.
Temel mantık hep aynı: Bir metin dosyası şablon (.j2), içinde değişkenli kısımlar. Ansible, template: modülüyle o değişkenleri doldurur ve dosyayı kopyalar.
8) Özet
Ansible copy modülü → Dosyayı değiştirmeden kopyalar.
Ansible template modülü → Dosyayı Jinja2 ile işler (değişkenleri yerleştirir), sonra kopyalar.
.j2 uzantılı dosyalar → Jinja2 şablonları. İçinde
{{ varname }}veya{% ... %}gibi ifade kullanabilirsiniz.inventory_hostname veya diğer Ansible değişkenleriyle her host’a özel içerik oluşturabilirsiniz.
Use Cases
Aşağıda, Nginx ve MySQL konfigürasyonlarını dinamikleştirmek için bir gerçekçi kullanım senaryosu (use case) örneği paylaşıyorum. İki farklı şablon (template) dosyası kullanacağız: biri nginx.conf.j2 (web sunucusu), diğeri my.cnf.j2 (MySQL veritabanı). Her sunucunun envanterde belirtilen değişkenlerine göre farklı ayarlar almasını sağlayacağız.
1) Klasör Yapısı (Örnek)
Basit bir Ansible projesi gibi düşünelim:
inventory: Ansible envanter dosyası (hangi host web, hangi host db).playbook.yml: Burada görevleri yazacağız (template modülü vb.).templates/: Şablon dosyalarımız (nginx.conf.j2,my.cnf.j2).group_vars/: Web sunucuları (webservers.yml) ve DB sunucuları (dbservers.yml) için değişken dosyaları.
2) Envanter (inventory)
Örneğin, iki web sunucusu (web1, web2) ve iki DB sunucusu (db1, db2) tanımlayalım:
Böylece webservers grubuna dahil host’lar ile dbservers grubuna dahil host’ları ayırdık.
3) group_vars Dosyaları
A) group_vars/webservers.yml
group_vars/webservers.ymlTüm web sunucular için ortak veya farklı değerleri burada girebiliriz. Örneğin her web sunucunun domain adı, port, SSL ayarı vb.:
Eğer
web1veweb2farklı domain’ler kullanacaksa,host_vars/web1.ymlvehost_vars/web2.ymldosyalarınanginx_domaintanımları yapabilirsiniz. Alternatif olarak inventory satırlarında da (web1 ansible_host=... nginx_domain=web1.example.com) eklenebilir.
B) group_vars/dbservers.yml
group_vars/dbservers.ymlVeritabanı sunucuları için farklı bellek (innodb-buffer-pool-size), IP adresi, port vb.:
İki DB sunucusu yine farklı bellek ayarlarına sahip olacaksa,
host_vars/üzerinden ayrıştırabilirsiniz (örneğindb1.yml’de 512M,db2.yml’de 1024M).
4) Template Dosyaları
A) templates/nginx.conf.j2
templates/nginx.conf.j2Basit bir Nginx konfigürasyon örneği:
{{ nginx_port }}→group_vars/webservers.yml’den değer okur (ör. 80).{{ nginx_ssl_enabled }}→ true/false. True ise 443 SSL ayarları eklenir.{{ nginx_domain }}→ Domain adı.
B) templates/my.cnf.j2
templates/my.cnf.j2MySQL konfigürasyonu örneği:
bind-address,port,innodb_buffer_pool_sizeyinegroup_vars/dbservers.ymlveya host bazlı ayarlardan gelir.| default("256M")ile tanımlanmamışsa 256M kullanılır.
5) Playbook (playbook.yml)
Aynı dosyada iki play tanımlayabiliriz: biri web sunucuları, diğeri DB sunucuları için. Örnek:
Açıklama:
İlk Play
Hedef:
webserversgrubu (web1, web2).templatemodülü ilenginx.conf.j2dosyasını/etc/nginx/nginx.confolarak kopyalar.Değişkenler:
nginx_port,nginx_domain,nginx_ssl_enabledvs.Handler:
Restart nginx(konfig dosyası değişince Nginx yeniden başlasın).
İkinci Play
Hedef:
dbserversgrubu (db1, db2).templatemodülü ilemy.cnf.j2dosyasını/etc/my.cnfyoluna yerleştirir.Değişkenler:
mysql_bind_address,mysql_port,mysql_innodb_buffer_pool_sizevs.Handler:
Restart mysql.
6) Çalıştırma ve Sonuç
Envanteriniz ve vars dosyalarınız hazır, playbook.yml de bu şekilde tanımlı. Komutu verin:
Web Sunucularda:
/etc/nginx/nginx.confdosyası,nginx.conf.j2şablonu baz alınarak host’a özelnginx_domain,nginx_portvb. değerlerle oluşturulur.Nginx restart edilir.
DB Sunucularda:
/etc/my.cnfdosyası,my.cnf.j2şablonundan host’a özelmysql_bind_address,mysql_innodb_buffer_pool_sizeile üretilir.MySQL (mysqld) restart edilir.
Her makine, kendi konfigürasyonuna sahip olur.
7) Özet
Vars (group_vars/host_vars) üzerinden her rol veya host grubuna özgü değişkenler atıyoruz (domain adı, port, bellek, vb.).
Template (.j2) dosyalarında
{{ variable }}veya Jinja2 koşulları/döngüleriyle dinamik kısımları tanımlıyoruz.Playbook içinde
templatemodülüyle bu şablonları hedef sisteme kopyalıyoruz.Servis restart gibi adımlarla değişiklikler aktif hale geliyor.
Bu yaklaşım sayesinde tek bir şablonla farklı sunuculara farklı değerler atayabilir, yönetimsel süreci oldukça basitleştirirsiniz.
Last updated