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