Technical Articles
F5 SMEs share good practice.
Showing results for 
Search instead for 
Did you mean: 
F5 Employee
F5 Employee


Event Driven Security is one of the projects I have been working on for the last year or so. The idea of creating automated security that can react similarly to how I would react in situations is fascinating to me, and then comes the BIG Question.... "Can I code it?"

Originally our solution we had utilized ELK (Elastic Logstash Kibana) where Elasticsearch was my logging and monitoring tool, Kibana was the frontend GUI for helping me visualize and set up my watchers for my webhook triggers, Logstash would be an intermediary to receive my webhooks to help me execute Ansible related code.

While using Logstash, if the Ansible code was simple it had no issues, however when things got more complex (i.e., taking payloads from Elastic and feeding them through Logstash to my playbooks), I would sometimes get intermittent results. Some of this could be my lack of knowledge of the software but for me it needed to be simple!

As I want to become more complex with my Event Driven Security, I needed a product that would follow those needs. And luckily in October 2022 that product was announced "Event Driven Ansible" it made it so I didn’t need Logstash anymore i could call Ansible related code directly, it even took in webhooks (JSON based) to trigger the code, so I was already half way there!



So now I have setup the preface let’s get down to the good stuff!  I have setup a GitHub repository for the code i have been testing with Which is free for all to use and please feel free to take/fork/expand!!! 

There are some cool things worth noting in the code specifically the transformation of the watch code into something usable in playbooks. This code will take all the times the watcher finds a match in its filter and then then copies the Source IP from that code and puts it into a CSV list, then it sends the list as a variable within the webhook along with the message to execute the code.

Here is the code I am mentioning above about transforming and sending the payloads in an elastic watcher. See the Full code in the GitHub repo.

  "actions": {
    "logstash_exec": {
      "transform": {
        "script": {
          "source": """
            def hits = ctx.payload.hits.hits; 
            def transform = ''; 
            for (hit in hits) 
                transform += hit._source.src_ip;
                transform += ', '
            return transform;
          "lang": "painless"
      "webhook": {
        "scheme": "http",
        "host": "",
        "port": 5000,
        "method": "post",
        "path": "/endpoint",
        "params": {},
        "headers": {},
        "body": """{
			"message": "Ansible Please Turn on AWAF Policy",
			"payload": "{{ctx.payload._value}}"


In the Ansible Rulebook the big thing to note is the var_root field, this allows us to pass along the payload and message without all the webhook POST fields it narrows it down to the minimalistic fields that i passed through and want.  This also creates what is called ExtraVars in Ansible. ExtraVars are a way to add variables that are not hardcoded into playbooks, but rather they are more dynamic in nature. These dynamic variables allow me to make my code more as a template rather than a single use playbook.  

- name: Listen for events on a webhook
  hosts: all

  ## Define our source for events

    - ansible.eda.webhook:
        port: 5000

  ## Define the conditions we are looking for

    - name: Say Hello
      condition: event.payload.message == "Ansible Please Block Some IPs"
          name: f5-playbooks/block-ips-playbook/block-ips.yaml
          var_root: payload
          post_events: true


In the Playbook you can see how we extract the payload from the event using the ansible_eda variable, this allows us to pull in the event we were sent from the rulebook and using the var_root variable to narrow down the specific fields we needed (Message and Payload) from there we create an array from that payload so we can pass it along to our F5 code to start adding Blocked IPs to the WAF Policy.

- name: ASM Policy Update with Blocked URLS, IPs or Both
  hosts: lb
  connection: local
  gather_facts: false 
    Blocked_IPs_Events: "{{ ansible_eda.event.payload }}"
    F5_VIP_Name: VS_WEB
    F5_VIP_Port: "80"
    F5_Admin_Port: "443"
    ASM_Policy_Name: "WAF-POLICY"
    ASM_Policy_Directory: "/tmp/f5/"
    ASM_Policy_File: "WAF-POLICY.xml"


  - name: Setup provider
      server: "{{ ansible_host }}"
      user: "{{ ansible_user }}"
      password: "{{ ansible_password }}"
      server_port: "{{ F5_Admin_Port }}"
      validate_certs: "no"

  - debug:
      msg: "{{ ansible_eda.event }}"

  - debug:
      msg: "{{ Blocked_IPs_Events }}"

  - name: Create Array from BlockedIPs
        Blocked_IPs: "{{ Blocked_IPs_Events.split(', ') }}"
    when: Blocked_IPs_Events is defined

  - name: Remove Last Object from Array which is empty array object
        Blocked_IPs: "{{ Blocked_IPs[:-1] }}"
    when: Blocked_IPs_Events is defined


All of this combined, creates a well-oiled setup that looks like the following diagram below, with the code and the flows setup we can now create proactive event based security!


Here is the flow of the code that is in the GitHub repo when executed.

  • The F5 BIG-IP is pushing all the monitoring logs to Elastic.
  • Elastic is taking all that data and storing it while utilizing a watcher with its filters and criteria,
  • The Watcher finds something that matches its criteria and sends the webhook to Event Driven Ansible
  • Event Driven Ansibles Rulebook triggers an Ansible Playbook to secure the F5 BIG-IP

In the End we go Full Circle, starting from the F5 BIG-IP and ending at the F5 BIG-IP!



I am happy to announce at this RedHat Summit and AnsibleFest in Boston we will be showing a demonstration of our solution utilizing EDA + F5 BIG-IP (will be posted soon to YouTube for all!) 

I will also be at the RedHat Summit the Week of May 22nd at our Sponsor booth and doing two lightning presentations at the Discovery Theater. If you are there, feel free to stop by and let’s have a chat!  



Version history
Last update:
‎25-May-2023 10:11
Updated by: