Advanced 9 min · 2026-06-21

Ansible Handlers: Production Traps & flush_handlers to Fix Them

Master Ansible handlers and notifications: notify, listen, flush_handlers, ordering, and the fail-trap.

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Notes here come from systems that actually shipped.

Follow
Production
production tested
June 21, 2026
last updated
1,596
articles · all by Naren
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer

Handlers run only at the end of a play, not immediately after the task that notifies them. Use notify on a task to trigger one or more handlers by name. Use listen on a handler to allow multiple tasks to notify it via a common topic. Handlers are skipped if a task fails in the play (unless ignore_errors: yes or force_handlers: true is set). Use meta: flush_handlers to force all pending handlers to run immediately, e.g., before a task that depends on the change. Handler ordering is the order they are defined in the handlers block, not the order of notifications. Idempotency: handlers only run if the notifying task reports 'changed' status. Use changed_when: false on tasks that should never trigger handlers (e.g., checks).

✦ Definition~90s read
What is Ansible Handlers and Notifications?

Ansible handlers are special tasks that run only when notified by a task that reports a 'changed' status. They are defined in a handlers block (or included via import_tasks) and triggered via the notify keyword. The key design principle: handlers run once, at the end of the play, in the order they are defined—not the order they are notified.

Think of Ansible handlers as the 'cleanup crew' at a party.

This prevents multiple restarts if the same handler is notified by multiple tasks.

Handlers solve the 'restart only on change' problem elegantly. Without handlers, you'd either restart services unconditionally (wasteful and causes downtime) or rely on complex conditionals. Handlers make playbooks both efficient and idempotent: if a task doesn't change anything, the handler doesn't run.

In the Ansible ecosystem, handlers are a core pattern for service management, cache invalidation, and any action that should only occur when a configuration change is made. They integrate with listen to allow multiple tasks to trigger the same handler via a common topic, and flush_handlers to force immediate execution when ordering matters.

Plain-English First

Think of Ansible handlers as the 'cleanup crew' at a party. The tasks are the guests who make messes (change files, restart services). When a guest makes a mess, they send a notification (notify) to the cleanup crew. But the crew doesn't act immediately—they wait until the party ends (end of the play). This is efficient because if multiple guests make a mess, the crew only cleans once. However, there's a trap: if a guest gets into a fight (task fails) before the party ends, the cleanup crew might never show up! In production, this means a configuration change might trigger a restart, but if a later task fails, the restart never happens, leaving the system in a half-baked state. That's where flush_handlers comes in—it's like telling the crew to clean up right now, before the next guest arrives.

I'll never forget the 3 AM outage. We had an Ansible playbook that deployed a new version of our API service. It updated the config file, notified a handler to restart nginx, then ran a database migration. The migration failed—and nginx never restarted. The old config was still active, but the database schema had changed. Users got 500 errors for 45 minutes while we scrambled. The root cause? The handler never ran because the play failed before the playbook ended. That's when I truly understood Ansible handlers—and their dangerous default behavior.

Handlers were introduced in Ansible 1.0 to solve a common problem: how to restart a service only when its configuration actually changes. Instead of always restarting (which causes downtime), you notify a handler and it runs once at the end. It's elegant, but the 'run at end' behavior has burned many teams.

In this article, I'll cover everything you need to know about handlers: the notify keyword, the handlers block, the listen keyword for grouping, meta: flush_handlers for immediate execution, handler ordering, the infamous trap of handlers not running on failure, and idempotency best practices. Every example is production-tested.

The notify Keyword: How to Trigger a Handler

The notify keyword is used on a task to indicate that one or more handlers should be triggered if the task reports a 'changed' status. The value can be a single handler name or a list of handler names.

``yaml - name: Update nginx config ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf notify: restart nginx ``

If the template changes the file, the 'restart nginx' handler is added to the notification queue. If the file is already up-to-date, the task reports 'ok' and the handler is not notified.

You can notify multiple handlers: ``yaml - name: Update application config ansible.builtin.copy: src: app.conf dest: /opt/app/app.conf notify: - restart app - reload nginx ``

