Ansible import_role vs include_role: Static vs Dynamic Role Loading
By Luca Berton · Published 2024-01-01 · Category: installation
Complete comparison of Ansible import_role vs include_role. Understand static vs dynamic loading, variable scope, handler behavior, tag inheritance, loop support, and when to use each with practical examples and decision guide.
Ansible loads roles two ways: import_role (static, at parse time) and include_role (dynamic, at runtime). The difference affects tags, handlers, loops, conditionals, and error handling. Choosing wrong causes subtle bugs.
Quick Comparison
| Feature | import_role (static) | include_role (dynamic) | |---------|---------------------|----------------------| | When loaded | Parse time (before play starts) | Runtime (when task executes) | | Tags | Inherited by all tasks in role | Applied to include task only | | Handlers | Available globally | Available after include runs | | Loop support | ❌ No | ✅ Yes | | Conditional (when) | Applied to every task in role | Applied once to include decision | | Variable file loading | Immediate | Deferred | | --list-tasks | Shows role tasks | Shows "include_role: name=X" | | --list-tags | Shows role tags | Hidden | | Error on missing | Fails at parse time | Fails at runtime |
import_role: Static Loading
import_role loads the role at parse time — before any task runs. All tasks, handlers, and variables are merged into the play.
Tags Work as Expected
Conditionals Apply to Every Task
include_role: Dynamic Loading
include_role loads the role at runtime — only when the task executes. The role is treated as a single unit.
Loop Support
Dynamic Role Names
Tags Apply to the Include Task Only
Conditionals Apply Once
Handler Differences
import_role: Handlers Immediately Available
include_role: Handlers Available After Include
Selective Task Loading
Both support loading specific task files:
Decision Guide
Roles Section vs import/include
The traditional roles: section uses static loading (like import_role):
FAQ
Can I mix import_role and include_role in the same playbook?
Yes. Use import_role for core roles where you need tag filtering and handler availability, and include_role for conditional or looped role loading. Mixing is common and supported.
Why can't import_role use variable names?
import_role loads at parse time, before variables are resolved. The role name must be a literal string so Ansible can find and parse the role's files before any task runs.
Which is faster?
import_role has slightly less runtime overhead because parsing happens once upfront. include_role re-parses each time it executes, which matters in loops. For a single role inclusion, the difference is negligible.
Does apply: work with include_role?
Yes. apply: lets you add tags, become, and other keywords to all tasks inside an included role:
Conclusion
import_role (static) for predictable, tag-filterable role loading. include_role (dynamic) for loops, variable role names, and conditional loading. Default to import_role unless you need dynamic features — it has better tooling support and more predictable behavior.
Related Articles • Ansible import_tasks vs include_tasks • Ansible Roles: Complete Guide • Ansible Tags Guide • Ansible Playbook Structure Guide
Category: installation