Ansible Jinja2-Vorlagen

AnsibleAnsibleBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab werden Sie Jinja2 erkunden, den leistungsstarken Templating-Engine (Vorlagen-Engine), der von Ansible verwendet wird. Jinja2 ermöglicht es Ihnen, dynamischen Inhalt zu erstellen, wodurch Ihre Ansible-Playbooks flexibler und anpassungsfähiger werden. Am Ende dieses Labs werden Sie verstehen, wie Sie die Jinja2-Syntax in Ansible verwenden, einschließlich Variablen, Filtern, Bedingungen und Schleifen. Mit diesem Wissen können Sie dynamischere und effizientere Ansible-Playbooks und -Rollen erstellen.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL ansible(("Ansible")) -.-> ansible/PlaybookEssentialsGroup(["Playbook Essentials"]) ansible(("Ansible")) -.-> ansible/ModuleOperationsGroup(["Module Operations"]) ansible/ModuleOperationsGroup -.-> ansible/template("Generate Files from Templates") ansible/PlaybookEssentialsGroup -.-> ansible/loop("Iteration") ansible/PlaybookEssentialsGroup -.-> ansible/playbook("Execute Playbook") subgraph Lab Skills ansible/template -.-> lab-390470{{"Ansible Jinja2-Vorlagen"}} ansible/loop -.-> lab-390470{{"Ansible Jinja2-Vorlagen"}} ansible/playbook -.-> lab-390470{{"Ansible Jinja2-Vorlagen"}} end

Grundlagen von Jinja2 verstehen

Jinja2 ist eine moderne und designerfreundliche Templating-Sprache (Vorlagen-Sprache) für Python, die an den Django-Templates orientiert ist. In Ansible wird Jinja2 verwendet, um Dateien zu templaten, dynamische Play-Strukturen zu erstellen und vieles mehr.

Beginnen wir damit, eine einfache Jinja2-Vorlage zu erstellen. Zunächst navigieren Sie in Ihr Projektverzeichnis:

cd ~/project

Jetzt erstellen wir ein Verzeichnis für unsere Vorlagen:

mkdir templates
cd templates

Erstellen Sie eine neue Datei mit dem Namen hello.j2:

nano hello.j2

Fügen Sie den folgenden Inhalt hinzu:

Hello, {{ name }}!

Today is {{ ansible_date_time.date }}.
Your home directory is {{ ansible_env.HOME }}.

Speichern Sie die Datei und verlassen Sie den nano-Editor (Strg+X, dann Y, dann Eingabe).

In dieser Vorlage:

  • {{ name }} ist eine Variable, die beim Rendern der Vorlage durch einen tatsächlichen Wert ersetzt wird.
  • {{ ansible_date_time.date }} und {{ ansible_env.HOME }} sind Ansible-Facts, die automatisch befüllt werden.

Jetzt erstellen wir ein Playbook, um diese Vorlage zu verwenden. Gehen Sie zurück in das Projektstammverzeichnis und erstellen Sie eine neue Datei mit dem Namen use_template.yml:

cd ~/project
nano use_template.yml

Fügen Sie den folgenden Inhalt hinzu:

---
- name: Use Jinja2 template
  hosts: localhost
  vars:
    name: "Ansible Learner"
  tasks:
    - name: Create file from template
      template:
        src: templates/hello.j2
        dest: /tmp/hello.txt

Dieses Playbook verwendet das template-Modul, um unsere Jinja2-Vorlage zu rendern und eine Datei unter /tmp/hello.txt zu erstellen.

Führen Sie das Playbook aus:

ansible-playbook use_template.yml

Nachdem Sie das Playbook ausgeführt haben, überprüfen Sie den Inhalt der erstellten Datei:

cat /tmp/hello.txt

Sie sollten die gerenderte Vorlage sehen, bei der die Variable und die Fakten durch tatsächliche Werte ersetzt wurden.

Verwendung von Jinja2-Filtern

Jinja2-Filter sind Funktionen, die auf Variablen angewendet werden können. Sie werden von der Variable durch ein senkrechtes Strichzeichen (|) getrennt. Ansible enthält viele integrierte Filter, und Sie können auch eigene benutzerdefinierte Filter erstellen.

