Ansible Loop: Grundlagen und Looping über mehrere Tasks

1 Oktober, 2026

Dirk Wening
Dirk Wening
Technical Writer

von | Okt. 1, 2026

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.
  • when wird 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 loop an include_tasks.
  • Ein eigener loop_var über loop_control verhindert Namenskonflikte mit item.

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

Das 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_reload

Wü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.

Lerne in unseren praxisnahen Ansible Trainings, wie du Server, Software und komplette IT-Workflows zuverlässig automatisierst.

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: site

Der 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_reload

Das 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=0

Fazit: 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!

Wie hat Dir unser Artikel gefallen?