GNU/Linux >> Znalost Linux >  >> Linux

RHCE Ansible Series #7:Jinja2 šablony

V předchozím tutoriálu o rozhodování v Ansible jste se naučili, jak provádět jednoduché úpravy souborů pomocí blockinfile nebo inline Ansible moduly.

V tomto tutoriálu se naučíte používat Jinja2 šablonovací engine k provádění složitějších a dynamičtějších úprav souborů.

Dozvíte se, jak přistupovat k proměnným a faktům v šablonách Jinja2. Dále se naučíte, jak používat podmíněné příkazy a smyčkové struktury v Jinja2.

Chcete-li vyzkoušet příklady v tomto tutoriálu, měli byste sledovat celou sérii tutoriálů RHCE Ansible ve správném pořadí.

Přístup k proměnným v Jinja2

Ansible vyhledá soubory šablon jinja2 ve vašem projektovém adresáři nebo v adresáři s názvem templates v adresáři vašeho projektu.

Pojďme vytvořit adresář šablon, aby byla věc čistší a organizovanější:

[[email protected] plays]$ mkdir templates
[[email protected] plays]$ cd templates/

Nyní vytvořte svou první šablonu Jinja2 s názvem index.j2 :

[[email protected] templates]$ cat index.j2 
A message from {{ inventory_hostname }}
{{ webserver_message }}

Všimněte si, že názvy souborů šablon Jinja2 musí končit příponou .j2.

název_hostitele inventáře je další vestavěná proměnná Ansible (neboli speciální nebo magická), která odkazuje na toho „aktuálního“ hostitele, který je ve hře iterován. zpráva_webového_serveru je proměnná, kterou definujete ve svém playbooku.

Nyní se vraťte o krok zpět do adresáře projektu a vytvořte následující check-apache.yml :

[[email protected] plays]$ cat check-apache.yml 
---
- name: Check if Apache is Working
  hosts: webservers
  vars:
    webserver_message: "I am running to the finish line."
  tasks:
    - name: Start httpd
      service:
        name: httpd
        state: started

    - name: Create index.html using Jinja2
      template:
        src: index.j2
        dest: /var/www/html/index.html

Všimněte si, že httpd balíček byl již nainstalován v předchozím kurzu.

V této příručce se nejprve ujistěte, že Apache běží v první úloze Start httpd . Poté použijte šablonu modulu ve druhé úloze Create index.html pomocí Jinja2 ke zpracování a přenosu index.j2 Soubor šablony Jinja2, který jste vytvořili, do cílového umístění /var/www/html/index.html .

Pokračujte a spusťte příručku:

[[email protected] plays]$ ansible-playbook check-apache.yml 

PLAY [Check if Apache is Working] **********************************************

TASK [Gathering Facts] *********************************************************
ok: [node3]
ok: [node2]

TASK [Start httpd] *************************************************************
ok: [node2]
ok: [node3]

TASK [Create index.html using Jinja2] ******************************************
changed: [node3]
changed: [node2]

PLAY RECAP *********************************************************************
node2                      : ok=3    changed=1    unreachable=0    failed=0    skipped=0    
node3                      : ok=3    changed=1    unreachable=0    failed=0    skipped=0

Všechno zatím vypadá dobře; spusťte rychlý ad-hoc příkaz Ansible ke kontrole obsahu index.html na uzlech webových serverů:

[[email protected] plays]$ ansible webservers -m command -a "cat /var/www/html/index.html"
node3 | CHANGED | rc=0 >>
A message from node3
I am running to the finish line.
node2 | CHANGED | rc=0 >>
A message from node2
I am running to the finish line.

Úžasný! Všimněte si, jak Jinja2 dokázala získat hodnoty inventory_hostname vestavěná proměnná a zpráva_webového_serveru proměnná ve vaší příručce.

Můžete také použít zvlnění příkaz, abyste zjistili, zda dostanete odpověď z obou webových serverů:

[[email protected] plays]$ curl node2.linuxhandbook.local
A message from node2
I am running to the finish line.
[[email protected] plays]$ curl node3.linuxhandbook.local
A message from node3
I am running to the finish line.

Přístup k faktům v Jinja2

K faktům v šablonách Jinja2 můžete přistupovat stejným způsobem jako k faktům z vaší příručky.

Chcete-li to ukázat, přejděte na své šablony a vytvořte info.j2 Jinja2 soubor s následujícím obsahem:

[[email protected] templates]$ cat info.j2 
Server Information Summary
--------------------------

hostname={{ ansible_facts['hostname'] }}
fqdn={{ ansible_facts['fqdn'] }}
ipaddr={{ ansible_facts['default_ipv4']['address'] }}
distro={{ ansible_facts['distribution'] }}
distro_version={{ ansible_facts['distribution_version'] }}
nameservers={{ ansible_facts['dns']['nameservers'] }}
totalmem={{ ansible_facts['memtotal_mb'] }}
freemem={{ ansible_facts['memfree_mb'] }}

Všimněte si, že info.j2 přistupuje k osmi různým faktům. Nyní se vraťte do adresáře projektu a vytvořte následující server-info.yml příručka:

[[email protected] plays]$ cat server-info.yml 
---
- name: Server Information Summary
  hosts: all
  tasks:
   - name: Create server-info.txt using Jinja2
     template:
       src: info.j2
       dest: /tmp/server-info.txt

Všimněte si, že vytváříte /tmp/server-info.txt na všech hostitelích založených na info.j2 soubor šablony. Pokračujte a spusťte příručku:

[[email protected] plays]$ ansible-playbook server-info.yml 

PLAY [Server Information Summary] *******************************************

TASK [Gathering Facts] **********************************
ok: [node4]
ok: [node1]
ok: [node3]
ok: [node2]

TASK [Create server-info.txt using Jinja2] ********
changed: [node4]
changed: [node1]
changed: [node3]
changed: [node2]

PLAY RECAP *************************
node1                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    
node2                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    
node3                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    
node4                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0

Všechno vypadá dobře! Nyní spusťte rychlý ad-hoc příkaz ke kontrole obsahu /tmp/server-info.txt soubor na jednom z uzlů:

[[email protected] plays]$ ansible node1 -m command -a "cat /tmp/server-info.txt"
node1 | CHANGED | rc=0 >>
Server Information Summary
--------------------------

hostname=node1
fqdn=node1.linuxhandbook.local
ipaddr=10.0.0.5
distro=CentOS
distro_version=8.2
nameservers=['168.63.129.16']
totalmem=1896
freemem=1087

Jak můžete vidět, Jinja2 měl přístup ke všem faktům a zpracoval je.

Podmíněné příkazy v Jinja2

Můžete použít pokud podmíněný příkaz v Jinja2 pro testování různých podmínek a porovnávání proměnných. To vám umožní určit tok provádění šablony souboru podle vašich testovacích podmínek.

Chcete-li to předvést, přejděte do šablon a vytvořte následující selinux.j2 šablona:

[[email protected] templates]$ cat selinux.j2 
{% set selinux_status = ansible_facts['selinux']['status'] %}

{% if selinux_status == "enabled" %}
	"SELINUX IS ENABLED"
{% elif selinux_status == "disabled" %}
	"SELINUX IS DISABLED"
{% else %}
	"SELINUX IS NOT AVAILABLE"
{% endif %}

První příkaz v šabloně vytvoří novou proměnnou selinux_statusand nastavte jeho hodnotu na ansible_facts['selinux']['status'] .

Poté použijete selinux_status ve vašem pokud testovací podmínky pro zjištění, zda SELinux je povoleno, zakázáno nebo není nainstalováno. V každém ze tří různých případů zobrazíte zprávu, která odráží stav Selinuxu.

Všimněte si, jak pokud příkaz v Jinja2 napodobuje if Pythonu prohlášení; jen nezapomeňte použít {% endif %} .

Nyní se vraťte do adresáře projektu a vytvořte následující selinux-status.yml příručka:

[[email protected] plays]$ cat selinux-status.yml 
---
- name: Check SELinux Status
  hosts: all
  tasks:
    - name: Display SELinux Status
      debug:
        msg: "{{ ansible_facts['selinux']['status'] }}"

    - name: Create selinux.out using Jinja2
      template:
        src: selinux.j2
        dest: /tmp/selinux.out

Pokračujte a spusťte příručku:

[[email protected] plays]$ ansible-playbook selinux-status.yml 

PLAY [Check SELinux Status] ****************************************************

TASK [Gathering Facts] *********************************************************
ok: [node4]
ok: [node2]
ok: [node3]
ok: [node1]

TASK [Display SELinux Status] **************************************************
ok: [node1] => {
    "msg": "enabled"
}
ok: [node2] => {
    "msg": "disabled"
}
ok: [node3] => {
    "msg": "enabled"
}
ok: [node4] => {
    "msg": "Missing selinux Python library"
}

TASK [Create selinux.out using Jinja2] *****************************************
changed: [node4]
changed: [node1]
changed: [node3]
changed: [node2]

PLAY RECAP *********************************************************************
node1                      : ok=3    changed=1    unreachable=0    failed=0    skipped=0    
node2                      : ok=3    changed=1    unreachable=0    failed=0    skipped=0    
node3                      : ok=3    changed=1    unreachable=0    failed=0    skipped=0    node4                      : ok=3    changed=1    unreachable=0    failed=0    skipped=0  

Z výstupu playbooku; můžete vidět, že SELinux je povolen na obou uzlech1 a uzel3 . Zakázal jsem SELinux na node2 před spuštěním playbooku a node4 nemá nainstalovaný SELinux, protože Ubuntu místo SELinux používá AppArmor.

Nakonec můžete spustit následující ad-hoc příkaz ke kontrole obsahu selinux.out na všech spravovaných hostitelích:

[[email protected] plays]$ ansible all -m command -a "cat /tmp/selinux.out"
node4 | CHANGED | rc=0 >>

	"SELINUX IS NOT AVAILABLE"
 
node2 | CHANGED | rc=0 >>

	"SELINUX IS DISABLED"
 
node3 | CHANGED | rc=0 >>

	"SELINUX IS ENABLED"
 
node1 | CHANGED | rc=0 >>

	"SELINUX IS ENABLED"

Otáčení v Jinja2

Můžete použít pro příkaz v Jinja2 pro opakování položek v seznamu, rozsahu atd. Například následující cyklus for bude opakovat čísla v rozsahu (1,11) a zobrazí tedy čísla od 1->10:

{% for i in range(1,11) %}
	Number {{ i }}
{% endfor %}

Všimněte si, jak cyklus for v Jinja2 napodobuje syntaxi cyklu for Pythonu; znovu nezapomeňte ukončit smyčku pomocí {% endfor %} .

Nyní vytvoříme úplný příklad, který ukazuje sílu smyček for v Jinja2. Přejděte do adresáře šablon a vytvořte následující hosts.j2 soubor šablony:

[[email protected] templates]$ cat hosts.j2 
{% for host in groups['all'] %}
{{ hostvars[host].ansible_facts.default_ipv4.address }}  {{ hostvars[host].ansible_facts.fqdn }}  {{ hostvars[host].ansible_facts.hostname }}
{% endfor %}

Všimněte si, že jste použili novou vestavěnou speciální (magickou) proměnnou hostvars což je v podstatě slovník, který obsahuje všechny hostitele v inventáři a proměnné k nim přiřazené.

Iterovali jste všechny hostitele ve svém inventáři a poté pro každého hostitele; zobrazili jste hodnotu tří proměnných:

  1. {{ hostvars[host].ansible_facts.default_ipv4.address }}
  2. {{ hostvars[host].ansible_facts.fqdn }}
  3. {{ hostvars[host].ansible_facts.hostname }}

Všimněte si také, že tyto tři proměnné musíte zahrnout na stejný řádek vedle sebe, aby odpovídaly formátu souboru /etc/hosts soubor.

Nyní se vraťte do adresáře projektů a vytvořte následující local-dns.yml příručka:

[[email protected] plays]$ cat local-dns.yml 
---
- name: Dynamically Update /etc/hosts File
  hosts: all
  tasks:
    - name: Update /etc/hosts using Jinja2
      template:
        src: hosts.j2
        dest: /etc/hosts

Pak pokračujte a spusťte příručku:

[[email protected] plays]$ ansible-playbook local-dns.yml 

PLAY [Dynamically Update /etc/hosts File] *********************************************

TASK [Gathering Facts] ***************************
ok: [node4]
ok: [node2]
ok: [node1]
ok: [node3]

TASK [Update /etc/hosts using Jinja2] ***********************************************
changed: [node4]
changed: [node3]
changed: [node1]
changed: [node2]

PLAY RECAP **********************
node1                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    
node2                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    
node3                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    
node4                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0 

Všechno zatím vypadá dobře; nyní spusťte následující ad-hoc příkaz k ověření, že /etc/hosts soubor je správně aktualizován na uzlu1 :

[[email protected] plays]$ ansible node1 -m command -a "cat /etc/hosts"
node1 | CHANGED | rc=0 >>
10.0.0.5  node1.linuxhandbook.local  node1
10.0.0.6  node2.linuxhandbook.local  node2
10.0.0.7  node3.linuxhandbook.local  node3
10.0.0.8  node4.linuxhandbook.local  node4

Perfektní! Vypadá správně naformátovaný, jak jste očekávali.

Doufám, že si nyní uvědomujete sílu šablon Jinja2 v Ansible. Zůstaňte naladěni na další tutoriál, kde se naučíte chránit citlivé informace a soubory pomocí Ansible Vault.


Linux
  1. RHCE Ansible Series #8:Šifrování obsahu pomocí Ansible Vault

  2. RHCE Ansible Series #6:Rozhodování v Ansible

  3. RHCE Ansible série #5:Ansible smyčky

  1. RHCE Ansible Series #4:Ansible proměnné, fakta a registry

  2. RHCE Ansible Series #11:Správa systémů s Ansible

  3. RHCE Ansible Series #10:Role systému RHEL

  1. Deconstructing ansible playbook

  2. RHCE Ansible Series #9:Ansible Role

  3. Ansible:sudo bez hesla