cassette-betamaxTemplating use cases

1) Statik Dosya Kopyalama vs. Dinamik Template

  • copy Modülü: Ansible’daki copy modü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:

  1. src: index.html.j2 → Yereldeki Jinja2 şablonu (kaynak dosya).

  2. dest: /var/www/html/index.html → Hedef sunucuda oluşacak gerçek dosyanın konumu.

  3. Ansible, index.html.j2 iç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:

  1. Envanter (inventory) veya diğer değişken kaynaklarından (vars, group_vars, vb.) host bilgileri okunur.

  2. Jinja2 Motoru: index.html.j2 dosyasındaki {{ ... }} yerlerine host özelindeki değerler konur.

  3. Sonuç: Her sunucuya farklı içerik sahip bir index.html kopyalanmış olur.

    • Örnek: web1’de This is web1 server., web2’de This 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_port tanımlanmazsa varsayılan 6379 kullanılır.

b) Döngü Örneği: resolv.conf

  • nameservers bir liste olduğu varsayılırsa (ör. [ "8.8.8.8", "8.8.4.4" ]), döngü her eleman için bir nameserver satı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.j2 ile 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

  1. Ansible copy modülü → Dosyayı değiştirmeden kopyalar.

  2. Ansible template modülü → Dosyayı Jinja2 ile işler (değişkenleri yerleştirir), sonra kopyalar.

  3. .j2 uzantılı dosyalar → Jinja2 şablonları. İçinde {{ varname }} veya {% ... %} gibi ifade kullanabilirsiniz.

  4. inventory_hostname veya diğer Ansible değişkenleriyle her host’a özel içerik oluşturabilirsiniz.

chevron-rightUse Caseshashtag

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

Tü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 web1 ve web2 farklı domain’ler kullanacaksa, host_vars/web1.yml ve host_vars/web2.yml dosyalarına nginx_domain tanımları yapabilirsiniz. Alternatif olarak inventory satırlarında da (web1 ansible_host=... nginx_domain=web1.example.com) eklenebilir.

B) group_vars/dbservers.yml

Veritabanı 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ğin db1.yml’de 512M, db2.yml’de 1024M).


4) Template Dosyaları

A) templates/nginx.conf.j2

Basit 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

MySQL konfigürasyonu örneği:

  • bind-address, port, innodb_buffer_pool_size yine group_vars/dbservers.yml veya 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:

  1. İlk Play

    • Hedef: webservers grubu (web1, web2).

    • template modülü ile nginx.conf.j2 dosyasını /etc/nginx/nginx.conf olarak kopyalar.

    • Değişkenler: nginx_port, nginx_domain, nginx_ssl_enabled vs.

    • Handler: Restart nginx (konfig dosyası değişince Nginx yeniden başlasın).

  2. İkinci Play

    • Hedef: dbservers grubu (db1, db2).

    • template modülü ile my.cnf.j2 dosyasını /etc/my.cnf yoluna yerleştirir.

    • Değişkenler: mysql_bind_address, mysql_port, mysql_innodb_buffer_pool_size vs.

    • 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.conf dosyası, nginx.conf.j2 şablonu baz alınarak host’a özel nginx_domain, nginx_port vb. değerlerle oluşturulur.

    • Nginx restart edilir.

  • DB Sunucularda:

    • /etc/my.cnf dosyası, my.cnf.j2 şablonundan host’a özel mysql_bind_address, mysql_innodb_buffer_pool_size ile üretilir.

    • MySQL (mysqld) restart edilir.

Her makine, kendi konfigürasyonuna sahip olur.


7) Özet

  1. Vars (group_vars/host_vars) üzerinden her rol veya host grubuna özgü değişkenler atıyoruz (domain adı, port, bellek, vb.).

  2. Template (.j2) dosyalarında {{ variable }} veya Jinja2 koşulları/döngüleriyle dinamik kısımları tanımlıyoruz.

  3. Playbook içinde template modülüyle bu şablonları hedef sisteme kopyalıyoruz.

  4. 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

Was this helpful?