Erstellen wir eine neue Vorlage, die einige häufige Filter demonstriert. Erstellen Sie eine neue Datei mit dem Namen filters.j2:

cd ~/project/templates
nano filters.j2

Fügen Sie den folgenden Inhalt hinzu:

1. Uppercase filter: {{ name | upper }}
2. Length filter: {{ name | length }}
3. Default filter: {{ optional_var | default('No value provided') }}
4. Join filter: {{ fruits | join(', ') }}
5. Random item: {{ fruits | random }}
6. First item: {{ fruits | first }}
7. JSON encode: {{ complex_data | to_json }}

Jetzt erstellen wir ein Playbook, um diese Vorlage zu verwenden. Gehen Sie zurück in das Projektstammverzeichnis und erstellen Sie eine neue Datei mit dem Namen use_filters.yml:

cd ~/project
nano use_filters.yml

Fügen Sie den folgenden Inhalt hinzu:

---
- name: Use Jinja2 filters
  hosts: localhost
  vars:
    name: "ansible learner"
    fruits:
      - apple
      - banana
      - cherry
    complex_data:
      key1: value1
      key2:
        - item1
        - item2
  tasks:
    - name: Create file from template
      template:
        src: templates/filters.j2
        dest: /tmp/filters.txt

    - name: Display file contents
      command: cat /tmp/filters.txt
      register: file_contents

    - name: Show file contents
      debug:
        var: file_contents.stdout_lines

Dieses Playbook wendet verschiedene Jinja2-Filter auf unsere Variablen an und zeigt die Ergebnisse an.

Führen Sie das Playbook aus:

ansible-playbook use_filters.yml

Die Ausgabe zeigt Ihnen, wie jeder Filter die Eingabedaten modifiziert. Dies demonstriert, wie Filter verwendet werden können, um Daten in Ihren Vorlagen zu manipulieren.

Jinja2-Bedingungen

Jinja2 ermöglicht es Ihnen, bedingte Anweisungen in Ihren Vorlagen zu verwenden. Dies ist besonders nützlich, wenn Sie Inhalte basierend auf bestimmten Bedingungen ein- oder ausschließen müssen.

Erstellen Sie eine neue Vorlagendatei mit dem Namen conditionals.j2:

cd ~/project/templates
nano conditionals.j2

Fügen Sie den folgenden Inhalt hinzu:

{% if user_type == 'admin' %}
Welcome, Administrator!
You have full access to the system.
{% elif user_type == 'user' %}
Welcome, User!
You have limited access to the system.
{% else %}
Welcome, Guest!
You have read-only access to the system.
{% endif %}

{% if fruits %}
Available fruits:
{% for fruit in fruits %}
  - {{ fruit }}
{% endfor %}
{% else %}
No fruits available.
{% endif %}

Jetzt erstellen wir ein Playbook, um diese Vorlage zu verwenden. Gehen Sie zurück in das Projektstammverzeichnis und erstellen Sie eine neue Datei mit dem Namen use_conditionals.yml:

cd ~/project
nano use_conditionals.yml

Fügen Sie den folgenden Inhalt hinzu:

---
- name: Use Jinja2 conditionals
  hosts: localhost
  vars:
    user_type: "admin"
    fruits:
      - apple
      - banana
      - cherry
  tasks:
    - name: Create file from template (admin)
      template:
        src: templates/conditionals.j2
        dest: /tmp/conditionals_admin.txt

    - name: Create file from template (user)
      template:
        src: templates/conditionals.j2
        dest: /tmp/conditionals_user.txt
      vars:
        user_type: "user"

    - name: Create file from template (guest)
      template:
        src: templates/conditionals.j2
        dest: /tmp/conditionals_guest.txt
      vars:
        user_type: "guest"
        fruits: []

    - name: Display file contents
      command: "cat {{ item }}"
      loop:
        - /tmp/conditionals_admin.txt
        - /tmp/conditionals_user.txt
        - /tmp/conditionals_guest.txt
      register: file_contents

    - name: Show file contents
      debug:
        var: file_contents.results[item].stdout_lines
      loop: [0, 1, 2]

