Home DevOps Event-Driven Ansible: Automating Incident Response Without Polling
Advanced 3 min · July 11, 2026

Event-Driven Ansible: Automating Incident Response Without Polling

Event-Driven Ansible automates incident response by reacting to events in real time.

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Lessons pulled from things that broke in production.

Follow
Production
production tested
July 11, 2026
last updated
1,727
articles · all by Naren
Before you start⏱ 30 min
  • Ansible 2.15+ installed. Basic familiarity with the monitoring tool you want to integrate (Prometheus, webhooks, etc.).
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer

Event-Driven Ansible lets you define rules that listen for events (e.g., a service goes down, a file changes) and automatically run Ansible playbooks. You set up an event source (like a webhook or message queue), write a rulebook that maps events to actions, and the engine handles the rest.

✦ Definition~90s read
What is Event-Driven Ansible?

Event-Driven Ansible is an extension of Ansible that listens for events from sources like Kafka, webhooks, or monitoring tools and triggers automation rules in response. It replaces polling-based cron jobs with real-time event-driven automation.

Imagine you have a butler who only acts when you ring a bell.
Plain-English First

Imagine you have a butler who only acts when you ring a bell. Instead of checking every hour if you need something (polling), the butler waits by the bell and springs into action the moment it rings. Event-Driven Ansible is that butler for your infrastructure: it listens for specific signals (events) and runs the appropriate playbook immediately.

Most infrastructure automation is reactive polling. You set a cron job to run every 5 minutes, check if something is wrong, and fix it. That's wasteful and slow. Event-Driven Ansible flips the model: it listens for events and reacts instantly. No more wasted cycles checking for problems that don't exist. By the end of this article, you'll be able to set up an event-driven rule that automatically restarts a failed service, scales a deployment based on load, or even triggers a rollback when a deployment fails — all without a single cron job.

Why Polling Is a Waste of Resources

Cron jobs are the duct tape of automation. They run regardless of whether anything needs to happen. In production, that means thousands of unnecessary API calls, wasted CPU cycles, and delayed responses. Event-Driven Ansible eliminates the polling tax. Instead of asking 'Is it broken yet?' every 5 minutes, it waits for the answer to come to it. The result: faster reaction times, lower resource usage, and simpler code. No more managing cron schedules or worrying about overlapping runs.

polling_vs_event.ymlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# io.thecodeforge — DevOps tutorial

# Polling approach (bad):
# cron: */5 * * * * ansible-playbook check_and_fix.yml

# Event-driven approach (good):
# Rulebook listens for 'service_down' event
- name: React to service failure
  hosts: localhost
  sources:
    - ansible.eda.alertmanager:
        host: 0.0.0.0
        port: 5000
  rules:
    - name: Restart failed service
      condition: event.alert.status == 'firing' and event.alert.labels.service == 'nginx'
      action:
        run_playbook:
          name: restart_service.yml
Output
No direct output; the rule waits for events.
Production Trap:
Don't mix polling and event-driven for the same task. You'll get duplicate actions and race conditions. Pick one pattern.

Setting Up Your First Event Source

Event sources are the ears of Event-Driven Ansible. They can be webhooks, message queues, cloud events, or monitoring alerts. The most common production setup is a webhook endpoint that receives POST requests from your monitoring system or CI/CD pipeline. Here's how to configure a simple webhook source that listens for JSON payloads on port 5000.

webhook_source.ymlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# io.thecodeforge — DevOps tutorial

- name: Webhook listener for deployment events
  hosts: localhost
  sources:
    - ansible.eda.webhook:
        host: 0.0.0.0
        port: 5000
  rules:
    - name: Deploy new version
      condition: event.payload.action == 'deploy' and event.payload.environment == 'production'
      action:
        run_playbook:
          name: deploy_app.yml
          vars:
            version: "{{ event.payload.version }}"
Output
No output until a webhook is received.
Senior Shortcut:
Use environment variables for sensitive config like webhook secrets. Ansible EDA supports {{ lookup('env', 'WEBHOOK_SECRET') }}.

Writing Rulebooks: The Brain of the Operation

Rulebooks define the logic: when an event arrives, what condition must be true, and what action to take. Conditions can check event fields, nested values, or even run Jinja2 expressions. Actions typically run a playbook, but can also run a module directly or send a notification. Keep rulebooks simple — one rule per logical action. Complex conditions lead to debugging nightmares.

rulebook_example.ymlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# io.thecodeforge — DevOps tutorial

- name: Production incident response
  hosts: localhost
  sources:
    - ansible.eda.alertmanager:
        host: 0.0.0.0
        port: 5000
  rules:
    - name: Restart high-load service
      condition: event.alert.labels.severity == 'critical' and event.alert.labels.alertname == 'HighCPU'
      action:
        run_playbook:
          name: restart_service.yml
          vars:
            service: "{{ event.alert.labels.instance }}"
    - name: Notify on warning
      condition: event.alert.labels.severity == 'warning'
      action:
        run_module:
          name: ansible.builtin.debug
          args:
            msg: "Warning alert: {{ event.alert.annotations.summary }}"
