> For the complete documentation index, see [llms.txt](https://thorstenkramm.gitbook.io/saltstack/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://thorstenkramm.gitbook.io/saltstack/jinja.md).

# Jinja

![Die Python-Template-Engine](/files/-LbJ6uhFh6zNE3eQb-AN)

### Jinja in SLS-Dateien verwenden

Alls SLS-Dateien werden immer durch die 📖 [Jinja-Template-Engine](https://docs.saltproject.io/en/latest/topics/jinja/index.html) "gejagt". Jinja wird aktiv, sobald es die Zeichenketten `{{ }}` oder `{% %}` findet.&#x20;

Innerhalb von `{% %}` definieren Sie Logik oder weisen Variablen Werte zu, z.B. `{% set name='Salt' %}`

`{{ var }}` veranlasst ein Suchen und Ersetzen. Die Variable innerhalb der Klammern wird durch ihren Wert ersetzt.

{% hint style="danger" %}
Jinja kennt weder Yaml noch sonst eine Programmiersprache oder Konvention innerhalb einer verarbeiteten Datei. Das hat zur Folge, dass Jinja das übliche Kommentarzeichen `#` ignoriert. Sie können mit `# {{ var }}` nicht verhindern, dass die Variable ersetzt wird.&#x20;

Verwenden Sie stattdessen Kommentare innerhalb der Jinja-Klammern. `{# {{ var }} #}`
{% endhint %}

### Variablen

{% code title="/srv/salt/exmaples/hosts.sls" %}

```yaml
{% set domain = 'example.com' %}
gw:
  host.present:
    - ip: 192.168.1.1
    - names:
      - gw
      - gw.{{ domain }}
mail:
  host.present:
    - ip: 192.168.1.2
    - names:
      - mail
      - mail.{{ domain }}
```

{% endcode %}

#### 🧩 **Aufgabe**

Schauen Sie sich das Beispiel zu [Installation von Netdata](/saltstack/salt-states/shell-kommandos.md#beispiel-netdata) noch einmal an. Dort wird die Versionsnummer mehrfach wiederholt. Optimieren Sie diesen State, sodass die Netdata Version nur einmal über eine Jinja-Variable definiert wird.

### Fallunterscheidungen (if/else)

{% code title="/srv/salt/examples/apache.sls" %}

```yaml
apache:
  pkg.installed:
{% if grains['os'] == 'RedHat' %}
    - name: httpd
{% elif grains['os'] == 'Ubuntu' %}
    - name: apache2
{% endif %}
```

{% endcode %}

#### 🧩 **Aufgabe**

1. Erstellen Sie einen State in `init/ssh.sls`, welcher den SSH-Server und Client für die unterschiedlichen Distributionen installiert.&#x20;
2. Legen Sie anschließend einen State `init/init.sls` an, der alle im Ordner `init` gespeicherten States inkludiert. Ziel ist es, dass man mit `salt '*' state.apply init` alle Minions »initialisieren« kann, d. h. alle Basis-Konfigurationen werden angewendet.

<details>

<summary>Lösung</summary>

```yaml
#
# Install SSH Server and Client for different distributions
#
{% set ssh_pkg = salt['grains.filter_by']({
    'Debian': ['ssh'],
    'RedHat': ['openssh-server','openssh-clients'],
    'Suse': ['openssh-common'],
    'Arch': ['openssh']
  })
%}

install-ssh:
  pkg.installed:
    - pkgs: {{ ssh_pkg }}
```

</details>

{% hint style="success" %}
Alle Grains sind bereits all Standard-Variablen (Python Dictionary) in Jinja verfügbar.
{% endhint %}

{% hint style="info" %}
Die Einrückung der Jina-Anweisungen spielen keine Rolle. Die SLS-Datei wird erst von Jinja verarbeitet, wobei alle Jinja-Anweisungen inklusive der Steuerzeichen entfernt werden. Danach wird die Datei an den Yaml-Interpreter des Minions übergeben, der nichts davon weiß, dass die Datei vorher von Jinja "manipuliert" wurde.
{% endhint %}

### Schleifen

{% code title="/srv/salt/examples/users.sls" %}

```yaml
{% for user in ['moe','larry','curly'] %}
{{ user }}:
  group:
    - present
  user:
    - present
    - gid_from_name: True
    - require:
      - group: {{ user }}
{% endfor %}
```

{% endcode %}

### Mapping-Tabellen

In Kombination mit dem Modul kann man mit Jinja kann man Mappings ohne lange if-else-elseif-Konstruktionen erstellen. Wenn nichts anderes angegeben wird, wird das Grain `os_family` zum Filtern verwendet.

{% code title="/srv/salt/examples/apache-map.sls" %}

```yaml
{% set apache = salt['grains.filter_by']({
    'Debian': {'pkg': 'apache2', 'srv': 'apache2'},
    'RedHat': {'pkg': 'httpd', 'srv': 'httpd'},
}, default='Debian') %}
{{ apache.pkg }}:
  pkg.installed: []
```

{% endcode %}

<figure><img src="/files/g0TiHjNBQeThtf5f6iAw" alt=""><figcaption><p>Mapping-Tabelle in Aktion</p></figcaption></figure>

{% code title="/srv/salt/caddy/php.sls" %}

```yaml
include:
  - .init

php-fpm:
  pkg.installed: []

{% set fpm = salt['grains.filter_by']({
    'Debian': {
        'backend': 'unix //var/run/php/php7.3-fpm.sock'
    },
    'Ubuntu': {
        'backend': 'unix //var/run/php/php7.2-fpm.sock'
    },
    'Rocky': {
        'backend': '127.0.0.1:9000'
    }  
},grain='os') %}

extend:
  /etc/caddy/Caddyfile:
    file.managed:
        - contents: |
            :80 {
                root * /var/www
                php_fastcgi {{ fpm['backend'] }}
            }

/var/www/info.php:
  file.managed:
    - contents: <?php phpinfo(); ?>
```

{% endcode %}

### Salt-Module in Jinja aufrufen

```yaml
{% if 1 == salt['cmd.retcode']('test -f /tmp/woo.test') %}
ack:
  file.touch:
    - name: /tmp/woo.test
{% endif %}
```

### Bedingungen testen und abbrechen <a href="#bedingungen-testen-und-abbrechen" id="bedingungen-testen-und-abbrechen"></a>

```
{% if not grains.id in salt['pillar.get']('master:nodegroups:webserver', []) %}
always-fails:
  test.fail_without_changes:
    - name: Requirement not met
    - failhard: True
{% endif %}
```

#### Beispiel Java installieren <a href="#beispiel-java-installieren" id="beispiel-java-installieren"></a>

```
{% if grains['os'] == 'CentOS' %}
{% set name='java-1.8.0-openjdk-headless' %}
{% else %}
{% set name='default-jre-headless' %}
{% endif %}

{% if 0 != salt['cmd.retcode']('which java') %}
{{ name }}:
  pkg.installed: []
{% endif %}
```

### Jina Line -Statements

Wer viel Jina in SLS-Dateien verwendet, kann auf die öffnenden und schließenden Klammern `{% %}` verzichten, und die sogenannten [Line-Statements](https://jinja.palletsprojects.com/en/2.10.x/templates/#line-statements) aktivieren. Damit kann eine komplette Zeile als Jinja-Zeile gekennzeichnet werden.

{% code title="/etc/salt/master.d/jinja.conf" %}

```yaml
jinja_sls_env:
  line_statement_prefix: ';'
  line_comment_prefix: ';;'
```

{% endcode %}

{% code title="/srv/salt/examples/multiline.sls" %}

```yaml
;; This is a comment
; set var1 = ['ietm1','item2','item4']
; if grains['os_family'] == 'Debian'
;     do var1.append('Debian')
; endif
; set list = var1|join(',')
/tmp/dummy.txt:
  file.managed:
    - contents: {{list}}
```

{% endcode %}

### Variablen in Variablenzuweisung einfügen

Variablen können andere Variablen enthalten.&#x20;

```
{% set my_var = grains['oscodename'] %}
{% set some_var = "some string" + grains['os_family']
```

```yaml
{% if grains['os'] == 'Debian' %}
{% set url = "https://repo.zabbix.com/zabbix/5.0/debian/pool/main/z/zabbix-release/zabbix-release_5.0-2+debian" + grains['osrelease'] + "_all.deb" %}
{% elif grains['os'] == 'Ubuntu' %}
{% set url = "https://repo.zabbix.com/zabbix/5.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_5.0-1+" + grains['oscodename'] + "_all.deb"%}
{% endif %}
zabbix-repo:
  cmd.run:
    - cwd: /tmp
    - name: |
        set -e
        wget {{ url }}
        dpkg -i zabbix-release*.deb
        apt-get -y update
    - creates: /etc/apt/sources.list.d/zabbix.list
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://thorstenkramm.gitbook.io/saltstack/jinja.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