Gotcha: If the task uses changed_when to override the changed status, handlers only run if you explicitly set changed_when: true. For example: ``yaml - name: Check if reboot required ansible.builtin.stat: path: /var/run/reboot-required register: reboot_file changed_when: reboot_file.stat.exists notify: reboot server ``

In production, I've seen teams accidentally set changed_when: false on tasks that should trigger handlers, completely breaking the notification chain.

Handler names must be unique
If you have two handlers with the same name (e.g., from included files), Ansible will silently use only the last one defined. Use --syntax-check to catch duplicates.
Production Insight
We once had a handler named 'restart nginx' defined in two different included role files. The second definition overwrote the first, causing the wrong service to restart. We caught it by running ansible-playbook --syntax-check which flagged duplicate handler names.
Key Takeaway
Always use unique handler names across your entire playbook and validate with --syntax-check.

The handlers Block: Defining the Actions

Handlers are defined in a handlers block at the play level, or in a role's handlers/main.yml. Each handler is essentially a task with a name and a module action.

``yaml handlers: - name: restart nginx ansible.builtin.service: name: nginx state: restarted ``

Handlers can use any module, but common ones are service, systemd, command, or uri. They can also include variables and conditionals.

Order matters: Handlers run in the order they are defined in the handlers block, not the order they are notified. For example: ``yaml handlers: - name: restart app ansible.builtin.service: name: app state: restarted - name: restart nginx ansible.builtin.service: name: nginx state: restarted `` Even if 'restart nginx' is notified first, 'restart app' will run first because it's defined first.

Gotcha: If you use include_tasks or import_tasks for handlers, the order is determined by the order of inclusion. This can be surprising if you include multiple handler files.

Handler definition order affects execution order
Always define handlers in the order you want them to execute, not the order you think they'll be notified.
Production Insight
In a microservices deployment, we had handlers for 'restart service A' and 'restart service B'. Service B depended on A, but we defined B first. Handlers ran B before A, causing a brief outage. We fixed it by reordering the handlers block.
Key Takeaway
Define handlers in dependency order (dependencies first) to avoid ordering surprises.

The listen Keyword: Grouping Multiple Triggers

The listen keyword allows a handler to be triggered by multiple tasks via a common topic. Instead of notifying a handler by name, tasks notify a 'listen' topic, and any handler that listens to that topic runs.

``yaml handlers: - name: restart nginx listen: "restart web services" ansible.builtin.service: name: nginx state: restarted - name: restart apache listen: "restart web services" ansible.builtin.service: name: apache2 state: restarted ``

Tasks can notify the topic: ``yaml - name: Update nginx config template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf notify: "restart web services" ``

This is useful when multiple changes require the same set of actions. It also decouples the task from the exact handler name.

Gotcha: The listen value must be a string. If you use a variable, ensure it resolves to a string. Also, if two handlers listen to the same topic, they both run (in definition order).

Use listen for service groups
If you have multiple services that all need restarting on any config change, define a single listen topic and have each service's handler listen to it.
Production Insight
We had a listen topic 'reload proxy' that triggered both nginx and haproxy reloads. One day, a junior engineer added a new handler with the same listen topic but for a different service, causing unintended reloads. We now enforce naming conventions for listen topics.
Key Takeaway
Use listen to group related handlers, but be careful with naming collisions—treat listen topics like a shared namespace.

meta: flush_handlers for Immediate Execution

By default, handlers run at the end of the play. But sometimes you need a handler to run immediately before a subsequent task. The meta: flush_handlers task forces all pending handlers to run right away.

```yaml - name: Update config template: src: app.conf.j2 dest: /opt/app/app.conf notify: restart app

  • name: Flush handlers
  • meta: flush_handlers
  • name: Wait for app to be ready
  • uri:
  • url: http://localhost:8080/health
  • status_code: 200
  • until: result.status == 200
  • retries: 10
  • delay: 2
  • ```

Without flush_handlers, the restart would happen after the play ends, and the health check would fail because the old process is still running.

Gotcha: flush_handlers only flushes handlers that have been notified up to that point. If a later task notifies a handler, it won't run until the next flush or end of play.

Production pattern: Use flush_handlers before any task that depends on the change being active, like health checks, smoke tests, or database migrations.