Output
No output until alerts are received.
Interview Gold:
Rulebooks are evaluated in order. The first matching rule wins. If you have overlapping conditions, order matters. Use enabled: false to disable rules without deleting them.

Running the EDA Controller in Production

The EDA controller is a long-running process that listens for events. In production, run it as a systemd service or in a container with restart policies. Never run it as a background job in a terminal — it will die when you log out. Use a dedicated user with minimal permissions. Monitor the controller itself: if it goes down, your automation goes deaf.

eda_service_setup.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# io.thecodeforge — DevOps tutorial

# Create systemd service for EDA controller
sudo cat > /etc/systemd/system/eda-controller.service << 'EOF'
[Unit]
Description=Event-Driven Ansible Controller
After=network.target

[Service]
Type=simple
User=ansible-eda
ExecStart=/usr/bin/ansible-rulebook --rulebook /etc/eda/rules.yml --controller
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable eda-controller
sudo systemctl start eda-controller

# Check logs
journalctl -u eda-controller -f
Output
Service starts and logs events.
Production Trap:
If you restart the controller, it loses buffered events. Use a persistent message queue (like RabbitMQ) to buffer events during restarts.

Handling Event Deduplication and Idempotency

Events can arrive multiple times (e.g., retries from monitoring). Your playbooks must be idempotent — running them twice should have the same effect as running them once. Use Ansible's state parameters and creates/removes to ensure idempotency. For deduplication, track event IDs in a Redis cache and skip already-processed events.

dedup_playbook.ymlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# io.thecodeforge — DevOps tutorial

# Playbook that checks if an event was already processed
- name: Restart service with dedup
  hosts: all
  vars:
    event_id: "{{ lookup('env', 'EVENT_ID') }}"
  tasks:
    - name: Check if event already processed
      ansible.builtin.slurp:
        src: "/var/log/eda/processed/{{ event_id }}"
      register: processed
      failed_when: false
    - name: Skip if already done
      ansible.builtin.meta: end_play
      when: processed.content is defined
    - name: Restart the service
      ansible.builtin.service:
        name: nginx
        state: restarted
    - name: Mark event as processed
      ansible.builtin.file:
        path: "/var/log/eda/processed/{{ event_id }}"
        state: touch
Output
Service restarted (or skipped if already processed).
Senior Shortcut:
Use Redis with TTL for event dedup. Set TTL to your max expected retry window. This keeps the cache small and avoids manual cleanup.

Scaling Event-Driven Ansible Horizontally

A single EDA controller can handle hundreds of events per second. Beyond that, run multiple controllers behind a load balancer, each with the same rulebook. Use a shared event source (like Kafka or RabbitMQ) that partitions events by a key (e.g., hostname) to ensure related events go to the same controller. This avoids race conditions on the same host.

kafka_source.ymlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# io.thecodeforge — DevOps tutorial

- name: Kafka event source for scaled setup
  hosts: localhost
  sources:
    - ansible.eda.kafka:
        host: kafka-broker:9092
        topic: ansible-events
        group_id: eda-group-1
        partition: 0
  rules:
    - name: Handle host-specific event
      condition: event.host == inventory_hostname
      action:
        run_playbook:
          name: handle_event.yml
Output
Events consumed from Kafka partition.
Interview Gold:
Partition by hostname to guarantee ordered processing per host. If you use a random partition, you might restart a service twice.

When Not to Use Event-Driven Ansible

Event-Driven Ansible is overkill for simple scheduled tasks like daily backups or log rotation. Stick with cron for those. Also avoid it for high-frequency events (thousands per second) — the rulebook evaluation overhead adds latency. Use a stream processor like Flink for that. Finally, don't use it for critical safety systems (e.g., emergency shutdown) where you need guaranteed delivery and ordering — use a dedicated industrial controller.

Never Do This:
Don't use Event-Driven Ansible for life-critical systems. The event delivery is best-effort. If you need guaranteed delivery, use a message queue with acknowledgments and a separate consumer.
● Production incidentPOST-MORTEMseverity: high

The 3AM Database Failover That Never Happened

Symptom
Primary database went down at 3:12 AM. The secondary was ready, but the failover script never ran. The site was down for 14 minutes.
Assumption
The team assumed the monitoring system would trigger the failover script via a webhook.
Root cause
The webhook endpoint was configured with a self-signed certificate that expired. The monitoring system's HTTP POST failed silently. Event-Driven Ansible never received the event.
Fix
Switched to a message queue (RabbitMQ) with TLS and added health checks on the event source connection. Also added a dead-letter queue for failed events with a retry mechanism.
Key lesson
  • Always validate the event delivery path end-to-end, including certificate expiry and network timeouts.
