Zmienne, fakty i szablony Jinja2

Zmienne, fakty i szablony Jinja2 w Ansible

Jednym z kluczowych elementów pracy z Ansible jest umiejętne wykorzystywanie zmiennych oraz szablonów Jinja2. To właśnie one pozwalają budować dynamiczne, elastyczne i wielokrotnego użytku konfiguracje. W tym artykule omówię różne typy zmiennych w Ansible, sposoby ich definiowania i nadpisywania, a także wykorzystanie silnika Jinja2 do generowania plików konfiguracyjnych.


1. Czym są zmienne w Ansible

Zmienne (variables) pozwalają przechowywać dane, które można wielokrotnie wykorzystać w zadaniach, rolach czy szablonach. Dzięki nim playbooki stają się bardziej uniwersalne i łatwe w utrzymaniu.

Zmienne mogą być zdefiniowane na wielu poziomach, m.in.:

  • w plikach group_vars/ i host_vars/,
  • w sekcji vars wewnątrz playbooka,
  • w roli (w defaults/ lub vars/),
  • za pomocą polecenia set_fact w trakcie działania zadania,
  • jako parametry przekazywane w linii komend (–extra-vars).

2. Definiowanie zmiennych w playbooku

Najprostszy sposób to zdefiniowanie zmiennych bezpośrednio w sekcji vars w playbooku.

Przykład:

– name: Example playbook with vars
  hosts: webservers
  vars:
    app_name: myapp
    nginx_port: 8080
  tasks:
    – name: Print application name
      ansible.builtin.debug:
        msg: „Application: {{ app_name }}, Port: {{ nginx_port }}”

Wartości zmiennych mogą być następnie wykorzystane w szablonach lub zadaniach.


3. Zmienne w plikach group_vars i host_vars

W większych projektach lepszym rozwiązaniem jest przechowywanie zmiennych w osobnych katalogach: group_vars/ oraz host_vars/. Pozwala to na przypisywanie różnych wartości w zależności od grupy hostów lub konkretnej maszyny.

Przykład struktury:

group_vars/
  webservers.yml
host_vars/
  web01.yml

group_vars/webservers.yml:
nginx_port: 80
app_env: production

host_vars/web01.yml:
nginx_port: 8080

Dzięki temu ten sam playbook może zachowywać się inaczej w zależności od środowiska.


4. Ustalanie zmiennych dynamicznie – set_fact

Zmienna może być utworzona lub zmieniona w trakcie wykonywania playbooka za pomocą modułu set_fact. To przydatne w sytuacjach, gdy wartość zależy od wyniku wcześniejszego zadania.

Przykład:
– name: Get current date
  ansible.builtin.command: date +%Y%m%d
  register: current_date

– name: Set dynamic variable
  ansible.builtin.set_fact:
    backup_file: „/backups/app_backup_{{ current_date.stdout }}.tar.gz”

– name: Display backup filename
  ansible.builtin.debug:
    msg: „{{ backup_file }}”

Zmienne utworzone przez set_fact są dostępne do końca wykonywania playbooka.


5. Fakty systemowe (facts)

Fakty (facts) to zmienne automatycznie zbierane przez Ansible podczas uruchamiania playbooka. Zawierają one informacje o systemie, takie jak wersja jądra, adres IP, architektura CPU czy nazwa hosta.

Fakty są dostępne w przestrzeni nazw ansible_*.

Przykład użycia:
– name: Display system facts
  hosts: all
  tasks:
    – name: Show hostname and IP
      ansible.builtin.debug:
        msg: „Host {{ ansible_hostname }} has IP {{ ansible_default_ipv4.address }}”

Fakty można też ręcznie zaktualizować przy użyciu modułu setup lub całkowicie wyłączyć ich zbieranie (gather_facts: no).


6. Szablony Jinja2

Szablony Jinja2 pozwalają generować pliki konfiguracyjne dynamicznie – na podstawie zmiennych, warunków i pętli. Pliki szablonów mają rozszerzenie .j2 i znajdują się zwykle w katalogu templates/ w obrębie roli.

Przykład szablonu nginx.conf.j2:

server {
  listen {{ nginx_port }};
  server_name {{ ansible_hostname }};
  root /var/www/{{ app_name }};

  location / {
    try_files $uri $uri/ =404;
  }
}

Szablon może zawierać także instrukcje warunkowe i pętle:

{% raw %}{% if app_env == „production” %}{% endraw %}
  error_log /var/log/nginx/error.log;
{% raw %}{% else %}{% endraw %}
  error_log /tmp/nginx_error.log;
{% raw %}{% endif %}{% endraw %}

Szablon jest wdrażany na serwer za pomocą modułu ansible.builtin.template:

– name: Deploy nginx config
  ansible.builtin.template:
    src: templates/nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify:
    – Restart nginx


7. Przykład: dynamiczne generowanie konfiguracji nginx

Połączenie zmiennych, faktów i Jinja2 pozwala tworzyć w pełni dynamiczne konfiguracje.

– name: Deploy web server configuration
  hosts: webservers
  vars:
    app_name: mysite
    nginx_port: 8080
  tasks:
    – name: Deploy nginx configuration
      ansible.builtin.template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify:
        – Restart nginx

Dzięki takiemu podejściu jeden szablon może obsługiwać wiele środowisk i serwerów z różnymi konfiguracjami portów, nazw hostów i katalogów.


8. Dobre praktyki przy pracy ze zmiennymi i szablonami

  • utrzymywanie zmiennych środowiskowych w group_vars/all.yml,
  • definiowanie domyślnych wartości w defaults/main.yml w roli,
  • stosowanie pełnych nazw modułów (np. ansible.builtin.template),
  • używanie filtrów Jinja2 do przetwarzania danych (np. to_json, upper, join),
  • unikanie nadpisywania zmiennych o tej samej nazwie na różnych poziomach,
  • testowanie szablonów lokalnie przy użyciu polecenia ansible-console lub renderowania przez Jinja CLI.

9. Podsumowanie

Zmiennie i szablony Jinja2 są sercem elastyczności Ansible. Pozwalają budować konfiguracje, które dostosowują się do środowiska, hosta i parametrów. W połączeniu z faktami systemowymi oraz możliwością dynamicznego tworzenia zmiennych przy użyciu set_fact, umożliwiają tworzenie w pełni zautomatyzowanych i inteligentnych playbooków. Świadome wykorzystanie Jinja2 pozwala zmniejszyć liczbę powtarzalnych plików i znacząco ułatwia utrzymanie infrastruktury jako kodu (IaC).

Przewijanie do góry