AnsibleXXXIX · Automation Platforms, RBAC and Event-DrivenAutomation platforms, RBAC and event-driven automation
Event-driven Ansible: sources, rules, actions
What you'll learn
- Read a rulebook and name each of its parts
- Distinguish a rulebook from a playbook by what triggers each
- Choose the right action for a rule, including the ones that change nothing
- Judge whether a problem is genuinely event-shaped or is a schedule in disguise
Prerequisites
Verified against ansible-core 2.21.x · ansible (community package) 14.x · Python (controller) 3.12+ · ansible-lint 26.x · Molecule 26.x · Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL / Rocky / AlmaLinux 9.x · 2026-08-11
Everything this course has taught so far is push automation. A person or a schedule decides that something should happen, and Ansible makes it happen.
Event-driven Ansible inverts the trigger. A long-running process watches a stream of events, and when an event matches a condition, an action fires.
event source --> rule (condition) --> action
That is the whole model. The rest of this lesson is what goes in each box, and the lesson after it is about why the arrow from action back to source is the dangerous part.
The shape of a rulebook
A rulebook is a YAML file containing one or more rulesets. A ruleset has a name, the hosts that actions requiring an inventory will use, a list of sources, and a list of rules:
---
- name: example_ruleset
hosts: all
sources:
- name: range_source
eda.builtin.range:
limit: 5
rules:
- name: example_rule
condition: event.i == 1
action:
debug:
Four parts, and the correspondence to a playbook is close enough to be useful and different enough to be worth stating precisely.
| Playbook | Rulebook |
|---|---|
| Runs once and exits | Runs until stopped |
hosts: is the blast radius | hosts: is only used by actions that need an inventory |
| Tasks execute in order | Rules fire when their condition matches, in no fixed order |
| Triggered by a person or a schedule | Triggered by an event |
| Fails, and you see the failure | Keeps running; a failure is an event among events |
The last row is the operationally significant one. A playbook that fails stops and tells you. A rulebook that fails to do something useful goes on running, waiting for the next event, and there is nothing to notice unless you built something to notice it.
Sources
A source is a plugin that produces events. What matters for design is what kind of thing your source is:
| Source class | Example | Event arrives when |
|---|---|---|
| Alerting webhook | A monitoring system posting an alert | A threshold is crossed — including repeatedly |
| Message queue | Kafka, AMQP | A producer publishes |
| Cloud or platform notification | An instance state change | Infrastructure changes |
| Source-control or CI webhook | A merge, a tag | Somebody pushes |
| Polling plugin | Watching a file or an API | The plugin looks and finds a difference |
The distinction that determines whether your rules will behave is not the transport. It is whether the source can emit the same event many times in quick succession.
An alerting webhook can and will. A merge notification generally does not. That single property decides whether lesson 7 is optional reading or the reason your estate has an incident.
Conditions
A condition is a boolean expression over the event payload:
rules:
- name: Respond to a disk alert
condition: event.payload.alertname == "DiskWillFillIn4Hours"
action:
run_job_template:
name: Reclaim log space
organization: Default
Conditions can combine terms, match across multiple events, and reference
facts the ruleset has accumulated. The craft here is the same as writing a
when: expression, with one addition that has no playbook equivalent:
precision in a condition is a safety control, because a condition that
matches too broadly is an action that fires too often.
Actions
There are eleven. Knowing the whole list matters because five of them change nothing, and starting with those is the recommended deployment path.
| Action | What it does |
|---|---|
run_playbook | Run an Ansible playbook |
run_module | Run an Ansible module |
run_job_template | Run a job template |
run_workflow_template | Run a workflow template |
set_fact | Post a fact to the running rule set in the rules engine |
post_event | Post an event to a running rule set in the rules engine |
retract_fact | Remove a fact from the running rule set |
print_event | Write the event to stdout |
debug | Debug ansible-rulebook |
shutdown | Generate a shutdown event which terminates the ansible-rulebook process |
none | No action, useful when writing tests |
Four of them touch the fleet: run_playbook, run_module,
run_job_template, run_workflow_template. The first two execute
directly from the rulebook process; the last two hand the work to a
platform, which means the run appears in the platform’s history with its
credentials and permissions — a significant difference when you are
deciding how much to trust an automated response.
The other seven stay inside the rules engine or write to stdout. They are how you build and test a rulebook without touching anything:
print_eventis your alert-only deployment mode. The rulebook watches production events and prints what it would have responded to.noneis for tests where you want the rule to match and nothing to happen at all.set_fact/retract_fact/post_eventare the state machine. Facts persist in the ruleset, so a rule can record that it has acted and a later rule can condition on that.shutdownstops the process — a kill switch expressible in the rulebook itself, which lesson 7 returns to.
Where event-driven automation genuinely fits
Being specific is worth more than enthusiasm here, because the honest list is shorter than the marketing list.
It fits when the trigger is genuinely unpredictable and the response is genuinely mechanical.
| Fits well | Why |
|---|---|
| Enrich an alert with diagnostics before a human reads it | Read-only, timing matters, the work is identical every time |
| Open or update a ticket from an event | No fleet change, removes toil |
| Reconfigure automation when inventory changes | The trigger is a real event; the response is deterministic |
| Contain a host on a confirmed security signal | Minutes matter, and the action is narrow — isolate one host |
| Roll a config change when a source of truth changes | Event-shaped by construction |
| Fits badly | Why |
|---|---|
| Anything that happens on a timetable | It is a schedule. Use a schedule |
| Restarting a service that keeps failing | The restart treats the symptom, and see lesson 7 |
| Responses that need judgement about impact | The rule has none |
| Anything triggered by a signal you do not fully trust | A bad signal becomes a fleet change |
Knowledge check
Knowledge check · 4 questions
Q1. A team wants to run a compliance check every five minutes and remediate anything it finds. They plan to build it as a rulebook with a polling source. What is the strongest objection?
Q2. Which rulebook actions let you deploy and observe a rule without changing anything on the fleet? Select all that apply.
Q3. Facts posted with set_fact live in the memory of the ruleset, so restarting ansible-rulebook discards them and a rule that used a fact to avoid repeating itself may repeat itself.
Q4. A production rule uses the condition event.payload.alertname == "DiskWillFillIn4Hours". What is the most important term missing from it?
Passing score: 75%. Answers are checked in this browser.