Production debug guideSystematic recovery paths for the failure modes engineers actually hit.3 entries
Symptom · 01
Events not triggering any rule
Fix
1. Check controller logs: journalctl -u eda-controller -f. 2. Verify event source is reachable: curl -X POST http://localhost:5000/endpoint -d '{"test":true}'. 3. Check rulebook syntax: ansible-rulebook --rulebook rules.yml --syntax-check.
Symptom · 02
Playbook runs but fails with 'host unreachable'
Fix
1. Verify inventory contains the target host. 2. Check SSH connectivity from the controller: ssh user@host. 3. Ensure the event payload includes the correct hostname.
Symptom · 03
Duplicate playbook executions for the same event
Fix
1. Check if event source retries (e.g., AlertManager resends). 2. Implement deduplication using Redis or file markers. 3. Set run_playbook with run_once: true if applicable.
★ Event-Driven Ansible Triage Cheat SheetFirst-response commands for when things go wrong — copy-paste ready.
Controller not starting: `ansible-rulebook: command not found`
Immediate action
Check if ansible-rulebook is installed
Commands
pip3 list | grep ansible-rulebook
which ansible-rulebook
Fix now
pip3 install ansible-rulebook
Events received but no rule matches: `No matching rules found` in logs+
Immediate action
Check event payload structure
Commands
ansible-rulebook --rulebook rules.yml --print-events
tail -f /var/log/eda/events.log
Fix now
Adjust condition to match actual event fields
Playbook fails: `ERROR! the playbook: restart_service.yml could not be found`+
Immediate action
Verify playbook path in rulebook
Commands
ls -la /path/to/playbooks/restart_service.yml
ansible-playbook --syntax-check /path/to/playbooks/restart_service.yml
Fix now
Update rulebook with absolute path or correct relative path
Webhook endpoint not reachable: `Connection refused`+
Immediate action
Check if controller is listening
Commands
ss -tlnp | grep 5000
systemctl status eda-controller
Fix now
Start controller: systemctl start eda-controller
FeaturePolling (Cron)Event-Driven Ansible
Reaction timeUp to 5 minutes delaySub-second (real-time)
Resource usageWasted CPU/API callsOnly when events occur
ComplexitySimple cron syntaxRulebooks + event sources
IdempotencyMust handle manuallyBuilt-in via playbook design
ScalabilityLimited by cron frequencyHorizontal with partitions
⚙ Quick Reference
6 commands from this guide
FileCommand / CodePurpose
polling_vs_event.yml- name: React to service failureWhy Polling Is a Waste of Resources
webhook_source.yml- name: Webhook listener for deployment eventsSetting Up Your First Event Source
rulebook_example.yml- name: Production incident responseWriting Rulebooks
eda_service_setup.shsudo cat > /etc/systemd/system/eda-controller.service << 'EOF'Running the EDA Controller in Production
dedup_playbook.yml- name: Restart service with dedupHandling Event Deduplication and Idempotency
kafka_source.yml- name: Kafka event source for scaled setupScaling Event-Driven Ansible Horizontally

Key takeaways

1
EDA closes the loop between monitoring and remediation with rulebooks.
2
Webhooks are the easiest event source to start with (testable with curl).
3
Always scope EDA actions to specific hosts. Never use hosts
all.
4
Deploy separate EDA workers per environment. Start with dry_run mode.

Common mistakes to avoid

3 patterns
×

Using hosts: all in EDA-triggered playbooks

Fix
Always scope EDA actions to specific hosts: hosts: "{{ event.payload.ansible_host }}". Broad playbooks can impact the entire fleet.
×

Enabling auto-remediation without dry-run testing

Fix
Run new rulebooks in dry_run mode for at least a week. Validate behavior before enabling active remediation.
×

Running EDA across environments without isolation

Fix
Deploy separate EDA workers per environment (staging, prod). A staging alert should never trigger production remediation.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
How does Event-Driven Ansible handle duplicate events? What's your strat...
Q02SENIOR
When would you choose Event-Driven Ansible over a traditional monitoring...
Q03SENIOR
What happens if the EDA controller crashes while processing an event? Ho...
Q04JUNIOR
What is a rulebook in Event-Driven Ansible?
Q05SENIOR
You have a rule that restarts a service on high CPU. The monitoring syst...
Q06SENIOR
How would you design Event-Driven Ansible to handle 10,000 events per se...
Q01 of 06SENIOR

How does Event-Driven Ansible handle duplicate events? What's your strategy to prevent duplicate actions?

ANSWER
It doesn't handle deduplication natively. You must implement it in your playbook or use an external cache like Redis. Track event IDs and skip if already processed. Also ensure playbooks are idempotent.
FAQ · 6 QUESTIONS

Frequently Asked Questions

01
What is Event-Driven Ansible?
02
What event sources does EDA support?
03
How is Event-Driven Ansible different from a cron job running a playbook?
04
How do I prevent EDA from making things worse with auto-remediation?
05
What's the architecture of Event-Driven Ansible?
06
Can EDA integrate with existing monitoring tools?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Lessons pulled from things that broke in production.

Follow
Verified
production tested
July 11, 2026
last updated
1,727
articles · all by Naren
🔥

That's Ansible. Mark it forged?

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

Previous
Ansible Execution Environments
33 / 37 · Ansible
Next
Ansible Azure Automation