Agentless automation with Event-Driven Ansible

On Call

Setting Rules

The test setup can basically react to any log entry and run a matching Ansible playbook. This example restarts the dnsmasq DNS/DHCP server if it fails for any reason. To do this, EDA monitors the log messages from systemd. The rule_dns.yml rulebook starts with the Kafka source:

- name: Kafka Monitor
  hosts: all
  sources:
    - name: Kafka
      ansible.eda.kafka:
        host: 192.168.2.12
        port: 9092
        topic: journals

With this rulebook, ansible-rulebook later taps into the message bus and forwards incoming messages in the hierarchical variable events. Sources also have filters that can change the content or structure of the variables:

filters:
  - json_filter:
    exclude_keys: ['user']

For example, it would remove all event.user values from the source event. An important filter is insert_hosts_to_meta, which takes one or more host names from the source message and then uses them as limits when executing a playbook. An Ansible playbook started by EDA will therefore only contact those hosts previously transferred to the event.meta.host variable by insert_hosts_to_meta. This example does not use the filter, though, simply because it was not yet included in the test build of ansible-rulebook (0.11) used.

The test rule responds to the message that the DNS server has been stopped:

rules:
  - name: Monitor DNS Service
    condition: event.message is search("Stopped DNS", ignorecase=true)

If a message on the message bus now contains Stopped DNS (Figure 2), EDA steps in and runs an action:

action:
  run_playbook:
    name: start_dns.yml
    extra_vars:
      event_host:
        "{{ event.host.name }}"
Figure 2: The Kafka messaging bus's Stopped DNS event triggers the Ansible rule. The triggered playbook restarts the failed service.

In the example, EDA only starts one action. The rulebook could alternatively use the Actions keyword and then perform several actions in sequence. Because the complete event variable of the rulebook is not automatically available for the playbook, you have to use extra_vars to pass information from the rulebook variable into the playbook.

The referenced playbook starts the DNS server but needs to know on which host to start the service. As mentioned before, because the limit filter was not working when this example was created, I used a simple hack in the playbook instead, which explains why the start_dns.yml playbook looks like it does:

- hosts: "{{ event_host }}"
  gather_facts: no
  tasks:
  - name: Start DNS Service
    ansible.builtin.service:
      name: dnsmasq
      state: started

It simply takes the value from the event as the host variable and only performs the actions on the host that triggered the event.

Simple with Huge Potential

The example given is quite simple, but it shows the great potential of EDA. The rulebook used is, of course, not limited to one rule. You can react with further rules to combinations of source events and link the conditions to several sources (AND/OR) with something like:

condition:
  all:
    - event.host.name == "srv1.local.ip"
      - event.journald.process.name == "systemd"
      - event.systemd.unit == "dnsmasq.service"
      - event.message is search("Stopped DNS", ignorecase=true)

The event only triggers if all of the specified values match (AND). The any keyword starts the action if one of the specified conditions is true (OR). Actions also have more options. While developing your own rulebooks, you will often use print_event to view the complete event variable or parts of it and adjust your rules and playbooks accordingly.

The start_playbook action uses Ansible Runner to run a playbook in the EDA container. In the future, however, it will be far more interesting to launch an existing job template on an Ansible controller or an AWX setup, for which you can turn to the run_ job_template action; it connects to an existing controller or AWX system with a URL and a token. Sooner or later, EDA is likely to find its way into the Controller and AWX web UIs and become a part of those tools.

Conclusions

Event-Driven Ansible architecture continues the idea of automating target systems without an agent. However, any kind of practical implementation is still complicated at the current early stage. Drools is a powerful rules engine and was definitely undertasked with EDA's previous simple capabilities. The question inevitably arises as to whether EDA really needs the complex setup with Python, Java, and the JPY bridge.

On the other hand, EDA is likely to add massive functionality in future versions, precisely because it is based on such a powerful rules engine. Thanks to this modular, open concept, it will be possible to use EDA in many scenarios with many different sources in the future – as long as users and developers continue to develop the tool and provide additional source plugins.

The Author

Andreas Stolzenberger worked as an IT magazine editor for 17 years. He was the deputy editor in chief of the german Network Computing Magazine from 2000 to 2010. After that, he worked as a solution engineer at Dell and Vmware. In 2012 Andreas moved to Red Hat. There, he currently works as principal solution architect in the Technical Partner Development department.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus