GNU/Linux >> LINUX-Kenntnisse >  >> Linux

RHCE Ansible Series #7:Jinja2-Vorlagen

Im vorherigen Tutorial zur Entscheidungsfindung in Ansible haben Sie gelernt, wie Sie einfache Dateiänderungen mithilfe der blockinfile vornehmen oder inline Ansible-Module.

In diesem Tutorial erfahren Sie, wie Sie Jinja2 verwenden Templating-Engine, um kompliziertere und dynamischere Dateiänderungen durchzuführen.

Sie erfahren, wie Sie auf Variablen und Fakten in Jinja2-Vorlagen zugreifen. Außerdem lernen Sie, wie Sie bedingte Anweisungen und Schleifenstrukturen in Jinja2 verwenden.

Um die Beispiele in diesem Tutorial auszuprobieren, sollten Sie die gesamte RHCE Ansible-Tutorial-Reihe in der richtigen Reihenfolge befolgen.

Zugriff auf Variablen in Jinja2

Ansible sucht in Ihrem Projektverzeichnis oder in einem Verzeichnis namens templates nach jinja2-Vorlagendateien unter Ihrem Projektverzeichnis.

Lassen Sie uns ein Vorlagenverzeichnis erstellen, um die Dinge sauberer und organisierter zu halten:

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

Erstellen Sie nun Ihr erstes Jinja2-Template mit dem Namen index.j2 :

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

Beachten Sie, dass Dateinamen von Jinja2-Vorlagen mit der Erweiterung .j2 enden müssen.

Der inventar_hostname ist eine weitere in Ansible integrierte (auch bekannt als spezielle oder magische) Variable, die auf den „aktuellen“ Host verweist, der im Spiel durchlaufen wird. Die webserver_message ist eine Variable, die Sie in Ihrem Playbook definieren.

Gehen Sie nun einen Schritt zurück in Ihr Projektverzeichnis und erstellen Sie die folgende 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

Beachten Sie, dass die httpd Paket wurde bereits in einem früheren Tutorial installiert.

In diesem Playbook stellen Sie zunächst sicher, dass Apache in der ersten Aufgabe Start httpd ausgeführt wird . Verwenden Sie dann die Vorlage Modul in der zweiten Aufgabe Create index.html Verwenden Sie Jinja2, um die index.j2 zu verarbeiten und zu übertragen Von Ihnen erstellte Jinja2-Vorlagendatei zum Ziel /var/www/html/index.html .

Fahren Sie fort und führen Sie das Playbook aus:

[[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

Soweit sieht alles gut aus; Lassen Sie uns einen schnellen Ad-hoc-Ansible-Befehl ausführen, um den Inhalt von index.html zu überprüfen auf den Knoten des Webservers:

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

Tolle! Beachten Sie, wie Jinja2 die Werte von inventory_hostname abrufen konnte eingebaute Variable und die webserver_message Variable in Ihrem Playbook.

Sie können auch den curl verwenden Befehl, um zu sehen, ob Sie eine Antwort von beiden Webservern erhalten:

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

Zugriff auf Fakten in Jinja2

Sie können auf Fakten in Jinja2-Vorlagen genauso zugreifen wie auf Fakten aus Ihrem Playbook.

Wechseln Sie zur Demonstration zu Ihren Vorlagen Verzeichnis und erstellen Sie die info.j2 Jinja2-Datei mit folgendem Inhalt:

[[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'] }}

Beachten Sie, dass info.j2 greift auf acht verschiedene Fakten zu. Gehen Sie nun zurück in Ihr Projektverzeichnis und erstellen Sie die folgende server-info.yml Spielbuch:

[[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

Beachten Sie, dass Sie /tmp/server-info.txt erstellen auf allen Hosts basierend auf info.j2 Vorlagendatei. Fahren Sie fort und führen Sie das Playbook aus:

[[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

Alles sieht gut aus! Lassen Sie uns nun einen schnellen Ad-hoc-Befehl ausführen, um den Inhalt der Datei /tmp/server-info.txt zu untersuchen Datei auf einem der Knoten:

[[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

Wie Sie sehen, konnte Jinja2 auf alle Fakten zugreifen und diese verarbeiten.

Bedingte Anweisungen in Jinja2

Sie können das if verwenden bedingte Anweisung in Jinja2 zum Testen verschiedener Bedingungen und zum Vergleichen von Variablen. Auf diese Weise können Sie Ihren Dateivorlagen-Ausführungsablauf gemäß Ihren Testbedingungen bestimmen.

Rufen Sie zur Demonstration Ihre Vorlagen auf Verzeichnis und erstellen Sie die folgende selinux.j2 Vorlage:

[[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 %}

Die erste Anweisung in der Vorlage erstellt eine neue Variable selinux_statusand setzen Sie seinen Wert auf ansible_facts['selinux']['status'] .

Sie verwenden dann selinux_status in Ihrem wenn Testbedingung, um festzustellen, ob SELinux aktiviert, deaktiviert oder nicht installiert ist. In jedem der drei unterschiedlichen Fälle zeigen Sie eine Meldung an, die den Status von Selinux widerspiegelt.

Beachten Sie, wie das if -Anweisung in Jinja2 ahmt Pythons if nach Erklärung; vergessen Sie nur nicht, {% endif %} zu verwenden .

Gehen Sie nun zurück in Ihr Projektverzeichnis und erstellen Sie die folgende selinux-status.yml Spielbuch:

[[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

Fahren Sie fort und führen Sie das Playbook aus:

[[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  

Aus der Playbook-Ausgabe; Sie können sehen, dass SELinux auf beiden node1 aktiviert ist und Knoten3 . Ich habe SELinux auf node2 deaktiviert bevor Sie das Playbook und node4 ausführen hat SELinux nicht installiert, da Ubuntu AppArmor anstelle von SELinux verwendet.

Schließlich können Sie den folgenden Ad-hoc-Befehl ausführen, um den Inhalt von selinux.out zu untersuchen auf allen verwalteten Hosts:

[[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"

Schleife in Jinja2

Sie können für verwenden -Anweisung in Jinja2, um Elemente in einer Liste, einem Bereich usw. zu durchlaufen. Beispielsweise wird die folgende for-Schleife über die Zahlen im Bereich(1,11) iterieren und zeigt daher die Zahlen von 1->10:

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

Beachten Sie, wie die for-Schleife in Jinja2 die Syntax der for-Schleife von Python nachahmt; Vergessen Sie auch hier nicht, die Schleife mit {% endfor %} zu beenden .

Lassen Sie uns nun ein vollständiges Beispiel erstellen, das die Leistungsfähigkeit von for-Schleifen in Jinja2 demonstriert. Wechseln Sie in Ihr Vorlagenverzeichnis und erstellen Sie die folgende hosts.j2 Vorlagendatei:

[[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 %}

Beachten Sie, dass Sie hier eine neue eingebaute spezielle (magische) Variable hostvars verwendet haben Das ist im Grunde ein Wörterbuch, das alle Hosts im Inventar und ihnen zugewiesene Variablen enthält.

Sie haben alle Hosts in Ihrem Inventar durchlaufen und dann für jeden Host; Sie haben den Wert von drei Variablen angezeigt:

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

Beachten Sie auch, dass Sie diese drei Variablen nebeneinander in dieselbe Zeile einfügen müssen, damit sie dem Format von /etc/hosts entsprechen Datei.

Gehen Sie nun zurück zu Ihrem Projektverzeichnis und erstellen Sie die folgende local-dns.yml Spielbuch:

[[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

Fahren Sie dann fort und führen Sie das Playbook aus:

[[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 

Soweit sieht alles gut aus; Führen Sie nun den folgenden Ad-hoc-Befehl aus, um zu überprüfen, ob /etc/hosts Datei wird auf Knoten1 ordnungsgemäß aktualisiert :

[[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

Perfekt! Sieht korrekt formatiert aus, wie Sie es erwartet haben.

Ich hoffe, Sie erkennen jetzt die Leistungsfähigkeit von Jinja2-Vorlagen in Ansible. Bleiben Sie dran für das nächste Tutorial, in dem Sie lernen, sensible Informationen und Dateien mit Ansible Vault zu schützen.


Linux
  1. Dekonstruktion eines Ansible-Playbooks

  2. YAML für Ansible verstehen

  3. RHCE Ansible Series #8:Verschlüsseln von Inhalten mit Ansible Vault

  4. RHCE Ansible Series #6:Entscheidungsfindung in Ansible

  5. RHCE Ansible Series #5:Ansible Loops

So verwenden Sie die Jinja2-Vorlage in Ansible

Eine Einführung in Ansible-Fakten

RHCE Ansible Series #2:Ausführen von Ad-hoc-Befehlen

RHCE Ansible Serie Nr. 1:Sag Hallo zu Ansible

RHCE Ansible Series #3:Ansible Playbooks

RHCE Ansible Series #12:Ansible-Fehlerbehebung