flush_handlers does not prevent handler execution on failure
If a task after flush_handlers fails, handlers that were flushed have already run. But handlers notified after the failure are still skipped unless force_handlers: true is set.
Production Insight
In a zero-downtime deployment, we used flush_handlers to restart the app before running a database migration that required the new schema. Without it, the migration would fail against the old version.
Key Takeaway
Use meta: flush_handlers whenever you need a handler's effect to be visible before the next task.

Handler Ordering: Why Definition Order Matters

Handlers execute in the order they are defined in the handlers block, not the order they are notified. This is a common source of confusion.

Example: ``yaml handlers: - name: restart database service: name: postgresql state: restarted - name: restart app service: name: app state: restarted ``

Even if 'restart app' is notified first, 'restart database' runs first because it's defined first.

Why this matters: If your app depends on the database, you want the database handler to run first. So define it first.

Gotcha: When using include_handlers or import_tasks for handlers, the order is determined by the order of inclusion. This can be tricky if you include multiple files from different roles.

Best practice: Define all handlers in a single file with explicit ordering, or use listen topics to group them logically.

Handler ordering is not influenced by notify order
Always check the definition order of your handlers. Use ansible-playbook --list-handlers to see the order.
Production Insight
We once had a handler that removed a temporary file, defined after a handler that created it. The removal ran first (because it was defined first) and the creation never happened. We reordered the handlers to fix it.
Key Takeaway
Definition order = execution order. Organize handlers by dependency, not by notification sequence.

The Common Trap: Handlers Not Running When Tasks Fail

This is the most dangerous handler behavior: if any task in the play fails (and ignore_errors is not set), all pending handlers are skipped at the end of the play. This is by design to avoid applying changes from an incomplete run.

Example: ``yaml - hosts: all tasks: - name: Update config template: src: config.j2 dest: /etc/app/config notify: restart app - name: Run migration command: /opt/app/migrate.sh # This fails - name: Clean up file: path: /tmp/old_config state: absent handlers: - name: restart app service: name: app state: restarted ``

If the migration fails, the 'restart app' handler never runs. The config file is updated, but the app is still running the old version. This can lead to inconsistent state.

Solutions: 1. Use force_handlers: true at the play level to force handlers to run even on failure. 2. Use meta: flush_handlers before the risky task to ensure the handler runs before the potential failure. 3. Use ignore_errors: yes on tasks that shouldn't block handlers (but be careful).

Handlers are skipped on ANY task failure in the play
Even if the failed task is unrelated to the handler, all pending handlers are discarded. Use force_handlers: true to override.
Production Insight
The 3 AM outage I mentioned earlier was exactly this: a migration failed, handlers were skipped, nginx never restarted. We now always set force_handlers: true on any play that modifies critical services.
Key Takeaway
Always set force_handlers: true on plays that manage services to ensure handlers run even on failure.

Idempotency and Handlers: Making Sure They Only Run When Needed

Handlers are inherently idempotent because they only run when the notifying task reports 'changed'. But you can break idempotency if your tasks always report 'changed'.

Common mistakes
  • Using command or shell modules without creates, removes, or changed_when.
  • Using copy with force: yes but the source file changes every time (e.g., from a build artifact).
  • Using template with a source that changes every run (e.g., includes a timestamp).
Best practices
  • Use changed_when to explicitly define when a task should be considered changed.
  • For command tasks, use creates or removes to avoid running unnecessarily.
  • Use register and conditionals to only notify handlers when actual changes occur.

Example of a properly idempotent task: ``yaml - name: Download new artifact get_url: url: "{{ artifact_url }}" dest: /opt/app/app.jar checksum: "sha256:{{ artifact_checksum }}" register: download notify: restart app ``

If the checksum matches, the file is not downloaded, and the handler is not notified.

Use checksums to ensure idempotency
For file downloads, always provide a checksum to avoid unnecessary downloads and handler triggers.
Production Insight
We had a playbook that deployed a new version every hour. The artifact URL always pointed to the latest build, so the file was always 'changed' even if the content was identical. We added checksum validation, and handler notifications dropped by 90%.
Key Takeaway
Idempotent tasks prevent unnecessary handler runs. Use changed_when, creates, and checksums to ensure tasks only report 'changed' when something actually changes.

Using force_handlers to Guarantee Handler Execution

The force_handlers play-level directive ensures that all notified handlers run even if a task fails. This is critical for plays that must apply changes regardless of subsequent failures.

``yaml - hosts: all force_handlers: true tasks: - name: Update config template: src: config.j2 dest: /etc/app/config notify: restart app - name: Risky migration command: /opt/app/migrate.sh # This might fail handlers: - name: restart app service: name: app state: restarted ``

With force_handlers: true, even if the migration fails, the 'restart app' handler will run. This prevents the app from running with an old config.

Caveat: force_handlers only ensures handlers run. It does not prevent the play from failing—Ansible will still report a failure. But the handler's effect is applied.

When to use: Always use on plays that manage production services. Reserve the default behavior for plays where you want to roll back on failure (e.g., database schema changes).

force_handlers is a play-level keyword
It cannot be set per task or per handler. It applies to the entire play.
Production Insight
We now have a policy: any play that restarts a service must have force_handlers: true. This single change prevented multiple incidents.
Key Takeaway
Use force_handlers: true on any play where handler execution is critical, especially service restarts.

Handlers with include_tasks and import_tasks

Handlers can be defined in separate files and included using include_tasks or import_tasks. This is common in roles.

``yaml # handlers/main.yml - name: restart app service: name: app state: restarted ``

``yaml # tasks/main.yml - name: Update config template: src: config.j2 dest: /etc/app/config notify: restart app ``

Gotcha: When using include_tasks (dynamic inclusion), handler names are evaluated at runtime. This can cause issues if the same handler name is defined in multiple included files—the last one wins.

Best practice: Use import_tasks (static) for handlers to ensure proper ordering and uniqueness checking at parse time. Dynamic inclusion with include_tasks can lead to duplicate handler names being silently overwritten.

Production pattern: In roles, always define handlers in handlers/main.yml and use import_tasks in the playbook if you need to include role handlers in a specific order.

Dynamic include_tasks can cause duplicate handler names
If you include the same handler file twice, the second inclusion overwrites the first. Use import_tasks for handlers when possible.
Production Insight
We had a role that was included twice in a playbook (once for each service instance). The handlers from the second inclusion overwrote the first, causing the first service to never restart. We refactored to use import_tasks and unique handler names.
Key Takeaway
Prefer import_tasks for handlers to avoid runtime surprises with duplicate names.

Debugging Handlers: Verbose Output and List Commands

  1. List all handlers in a playbook:
  2. ```bash
  3. ansible-playbook playbook.yml --list-handlers
  4. ```
  5. Run with verbose output to see handler notifications:
  6. ```bash
  7. ansible-playbook playbook.yml -v
  8. ```
  9. Look for lines like:
  10. ```
  11. NOTIFIED HANDLER restart nginx
  12. ```
  13. Run with step mode to confirm order:
  14. ```bash
  15. ansible-playbook playbook.yml --step
  16. ```
  17. Check if a handler was skipped due to failure:
  18. ```bash
  19. ansible-playbook playbook.yml -v 2>&1 | grep -E '(failed|skipping|handler)'
  20. ```

Gotcha: In Ansible 2.x, handlers that are skipped due to a failed task do not appear in the output at all. You only see the failure. This is why force_handlers: true is important.

Use --list-handlers to preview execution order
Run this before any production deployment to verify handler ordering.
Production Insight
During a major outage, we ran ansible-playbook --list-handlers and discovered that a handler we thought was defined was actually missing due to a typo in the file name. The command saved us hours of debugging.
Key Takeaway
Always validate handler configuration with --list-handlers and -v before running on production.

Advanced Patterns: Conditional Handlers and Loops

Handlers can include conditionals (when) and can be used with loops, but there are nuances.

Conditional handlers: ``yaml handlers: - name: restart app service: name: app state: restarted when: ansible_facts.os_family == "Debian" ``

Handler with loop: ``yaml handlers: - name: restart services service: name: "{{ item }}" state: restarted loop: - nginx - app ``

Gotcha: If you use listen with a loop, each item in the loop is a separate handler instance. Notifying the listen topic triggers all of them.

Production pattern: Use listen with a loop to restart multiple services from a single notification. For example: ``yaml handlers: - name: restart web stack listen: "restart web" service: name: "{{ item }}" state: restarted loop: - nginx - php-fpm ``

