Event-Driven Ansible in the Wild (Part 1/2)

We’ve already shown what Event-Driven Ansible and ansible-rulebook are, and how they can be run on command-line in this previous blogpost and the extensive article in Heise’s iX magazine (german). Now, we want to go a step further and use the tools EDA-Server and Ascender to run Event-Driven Ansible in a more enterprise-like environment.

EDA-Server

EDA-Server is a tool that offers management, scaling and observability functionality around your ansible-rulebook runs. As part of Red Hat’s Ansible Automation Platform, EDA-Server is called EDA-Controller. There’s an official Kubernetes operator eda-server-operator to install EDA-Server on your favourite Kubernetes flavour. In our techlab, we installed k3s on a Rocky Linux 9 VM and used the operator to run EDA-Server on top of it. However, we had to fight with a few issues. First of all, the container images of EDA-UI changed the ports where the webserver listens and therefore, the operator’s Liveness and Readiness-Probes always failed. That’s why we installed the specific older version 2.4.454 of the EDA-UI container image. The corresponding problem is described in this Github issue.

After spinning up the operator with the default Kustomization file, we used the following deployment file for EDA-Server:

---
# EDA-Server TLS Certificate and Key
apiVersion: v1
data:
  tls.crt: <omitted>
  tls.key: <omitted>
kind: Secret
metadata:
  name: edaserver-tls-secret
  namespace: eda
type: kubernetes.io/tls
---
# Admin Password
apiVersion: v1
kind: Secret
metadata:
  name: edaserver-app-admin-password
  namespace: eda
stringData:
  password: <omitted>
---
# EDA Server Object
apiVersion: eda.ansible.com/v1alpha1
kind: EDA
metadata:
  name: edaserver-app
  namespace: eda
spec:
  automation_server_url: https://puzzle-ascender.workshop.puzzle.ch
  image: quay.io/ansible/eda-server
  image_version: main
  image_web: quay.io/ansible/eda-ui
  image_web_version: 2.4.454 #https://github.com/ansible/ansible-ui/issues/951
  admin_user: ansible
  admin_password_secret: edaserver-app-admin-password
  service_type: ClusterIP
  ingress_type: ingress
  ingress_tls_secret: edaserver-tls-secret
  ingress_path: "/"
  ingress_path_type: Prefix
  hostname: puzzle-edaserver.workshop.puzzle.ch
  extra_settings:
  - setting: CSRF_TRUSTED_ORIGINS
    value:
      - https://puzzle-edaserver.workshop.puzzle.ch

EDA-Server is designed to run together with AWX (or one of its twins Ascender or AAP-Controller). You have to specify an automation_server_url in your Kustomization file to let EDA-Server know where to trigger AWX job templates (aka your Ansible playbook runs).

Ascender

With all this set, we are able to spin up our EDA-Server instance and log in. If you didn’t specify any credentials on your own, and used all the default values from the deployment guide, you can retrieve the password with this command:

kubectl get secret eda-demo-admin-password -o jsonpath="{.data.password}" | base64 --decode

Connecting EDA-Server with Ascender

We use Ascender to run our Ansible playbooks. Like Red Hat’s AAP-Controller, Ascender is based on AWX and provides virtually the same functionality. We chose to install Ascender because there’s a handy installation script available. To start job templates, EDA-Server needs to be able to authenticate to Ascender. We achieve this by creating a token on Ascender, and add it to EDA-Server.

Decision Environment

Now we have almost everything in place to actually run our rulebooks. However, EDA-Server ships without Decision Environments (DE). A Decision Environment is a special version of an Execution Environment containing everything to run ansible-rulebook. We built our own DE by following the official documentation. However, we encountered some permission issues later when using the DE inside EDA-Server. Adjusting the permissions of the /opt folder as an additional build step solved these issues (Note: Don’t do this in production!).

Decision Environments are built with ansible-builder just like ordinary Execution Environments. Inside the image, we want to pack (among other things):

  • java-17-openjdk-devel as an rpm,
  • ansible-rulebook and other python packages,
  • ansible.eda Ansible collection providing source plugins.

The final yaml definition puzzle-de.yml we used to build our DE looked like the following:

---
version: 3
images:
  base_image:
    name: 'registry.access.redhat.com/ubi9/python-311:latest'
dependencies:
  galaxy:
    collections:
      - ansible.eda
  python:
    - azure-servicebus
    - aiobotocore
    - aiohttp
    - aiokafka
    - watchdog
    - systemd-python
    - dpath
    - ansible-rulebook
  ansible_core:
    package_pip: ansible-core==2.14.4
  ansible_runner:
    package_pip: ansible-runner
  system:
    - java-17-openjdk-devel [platform:rpm]
additional_build_steps:
  append_final:
    - RUN chmod -R 777 /opt

If you would like to use additional source plugins, you have to install their respective Ansible collections. The source plugin for Dynatrace tenants for example is found in the dynatrace.event_driven_ansible collection, ibm.turbonomic_eda would be another example.

After building the DE from the definition file puzzle-de.yml with the command below, we had everything in place to actually run a rulebook inside EDA-Server.
ansible-builder build -f puzzle-de.yml -t puzzle-de:latest

In the second part of this blogpost miniseries, we’ll show you how to set up on EDA-Server a rulebook activation that checks if some webpages are available and trigger an appropriate action on Ascender once a defined condition is met.

Are you interested in learning everything about these topics? Check out our brand new workshops here:

Kommentare sind geschlossen.