Zuletzt aktualisiert: 1.10.2026 · Lesezeit: 4-6 Minuten
Mit einem Ansible Loop führst du einen Task für jedes Element einer Liste aus. Hier findest du die Grundlagen mit Praxisbeispielen und erfährst, wie du mit include_tasks auch über multiple Tasks loopst, die voneinander abhängen.
Die wichtigsten Punkte in 30 Sekunden
- Ein Ansible Loop führt einen Task für jedes Element einer Liste aus,
{{ item }}steht dabei für das aktuelle Element. - Die Liste kann direkt im Task stehen, aus einer Variablen kommen oder aus Dictionaries mit mehreren Werten pro Durchlauf bestehen.
whenwird in einem Loop bei jeder Wiederholung einzeln ausgewertet.- Für mehrere voneinander abhängige Tasks lagerst du diese in eine eigene Datei aus und hängst den
loopaninclude_tasks. - Ein eigener
loop_varüberloop_controlverhindert Namenskonflikte mititem.
Der Loop gehört zu den nützlichsten Werkzeugen in Ansible. Er sorgt dafür, dass ein Task mehrmals ausgeführt wird, einmal für jedes Element einer Liste. Das spart Schreibarbeit und macht Playbooks deutlich wartbarer. Dieser Artikel zeigt zunächst die Grundlagen und geht dann auf einen fortgeschrittenen Anwendungsfall ein: das Looping über eine ganze Kette zusammenhängender Tasks.
Ansible Loop auf einem einzelnen Task verwenden
Am häufigsten wird Loop genutzt, um ein einzelnes Modul mehrfach mit unterschiedlichen Werten aufzurufen.
- name: Mehrere Pakete installieren
ansible.builtin.apt:
name: "{{ item }}"
state: present
loop:
- nginx
- git
- curlDas entspricht drei separaten Aufrufen des apt-Moduls. Innerhalb der Loop verweist {{ item }} auf das aktuelle Element.
Loop über eine Variable
Du kannst die Liste auch aus einer Variablen ziehen statt sie direkt hinzuschreiben:
vars:
paketliste:
- nginx
- git
- curl
tasks:
- name: Pakete installieren
ansible.builtin.apt:
name: "{{ item }}"
state: present
loop: "{{ paketliste }}"Loop über eine Liste von Dictionaries
Sehr häufig genutzt, wenn mehrere Werte pro Durchlauf gebraucht werden:
- name: Nutzer anlegen
ansible.builtin.user:
name: "{{ item.name }}"
uid: "{{ item.uid }}"
groups: "{{ item.groups }}"
loop:
- { name: "alice", uid: 1001, groups: "admins" }
- { name: "fabian", uid: 1002, groups: "finance" }Bedingungen in Ansible Loops
when wird bei jeder Wiederholung einzeln ausgewertet:
- name: Nur bestimmte Pakete installieren
ansible.builtin.apt:
name: "{{ item }}"
state: present
loop:
- nginx
- git
- docker
when: item != "docker"Ansible Loop über multiple Tasks: mehrfach zusammenhängende Loops
Ein einfacher Loop eignet sich gut, wenn ein einzelner Task mehrfach ausgeführt werden soll. Schwieriger wird es, wenn mehrere Tasks voneinander abhängen. Zum Beispiel kann ein Task das Ergebnis (register) eines vorherigen Tasks für eine when-Bedingung benötigen.
Ein typisches Beispiel hierfür ist das Einrichten mehrerer Websites. Für jede Website soll ein Verzeichnis angelegt, eine vHost-Konfiguration erstellt und die Website aktiviert werden, sobald sich die vHost-Datei geändert hat.
- name: "create {{ site }} directory"
ansible.builtin.file:
path: "/var/www/{{ site }}"
state: directory
- name: "create {{ site }}"
ansible.builtin.template:
src: vhost.j2
dest: "/etc/apache2/sites-available/{{ site }}"
register: vhost
- name: "enable {{ site }}"
ansible.builtin.command: /usr/sbin/a2ensite "{{ site }}"
register: result
when: vhost.changed
changed_when: "'Enabling site' in result.stdout"
notify: apache_reloadWürde man hier jeden Task einzeln mit einem Loop versehen, müsste man die jeweiligen register-Ergebnisse für die einzelnen Durchläufe korrekt zuordnen. Das macht den Code unnötig kompliziert.

Die Lösung: include_tasks mit Loop
Hier kommt include_tasks ins Spiel. Damit können mehrere zusammengehörige Tasks in eine eigene Datei ausgelagert werden.
Der include_tasks Task selbst bekommt anschließend die loop Schleife. Dadurch wird die komplette Task-Datei für jedes Element der Liste einmal ausgeführt.
Das Hauptplaybook sieht so aus:
- ansible.builtin.set_fact:
sites:
- default
- icingaweb2
- name: create vhosts
ansible.builtin.include_tasks: create-vhosts.yml
loop: "{{ sites }}"
loop_control:
loop_var: siteDer eigene loop_var-Name (site statt des Standards item) sorgt dafür, dass es nicht zu Namenskonflikten kommt, falls die eingebundene Datei selbst irgendwann eine eigene Loop mit item bekommt.
Die Task-Datei create-vhosts.yml
Die anderen Tasks werden in create-vhosts.yml gespeichert:
- name: "create {{ site }} directory"
ansible.builtin.file:
path: "/var/www/{{ site }}"
state: directory
- name: "create {{ site }}"
ansible.builtin.template:
src: vhost.j2
dest: "/etc/apache2/sites-available/{{ site }}"
register: vhost
- name: "enable {{ site }}"
ansible.builtin.command: /usr/sbin/a2ensite "{{ site }}"
register: result
when: vhost.changed
changed_when: "'Enabling site' in result.stdout"
notify: apache_reloadDas Ergebnis im Playbook-Output
Das Ergebnis: Alle drei Tasks werden für jedes Element in Sites vollständig durchlaufen, inklusive korrekt zugeordnetem Register-Kontext.
TASK [set_fact] *********************************************
ok: [localhost]
TASK [create vhosts] ****************************************
included: /Users/dwening/Documents/netways/ansible_test/create-vhosts.yml for localhost => (item=default)
included: /Users/dwening/Documents/netways/ansible_test/create-vhosts.yml for localhost => (item=icingaweb2)
TASK [create default directory] *****************************
ok: [localhost]
TASK [create default] ***************************************
ok: [localhost]
TASK [enable default] ***************************************
ok: [localhost]
TASK [create icingaweb2 directory] **************************
ok: [localhost]
TASK [create icingaweb2] ************************************
ok: [localhost]
TASK [enable icingaweb2] ************************************
ok: [localhost]
PLAY RECAP **************************************************
localhost : ok=10 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0Fazit: include_tasks macht ganze Tasksequenzen loopbar
Loop ist im einfachen Fall schnell erklärt: eine Liste, ein Task, mehrere Durchläufe. Sobald jedoch mehrere Tasks mit Abhängigkeiten wiederholt werden sollen, reicht das direkte Loop am Task nicht mehr aus. Genau diese Lücke schließt die Kombination aus include_tasks und loop. Sie behandelt eine ganze Tasksequenz als Einheit und macht sie wiederholbar, ohne dass Code dupliziert werden muss oder Umwege über Jinja2 in when-Bedingungen nötig sind.
Du willst Ansible in deiner Umgebung einsetzen oder bestehende Playbooks aufräumen? Unsere Consultants unterstützen dich gerne dabei!
