Import tenzij: geef de voorkeur aan statisch hergebruik in Ansible
import_tasks, import_role of de play-level roles-sectie voor herbruikbare Ansible-content. Gebruik include_tasks of include_role alleen wanneer dynamisch runtime-gedrag nodig is.Categories:
import_tasks, import_role of de play-level roles-sectie. Gebruik
include_tasks of include_role alleen wanneer je dynamisch runtime-gedrag
nodig hebt, zoals loopen, runtime bestandsselectie of conditionele inclusion op
basis van facts of resultaten van eerdere taken.Probleem
Ansible biedt zowel import_*- als include_*-vormen om taken en rollen te
hergebruiken.
Zonder een duidelijke regel ontstaat in codebases al snel een mix van statisch
en dynamisch hergebruik. Dat maakt playbooks moeilijker leesbaar, lastiger om
over te redeneren en ingewikkelder om te troubleshooten. Taken verschijnen dan
mogelijk niet meer duidelijk in --list-tasks, tags kunnen zich onverwacht
uiten en de uitvoering kan afhankelijk worden van runtime-status op manieren die
voor reviewers en operators minder goed vooraf zichtbaar zijn.
Context
Volgens de Ansible-documentatie is import_* statisch hergebruik en wordt het
verwerkt terwijl Ansible het playbook parseert. De geïmporteerde taken of
roltaken worden dan onderdeel van de play alsof ze daar direct waren
uitgeschreven.
Dat geeft praktische voordelen:
- Beter zichtbaar in
--list-tasksen--list-tags. - Betere ondersteuning voor
--start-at-task. - Eenvoudiger tag-gedrag omdat tags direct op de geïmporteerde child tasks worden toegepast.
- Voorspelbaardere structuur omdat de taakgrafiek al vóór uitvoering bekend is.
- Minder runtime-overhead, omdat imports lichter zijn dan includes.
De Ansible-documentatie vermeldt expliciet dat imports tijdens het parsen van het playbook worden voorverwerkt, terwijl includes dynamisch tijdens runtime worden verwerkt. Die documentatie vermeldt ook dat imports lichter en sneller zijn, terwijl includes meer beheer en bookkeeping vereisen.
De Red Hat COP-richtlijn laat eveneens een voorkeur zien voor een statische
structuur wanneer dat volstaat. Die richtlijn beveelt aan om in een playbook óf
de roles-sectie óf de tasks-sectie te gebruiken, niet allebei, en toont
import_role als het eenvoudigere tagmodel wanneer een playbook uit rollen is
opgebouwd.
Oplossing
- Gebruik standaard
import_tasksvoor herbruikbare task-bestanden. - Gebruik standaard
import_roleof de play-levelroles-sectie voor herbruikbare rollen. - Gebruik
include_tasksofinclude_rolealleen wanneer je dynamisch gedrag tijdens runtime nodig hebt. - Behandel dynamische inclusion als een uitzondering die door de use case moet worden gerechtvaardigd, niet als de normale stijl.
- Als je statische role-executie op play-niveau nodig hebt, geef dan de
voorkeur aan de
roles-sectie. Als je een rol in een specifieke volgorde binnen detasks-sectie nodig hebt, gebruik danimport_role. - Vermijd het mengen van statisch en dynamisch hergebruik in hetzelfde playbook tenzij daar een duidelijke reden voor is.
Voordelen
- Maakt de structuur van de play eerder zichtbaar.
- Verbetert leesbaarheid en reviewbaarheid.
- Maakt taaklijsten, taglijsten en taakselectie bruikbaarder.
- Vermindert verrassingen die worden veroorzaakt door uitbreiding pas tijdens runtime.
- Presteert meestal beter dan dynamische includes.
Wanneer include_* wel de juiste keuze is
Gebruik include_tasks of include_role wanneer het playbook echt dynamisch
runtime-gedrag nodig heeft.
Typische gevallen zijn:
- Loopen over een task-bestand of rol
include_*kan één keer per loop-item worden uitgevoerd.import_*kan niet in een loop worden gebruikt. - Een task-bestand tijdens runtime selecteren
Bijvoorbeeld provider-specifieke of platform-specifieke task-bestanden die
gekozen worden met
lookup('first_found')of een bestandsnaam afgeleid van facts. - Content alleen includen wanneer de runtime-status dat vereist Bijvoorbeeld wanneer de inclusion-beslissing afhangt van facts, geregistreerde resultaten of wijzigingen die eerdere taken in dezelfde play hebben aangebracht.
- Dynamische role-orkestratiepatronen Bijvoorbeeld een loop over acties waarbij elk item variabelen aan een included role doorgeeft.
- Specifieke handler-patronen die vereisen dat de include zelf wordt genotificeerd Bij dynamische includes is de include-task zelf wat tijdens runtime bestaat.
Als geen van deze gevallen van toepassing is, gebruik dan import.
Aanvullende richtlijn voor rollen
Voor rollen zijn er drie veelvoorkomende opties:
- Gebruik de play-level
roles-sectie voor normale statische rolsamenstelling. - Gebruik
import_rolewanneer de rol op een specifieke plaats binnen detasks-volgorde moet verschijnen. - Gebruik
include_rolealleen wanneer je dynamisch gedrag nodig hebt, zoals loopen of runtime-selectie.
Gebruik include_role niet alleen uit gewoonte. Als de rolnaam en de plaats in
uitvoering al bekend zijn wanneer het playbook wordt geschreven, is statische
compositie duidelijker.
Voorbeelden en implementatie
Geef de voorkeur aan import_tasks voor een vaste task-structuur
- name: Main tasks
hosts: all
gather_facts: false
tasks:
- name: Import install tasks
ansible.builtin.import_tasks: install.yml
- name: Import configure tasks
ansible.builtin.import_tasks: configure.yml
Dit is de normale keuze wanneer beide task-bestanden vooraf bekend zijn.
Gebruik include_tasks voor runtime bestandsselectie
- name: Main tasks
hosts: all
gather_facts: true
tasks:
- name: Include platform-specific tasks
ansible.builtin.include_tasks: >-
{{ lookup('first_found', params) }}
vars:
params:
files:
- "{{ ansible_facts['distribution'] }}.yml"
- "{{ ansible_facts['os_family'] }}.yml"
- default.yml
paths:
- "{{ role_path }}/tasks/setup"
Hier staat het geselecteerde bestand pas tijdens runtime vast, dus is
include_tasks het juiste hulpmiddel.
Geef de voorkeur aan import_role voor vaste role-executie in task-volgorde
- name: Configure servers
hosts: all
gather_facts: false
tasks:
- name: Import base role
ansible.builtin.import_role:
name: c2platform.core.base
- name: Import application role
ansible.builtin.import_role:
name: c2platform.app.web
Dit houdt de role-executie statisch en zichtbaar.
Gebruik include_role wanneer je over role-input loept
- name: Execute actions
hosts: all
gather_facts: false
tasks:
- name: Run action role per item
ansible.builtin.include_role:
name: mycollection.run
vars:
action: "{{ item }}"
loop: "{{ actions }}"
Dit is een geldige reden om include_role te gebruiken, omdat de rol één keer
per loop-item wordt uitgevoerd.
Gebruik de play-level roles-sectie voor eenvoudige samenstelling
- name: Build web server
hosts: web
gather_facts: false
roles:
- role: c2platform.core.base
- role: c2platform.web.apache
Dit is vaak de duidelijkste optie wanneer geen dynamisch gedrag nodig is.
Aanvullende informatie
- Reusing Ansible artifacts — Ansible Community Documentation
- import_tasks — Ansible Community Documentation
- include_tasks — Ansible Community Documentation
- import_role — Ansible Community Documentation
- include_role — Ansible Community Documentation
- Roles — Ansible Community Documentation
- Good Practices for Ansible — Red Hat COP
Feedback
Was deze pagina nuttig?
Fijn om te horen! Vertel ons alstublieft hoe we kunnen verbeteren.
Jammer om dat te horen. Vertel ons alstublieft hoe we kunnen verbeteren.