Event Driven Ansible
The Syncer can send events to Event Driven Ansible (EDA). Rules decide which hosts send which event, a cronjob sends them, and a rulebook on the EDA side decides what to run, for example a job template that registers the Checkmk agent.
The module lives under Modules → Event Driven Ansible.
How it works
- An account of the type Event Driven Ansible names the event stream (or
ansible.eda.webhooksource) the events go to. - Event Rules match hosts with the standard condition engine (hostname, any attribute, any inventory value). Every outcome of a matching rule is one event.
- The command
eda send_events <account>(cronjob "EDA: Send Events") walks all hosts, evaluates the enabled rules and posts one JSON event per match. - Every event sent is recorded in the Event History. A host that still matches sends the same event again only after Resend after hours have passed, so a registration that failed on the Ansible side is retried, but the event stream is not flooded on every cron run.
Like the Playbook Fire Rules, sending happens only from the dedicated command, never from an inventory or export run.
Account
Create an account under Accounts with the type Event Driven Ansible.
| Field | Value |
|---|---|
| Address | URL of the event stream, e.g. https://aap.example.com/eda-event-streams/api/eda/v1/external_event_stream/<uuid>/post/, or the URL of an ansible.eda.webhook source, e.g. http://eda.example.com:5000/endpoint |
| Username / Password | With a username, the request uses Basic Auth. Without a username, the password is the token. |
| auth_header | Header the token is sent in, default Authorization |
| auth_prefix | Put in front of the token, default Bearer (what ansible.eda.webhook with token: expects). Empty sends the bare token, for an event stream credential that compares the header with the token as is. |
| repeat_threshold | From this many sends on, an event whose host still matches counts as repeating, see Repeated Events. Default 3, 0 switches it off. |
| verify_cert, ca_cert_chain, ca_root_cert | TLS settings as for every account |
Event Rules
| Field | Meaning |
|---|---|
| Conditions | Which hosts send the event |
| Event | Name of the event, the rulebook matches on event.payload.event. Jinja with the host attributes is allowed. |
| Extra Vars | YAML key: value pairs, Jinja with the host attributes is allowed. Sent as event.payload.vars. |
| Resend after hours | Send again after this many hours while the host still matches (default 24). 0 sends once and never again. |
An event looks like this:
{
"source": "cmdbsyncer",
"event": "register_agent_tls",
"hostname": "srv01",
"rule": "Register TLS",
"vars": {"os": "linux"},
"timestamp": "2026-10-13T09:00:00+02:00"
}
Extra Vars that are no valid YAML mapping are not sent: the event shows up as failure in the Event History with the reason.
Repeated Events
An event should make its condition go away: after the registration the agent no longer reports that it is not registered, the host no longer matches, nothing is sent anymore. When that does not happen, the event goes out again after every resend interval (or, while the event stream does not accept it, on every cron run) and nothing changes.
That is what Modules → Event Driven Ansible → Repeated Events shows. Every event of a rule on a host has a streak per account:
| State | Meaning |
|---|---|
| Pending | The event was sent, the host still matches, fewer sends than the threshold so far |
| Repeating | The host still matches after repeat_threshold sends (account field, default 3): the event goes out without effect |
| Resolved | A run of "EDA: Send Events" no longer gave the host this event: the rule no longer matches (or was disabled, or the host is gone) |
Sends counts every send of the streak, successful or not, Failed sends the ones the event stream refused. A resolved streak starts over at 0 when the host matches again. Resolved streaks are removed after the retention of the Event History (EDA_EVENT_LOG_RETENTION_DAYS, 90 days).
With the default resend interval of 24 hours and the threshold 3, a host shows up as repeating on the third day its event went out without effect. A dry run changes nothing.
The same numbers are available over the REST API for monitoring, for example with the Checkmk check of the Syncer: GET /api/v1/syncer/eda, see Syncer Endpoints.
CLI
./cmdbsyncer eda send_events ACCOUNT # send the events
./cmdbsyncer eda send_events ACCOUNT --dry-run # only print them
./cmdbsyncer eda debug_host srv01 # matching rules and the events of one host
Example: register Checkmk agents that are not registered
- Inventorize the agent state from Checkmk: under Checkmk → Inventorize from Checkmk Settings, add
Check_MK Agentwith the source Service Plugin Output, and run./cmdbsyncer checkmk inventorize_hosts ACCOUNT(or its cronjob). Every host then carriescmk_svc__check_mk_agent_output(see Manage Checkmk Agents). - Create two Event Rules:
| Rule | Condition | Event |
|---|---|---|
| Register TLS | cmk_svc__check_mk_agent_output contains TLS is not activated on monitored host |
register_agent_tls |
| Register Bakery | cmk_svc__check_mk_agent_output contains not registered |
register_agent_bakery |
Checkmk's exact wording varies by version, check it with ./cmdbsyncer eda debug_host HOST.
- Put "EDA: Send Events" with the EDA account into a Cronjob Group, after the Checkmk inventory.
- On the EDA side, a rulebook starts the matching job template, for example with the
cmk_agent_mngmt.ymlplaybook andcmk_register_tlsorcmk_register_bakeryset:
- name: Checkmk agent registration from the Syncer
hosts: all
sources:
- ansible.eda.webhook:
host: 0.0.0.0
port: 5000
token: "{{ syncer_token }}"
rules:
- name: Register TLS
condition: event.payload.event == "register_agent_tls"
action:
run_job_template:
name: Register Checkmk agent
organization: Default
job_args:
limit: "{{ event.payload.hostname }}"
extra_vars:
cmk_register_tls: true
- name: Register Bakery
condition: event.payload.event == "register_agent_bakery"
action:
run_job_template:
name: Register Checkmk agent
organization: Default
job_args:
limit: "{{ event.payload.hostname }}"
extra_vars:
cmk_register_bakery: true
With an event stream in the Ansible Automation Platform, the source is the event stream instead of ansible.eda.webhook, the rules stay the same.