Dieses Playbook erstellt drei verschiedene Dateien unter Verwendung der gleichen Vorlage, aber mit unterschiedlichen Variablenwerten, was zeigt, wie die bedingten Anweisungen in der Vorlage funktionieren.

Führen Sie das Playbook aus:

ansible-playbook use_conditionals.yml

Die Ausgabe zeigt Ihnen, wie sich der Vorlageninhalt basierend auf den verschiedenen Bedingungen ändert.

Jinja2-Schleifen

Jinja2 bietet Schleifenkonstrukte, die es Ihnen ermöglichen, über Listen und Dictionaries (Wörterbücher) zu iterieren. Dies ist besonders nützlich, wenn Sie wiederholten Inhalt basierend auf variablen Daten generieren müssen.

Erstellen Sie eine neue Vorlagendatei mit dem Namen loops.j2:

cd ~/project/templates
nano loops.j2

Fügen Sie den folgenden Inhalt hinzu:

1. Simple loop:
{% for item in simple_list %}
   - {{ item }}
{% endfor %}

2. Loop with index:
{% for item in simple_list %}
   {{ loop.index }}. {{ item }}
{% endfor %}

3. Loop over a dictionary:
{% for key, value in simple_dict.items() %}
   {{ key }}: {{ value }}
{% endfor %}

4. Nested loop:
{% for category, items in nested_dict.items() %}
   {{ category }}:
   {% for item in items %}
     - {{ item }}
   {% endfor %}
{% endfor %}

5. Conditional in loop:
{% for item in simple_list %}
   {% if loop.first %}First item: {% endif %}
   {% if loop.last %}Last item: {% endif %}
   {{ item }}
{% endfor %}

Jetzt erstellen wir ein Playbook, um diese Vorlage zu verwenden. Gehen Sie zurück in das Projektstammverzeichnis und erstellen Sie eine neue Datei mit dem Namen use_loops.yml:

cd ~/project
nano use_loops.yml

Fügen Sie den folgenden Inhalt hinzu:

---
- name: Use Jinja2 loops
  hosts: localhost
  vars:
    simple_list:
      - apple
      - banana
      - cherry
    simple_dict:
      name: John Doe
      age: 30
      city: New York
    nested_dict:
      fruits:
        - apple
        - banana
      vegetables:
        - carrot
        - potato
  tasks:
    - name: Create file from template
      template:
        src: templates/loops.j2
        dest: /tmp/loops.txt

    - name: Display file contents
      command: cat /tmp/loops.txt
      register: file_contents

    - name: Show file contents
      debug:
        var: file_contents.stdout_lines

Dieses Playbook demonstriert verschiedene Möglichkeiten, Schleifen in Jinja2-Vorlagen zu verwenden.

Führen Sie das Playbook aus:

ansible-playbook use_loops.yml

Die Ausgabe zeigt Ihnen, wie die verschiedenen Schleifenkonstrukte in der Vorlage Inhalt basierend auf den bereitgestellten Variablen generieren.

Fortgeschrittene Jinja2-Techniken

In diesem letzten Schritt werden wir einige fortgeschrittene Jinja2-Techniken erkunden, einschließlich Makros und Filtern. Makros sind wiederverwendbare Vorlagenschnipsel, ähnlich wie Funktionen in Programmiersprachen.

Erstellen Sie eine neue Vorlagendatei mit dem Namen advanced.j2:

cd ~/project/templates
nano advanced.j2

Fügen Sie den folgenden Inhalt hinzu:

{% macro render_list(title, items) %}
{{ title }}:
{% for item in items %}
  - {{ item }}
{% endfor %}
{% endmacro %}

1. Using a macro:
{{ render_list("Fruits", fruits) }}

{{ render_list("Vegetables", vegetables) }}

2. Using set:
{% set greeting = "Hello, " + name + "!" %}
{{ greeting }}

3. Custom filter (defined in playbook):
{{ complex_data | to_nice_json }}

4. Whitespace control:
{% for item in fruits -%}
    {{ item }}
{%- if not loop.last %}, {% endif %}
{%- endfor %}

5. Raw block (no processing):
{% raw %}
This {{ will_not_be_processed }}
{% endraw %}

6. Include another template:
{% include 'simple_include.j2' %}

