Event-Driven Ansible for Ansible Automation Platform

Introduction

In my opinion, a big oversight in the initial implementation of Event-Driven Ansible (EDA) in Ansible Automation Platform (AAP) is that there is no built-in event source for events generated by AAP itself.

I had a customer request this to be able to apply some policy compliance on objects within AAP. For example, having a user create a credential with no Organization selected is allowed by AAP, but can cause problems with name clashes or inaccessibility later down the line. We could run a scheduled Ansible task to inspect and validate all our credentials have Organizations specified, but this leaves a window of invalid data, and might be quite intensive for large installs with many credentials.

This use case is a perfect candidate for the upcoming Policy As Code feature in AAP, but in the meantime, I was interested to see if we could use EDA to detect these objects being created and run a remediation automatically.

Rulebook Listener

The first step in this is to set up an EDA listener to listen for AAP events. A webhook listener can be used which will take any json-formatted input events and let us apply rules to them. The rulebook snippet below shows how you can detect the creation of credentials with no organization set.

  rules:
    - name: Empty Organization detected
      condition: >
        event.payload.operation == "create" and
        event.payload.object1 == "credential" and
        event.payload.changes.organization == null
      action:
        run_job_template:
          ...

We’re looking for event data where operation is set to “create” and the object1 type is “credential”. We want to detect the credential creation where no organization is defined. Despite all of the debug of event data showing the “None” value for the organization field, in the condition syntax you actually need to compare to the value “null” (Sigh…). We can take any action we like when this event is matched. For example, we might delete the credential or notify the creator of the issue.

To help in testing, you can add a “catch all” rule to your rulebook which will log out the entire event payload so you can check the structure of the events being sent by AAP:

    - name: Default debug
      condition: event.payload is defined
      actions:
        - debug:
            var: event.payload

AAP Logging Aggregation

Now that we have a rulebook listening for events, we need to forward them from AAP. AAP has a very flexible logging export and aggregation system. Initially I thought I’d use the ‘other’ aggregator service, as I wasn’t using any of the other named tools. However, the format of the data send to my webhook listener was then definitely not JSON! (do not do this, EDA really did not like it). The Elastic (logstash) aggregator service sends JSON-formatted events, so instead I tried using that and configured it to point at my EDA listener.

My full AAP logging settings are shown below.

AAP Logging Settings

A couple of things to note:

1) In my lab environment the host is set to ‘localhost’ because I’m running the containerized AAP installation on a single VM. In a larger installation, the host will need to be the name of the host running the EDA rulebook activations, or the hostname/IP address defined in the rulebook event source itself.

2) I turned off all the loggers except for ‘activity_stream’. If you had use cases to trigger automation based on other AAP logging data (job execution, for example), you could leave all the loggers enabled.

Results

With the rulebook in place, I can create a new credential with no Organization set:

Credential with no Organization

and see that the rulebook activation launches my job template:

Event Detected with No Organization

Creating a Credential with an Organization defined:

Credential with an Organization

Doesn’t trigger any playbook action:

No Event Detected

There’s a lot of scope for taking other automated actions in response to users creating / updating / deleting objects within AAP, not just for compliance. AAP’s upcoming Policy As Code function will help with a lot of these sorts of requirements, but as with a lot of EDA setups, there’s a huge scope for other use cases. Let me know if you think of something cool!

The code for the rulebook can be found here