Then any task can notify 'restart web' and both services restart.

Handlers with loops run all items if notified
The loop is executed once per handler notification. If the handler is notified multiple times, the loop runs each time (but only once due to handler deduplication).
Production Insight
We used a loop in a handler to restart a microservice cluster. When a config changed, all 10 instances restarted. But because handlers deduplicate, it only happened once per play. This pattern saved us from writing 10 separate handlers.
Key Takeaway
Use loops in handlers to manage multiple services with a single handler definition, but be aware of the deduplication behavior.

Common Pitfalls and How to Avoid Them

  1. Assuming handlers run immediately: They don't. Use flush_handlers if you need immediate effect.
  2. Not using force_handlers: Leads to skipped restarts on failure.
  3. Duplicate handler names: Silently overwritten. Use unique names or import_tasks to catch duplicates.
  4. Wrong ordering: Define handlers in dependency order.
  5. Not checking idempotency: Tasks that always report 'changed' cause unnecessary handler runs.
  6. Using listen with variables that might be undefined: Always ensure the listen topic is a literal string or a variable that resolves.
  7. Forgetting that handlers are skipped on unreachable hosts: If a host becomes unreachable during the play, handlers for that host are skipped.
Production checklists
  • Always add force_handlers: true to plays with service restarts.
  • Run --list-handlers before deployment.
  • Use -v to verify handler notifications in CI/CD.
  • Test failure scenarios in staging.
Handlers are skipped on unreachable hosts
If a host becomes unreachable during the play (e.g., network issue), handlers for that host are not executed. This is another reason to use force_handlers: true and handle unreachability separately.
Production Insight
We had a playbook that restarted a load balancer after config change. The load balancer host became unreachable mid-play due to a network blip. The handler never ran, and the config was applied but not active. We added a retry mechanism and force_handlers: true.
Key Takeaway
Plan for handler failures due to host unreachability and use force_handlers to mitigate.
● Production incidentPOST-MORTEMseverity: high

The Handler That Never Ran

Symptom
Users received 500 errors after a deployment. Nginx was still running with old config despite config file being updated.
Assumption
The nginx restart handler must have run because the config file task reported 'changed'.
Root cause
The handler was notified, but because a subsequent task (database migration) failed, Ansible skipped all pending handlers at the end of the play.
Fix
Added force_handlers: true to the play and used meta: flush_handlers before the critical migration task.
Key lesson
  • Always assume handlers might not run if any task fails.
  • Use force_handlers: true or flush_handlers to ensure critical actions like restarts happen regardless.
Production debug guideSymptom → Root cause → Fix4 entries
Symptom · 01
Handler never runs despite task reporting 'changed'
Fix
Check if any later task failed. Add force_handlers: true to the play. Use -v to see handler execution status.
Symptom · 02
Handler runs multiple times or not at all when using listen
Fix
Ensure handler names are unique. listen topics can overlap; use ansible-playbook --syntax-check to detect duplicates.
Symptom · 03
Handler runs before a dependent task
Fix
Handlers run only at end of play by default. Insert meta: flush_handlers before the dependent task.
Symptom · 04
Handler runs in wrong order (e.g., restart before config write)
Fix
Check handler definition order. Handlers execute in definition order, not notification order. Reorder if needed.
★ Ansible Handlers and Notifications Quick Referenceprint this for your desk
Handler not running on failure
Immediate action
Check if any task failed
Commands
ansible-playbook playbook.yml -v | grep -E '(changed|failed|handler)'
ansible-playbook playbook.yml --force-handlers
Fix now
Add force_handlers: true to play or use meta: flush_handlers before critical tasks
Handler running too late+
Immediate action
Insert flush_handlers
Commands
ansible-playbook playbook.yml --step
Fix now
Add - name: flush handlers\n meta: flush_handlers before the dependent task
Multiple handlers with same name+
Immediate action
Check for duplicate handler names
Commands
ansible-playbook playbook.yml --syntax-check
grep -r 'name:.*handler' handlers/
Fix now
Rename handlers to be unique across all included files
Handler not triggered by listen+
Immediate action
Verify listen topic matches
Commands
ansible-playbook playbook.yml -v 2>&1 | grep -i 'notified'
Fix now
Ensure listen value is a string, not a variable that might not resolve
Handler runs but no change needed+
Immediate action
Check idempotency
Commands
ansible-playbook playbook.yml --diff
Fix now
Add changed_when: false to tasks that should never trigger handlers
Handler Execution: Default vs force_handlers vs flush_handlers
ScenarioDefault Behaviorforce_handlers: trueflush_handlers before failure
No task failureHandlers run at end of playHandlers run at end of playHandlers run immediately, then remaining tasks continue
Task fails before handler notificationNo handlers run (none pending)No handlers run (none pending)No handlers run (none pending)
Task fails after handler notificationAll pending handlers skippedAll pending handlers run at endFlushed handlers run; handlers notified after failure are skipped
Host unreachable mid-playHandlers for that host skippedHandlers for that host skipped (force_handlers does not override unreachability)Same as default
Multiple handlers notifiedRun in definition orderSameSame (but only flushed ones)

Key takeaways

1
Handlers run only at the end of the play by default; use `meta
flush_handlers` for immediate execution.
2
Always set `force_handlers
true` on plays that manage services to prevent skipped restarts on failure.
3
Handler execution order is determined by definition order, not notification order.
4
Use listen to group multiple handlers under a common topic for decoupled notifications.
5
Duplicate handler names cause silent overwrites; validate with --syntax-check.
6
Ensure tasks are idempotent with changed_when to avoid unnecessary handler triggers.
7
Use ansible-playbook --list-handlers to preview handler order before deployment.
8
Handlers are skipped on unreachable hosts; plan accordingly with retries or force_handlers.

Common mistakes to avoid

6 patterns
×

Not using force_handlers on critical plays

Symptom
Service restart skipped after a failed task, leading to inconsistent state
Fix
Add force_handlers: true to the play
×

Duplicate handler names in included files

Symptom
Only the last defined handler runs
Fix
Use unique names or import_tasks and verify with --syntax-check
×

Assuming handlers run immediately after notify

Symptom
Subsequent tasks see old state (e.g., old service running)
Fix
Insert meta: flush_handlers before dependent tasks
×

Using command/shell without changed_when

Symptom
Handler always runs even if no real change
Fix
Add changed_when: false or use creates/removes
×

Defining handlers in wrong order

Symptom
Service B restarts before Service A, causing dependency failures
Fix
Reorder handlers in definition to match dependency order
×

Using listen with a variable that might be undefined

Symptom
Handler never triggered because listen topic resolved to empty string
Fix
Use literal strings for listen topics or ensure variable is defined
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What is the default behavior of Ansible handlers when a task fails?
Q02SENIOR
How can you force handlers to run immediately before a specific task?
Q03SENIOR
What is the difference between `notify` and `listen` in handlers?
Q04SENIOR
Explain how handler ordering is determined in Ansible.
Q05SENIOR
What happens if two handlers have the same name in a playbook?
Q06SENIOR
How can you ensure idempotency when using handlers with command modules?
Q07SENIOR
What is the purpose of `force_handlers` and when should you use it?
Q08SENIOR
Can handlers be used with loops? If so, what is the behavior?
Q01 of 08JUNIOR

What is the default behavior of Ansible handlers when a task fails?

ANSWER
By default, if any task in the play fails, all pending handlers are skipped and not executed. This is to prevent applying partial changes. You can override this with force_handlers: true at the play level.
FAQ · 8 QUESTIONS

Frequently Asked Questions

01
Do handlers run if a task fails with ignore_errors: yes?
02
Can I have multiple handlers with the same listen topic?
03
Does flush_handlers run handlers that were notified after the flush?
04
What is the difference between handlers and tasks with when conditions?
05
Can I use variables in handler names?
06
How do I debug why a handler didn't run?
07
Can handlers be used in pre_tasks or post_tasks?
08
Is it possible to have a handler that runs only on certain hosts?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Notes here come from systems that actually shipped.

Follow
Verified
production tested
June 21, 2026
last updated
1,596
articles · all by Naren
🔥

That's Ansible. Mark it forged?

9 min read · try the examples if you haven't

Previous
Ansible Conditionals and Loops
7 / 23 · Ansible
Next
Ansible Jinja2 Templates