Jetzt erstellen wir die einfache Einbeziehung-Datei. Erstellen Sie eine neue Datei mit dem Namen simple_include.j2:

nano simple_include.j2

Fügen Sie den folgenden Inhalt hinzu:

This is content from an included template.
Current user: {{ ansible_user_id }}

Jetzt erstellen wir ein Playbook, um diese fortgeschrittene Vorlage zu verwenden. Gehen Sie zurück in das Projektstammverzeichnis und erstellen Sie eine neue Datei mit dem Namen use_advanced.yml:

cd ~/project
nano use_advanced.yml

Fügen Sie den folgenden Inhalt hinzu:

---
- name: Use advanced Jinja2 techniques
  hosts: localhost
  vars:
    name: "Ansible Expert"
    fruits:
      - apple
      - banana
      - cherry
    vegetables:
      - carrot
      - potato
      - broccoli
    complex_data:
      key1: value1
      key2:
        - item1
        - item2
    custom_filters:
      to_nice_json: "{{ '(' ~ ((complex_data | to_json) | replace('\"', '\\\"')) ~ ')' | from_json | to_nice_json }}"
  tasks:
    - name: Create file from template
      template:
        src: templates/advanced.j2
        dest: /tmp/advanced.txt

    - name: Display file contents
      command: cat /tmp/advanced.txt
      register: file_contents

    - name: Show file contents
      debug:
        var: file_contents.stdout_lines

Dieses Playbook demonstriert fortgeschrittene Jinja2-Techniken, einschließlich Makros, benutzerdefinierten Filtern, Leerzeichenkontrolle und Einbeziehung anderer Vorlagen.

Führen Sie das Playbook aus:

ansible-playbook use_advanced.yml

Die Ausgabe zeigt Ihnen, wie diese fortgeschrittenen Jinja2-Techniken in der Praxis funktionieren.

Zusammenfassung

In diesem Lab haben Sie die Jinja2-Templating-Funktionalität in Ansible untersucht und eine Vielzahl von Features und Techniken kennengelernt. Hier sind die wichtigsten Erkenntnisse:

  1. Grundlegende Jinja2-Syntax: Sie haben gelernt, wie Sie Variablen und Ansible-Facts in Vorlagen verwenden.
  2. Jinja2-Filter: Sie haben verschiedene integrierte Filter erkundet, um Daten innerhalb von Vorlagen zu manipulieren.
  3. Bedingungen: Sie haben if-elif-else-Anweisungen verwendet, um dynamischen Inhalt basierend auf Bedingungen zu erstellen.
  4. Schleifen: Sie haben gelernt, wie Sie über Listen und Dictionaries iterieren, einschließlich geschachtelter Schleifen und Schleifensteuerungen.
  5. Fortgeschrittene Techniken: Sie haben Makros, benutzerdefinierte Filter, Leerzeichenkontrolle, Raw-Blöcke und Vorlageneinbindung untersucht.

Diese Jinja2-Features ermöglichen es Ihnen, in Ansible hochdynamische und flexible Vorlagen zu erstellen. Sie können damit Konfigurationsdateien, Skripte und anderen Inhalt generieren, der sich an verschiedene Szenarien und Dateninputs anpassen kann.

Wenn Sie weiterhin mit Ansible arbeiten, werden Sie feststellen, dass die Beherrschung der Jinja2-Templating-Technik entscheidend für die Erstellung effizienter und anpassungsfähiger Playbooks und Rollen ist. Es ermöglicht Ihnen, kompakteres und wartbareres Code zu schreiben, die Wiederholung zu reduzieren und Ihre Ansible-Projekte skalierbarer zu gestalten.

Denken Sie daran, dass es, obwohl Jinja2 leistungsstark ist, wichtig ist, Flexibilität und Lesbarkeit auszubalancieren. Übermäßig komplexe Vorlagen können schwierig zu warten sein, also streben Sie immer nach Klarheit in Ihrem Vorlagendesign.

Üben Sie die Verwendung dieser Jinja2-Features in Ihren Ansible-Projekten, und Sie werden in der Lage sein, zunehmend komplexe Automatisierungsaufgaben problemlos zu bewältigen.