September 18, 2018

Ansible Playbook as an Event Callback in CloudForms


Running your own Ansible playbooks upon ManageIQ/CloudForms provider event opens unimaginable possibilities to automate your data centers. This blogpost and accompanying YouTube video is a step-by-step tutorial that will show you how to unleash the power of Ansible within CloudForms. Our example is based on Nuage Networks provider and focuses on triggering a playbook executed when a "new enterprise was created" event occurs on remote server. The playbook connects to the remote server and automatically provisions a dozen of entites in the newly created enterprise.

For the Impatient

We'll focus mostly on explaining how our auxiliary Ansible role works in this blog post. But you can skip directly to the CloudForms: Ansible Playbook as a Callback to Nuage Event video where we demonstrate the entire integration from zero to the state where the playbook gets triggered upon the event. Here's the agenda:

  • Look at the format of the nuage_auth and the event variables.
  • Quickly go through the sample playbook.
  • Import the sample playbook into ManageIQ.
  • Hook it to the nuage_enterprise_create event.
  • Provide Nuage credentials in a form of Automation Instance attributes.
  • Show where the playbook logs are available.

CloudForms: Ansible Playbook as a Callback to Nuage Event

Goals

Nuage Networks asked us to help them integrate their software-defined networking (SDN) solution into ManageIQ. One of their top priority requirements was the ability to run the custom workload based on events emitted by the Nuage server, preferrably the workload written in a form of Ansible playbooks.

There were more specifications to it: the playbook had to be able to access JSON payload that the event was emitted with, as it contains vital information which may influence what actions the playbook runs.

Furthermore, the playbook had to be provided with the five Nuage credential variables that are required by the nuage_vspk Ansible module:

  • username (string)
  • password (encrypted string)
  • enterprise aka. user scope (string)
  • endpoint URL (string)
  • api version (string)

The five credential variables are necessary to authenticate against the Nuage server and manage it e.g create a new router, create a new subnet etc.

Design

Turns out ManageIQ was already able to consume events from the Nuage server and was therefore able to execute different Automation Instances based on event types - so we had 90% of the requirement done for free :)

The Automation Engine, moreover, feeds Instance with the entire event data upon execution so we only had to somehow grab it from within the playbook. Similarly goes for Nuage credential variables - it's easy to specify custom attributes on an Instance, even the encrypted ones, for example:

Nuage credentials as Automation Instance attributes.

Nuage credentials as Automation Instance attributes.

And those custom attributes are all present when the Instance runs. It's all there somewhere, but where exactly?

So the only missing part was a glue between the Automation Engine and the playbook: both - JSON payload of the event and the Nuage credentials attributes - had to be consumed somehow by the playbook.

Spoiler alert: the missing part is implemented by means of ManageIQ RESTful API.

Yeah so we provided a new Ansible role, xlab_si.nuage_miq_automate, to perform the interaction between the Automation Engine and the playbook by means of ManageIQ RESTful API. The role silently carries out the communication and yields two simple yet useful variables to the playbook: nuage_auth and event.

The rest of the blogpost describes how exactly the role works and eventually demonstrates how playbook writers can use it in their playbooks that are hooked to Nuage events.

How the Role Works

We developed a new role, the xlab_si.nuage_miq_automate, which consumes the ManageIQ RESTful API to obtain desired data. Merely two API requests are needed:

  • Fetch Automation Workspace via ManageIQ API.
    • Parse event id out of it.
    • Parse Nuage credentials out of it.
  • Fetch event record via ManageIQ API (using event id from the previous step).
    • Parse JSON payload out of it.

And to make things dead simple there is that syncrou.manageiq-automate role available at the Ansible Galaxy portal. It's an official ManageIQ role that promises ease of access to the Automation Workspace. And man do they keep the promise!

Providing Credential Variables

So in our new role, we rely heavily on the official syncrou.manageiq-automate role which makes fetching Nuage credentials from Automation Instance attributes as simple as it can get:

- name: "Obtain username"
  manageiq_automate:
    workspace: "{{ workspace }}"
    get_attribute:
      object: "{{ object }}"
      attribute: nuage_username
  register: nuage_username

- name: "Obtain password"
  manageiq_automate:
    workspace: "{{ workspace }}"
    get_decrypted_attribute:
      object: "{{ object }}"
      attribute: nuage_password
  register: nuage_password

- ... # similar for enterprise, url and api version

- set_fact:
    nuage_auth:
      api_username:   "{{ nuage_username.value }}"
      api_password:   "{{ nuage_password.value.value }}"
      api_enterprise: "{{ nuage_enterprise.value }}"
      api_url:        "{{ nuage_url.value }}"
      api_version:    "{{ nuage_api_version.value }}"

The manageiq_automate module is part of the syncrou.manageiq-automate role and in the example above we use it five times to fetch all Nuage credential variables from the Automation Workspace. Eventually, we pack all of them in a nuage_auth variable which is directly consumable by whichever playbook required the role.

Providing JSON Event Payload

Here, too, we make use of the syncrou.manageiq-automate role to fetch the EventStream record and then extract its JSON payload into a variable called event.full_data:

- name: "Obtain EMS event"
  manageiq_automate:
    workspace: "{{ workspace }}"
    get_vmdb_object:
      object: root
      attribute: event_stream
  register: stream

- name: "Parse event full data"
  set_fact:
    event:
      full_data: "{{ stream.value.full_data }}"

And that's it, that's all what our brand new xlab_si.nuage_miq_automate role does! It provides you with nuage_auth and event variables that you can use in your custom playbook.

Example Playbook

Below you can find an example playbook (taken from example repository) that can be assigned as a callback to the arbitrary Nuage event, e.g. nuage_subnet_create. It first requires the xlab_si.nuage_miq_automate role to get nuage_auth and event variables populated. Then it logs them both. Eventually it performs some simple interaction with the Nuage server using nuage_vspk Ansible module - namely, it fetches the entity that raised the event - and logs it.

- name: Ansible Playbook as an Event Callback
  hosts: all

  roles:
  - xlab_si.nuage_miq_automate
  
  tasks:
  - debug: msg="I'm a playbook running as event callback and here are my credentials"
  - debug: var=nuage_auth
  - debug: msg="Here are details of the event that triggered me"
  - debug: var=event
  - debug: msg="I'm now ready to do some work!"
  - name: Fetch entity from Nuage
    delegate_to: localhost
    nuage_vspk:
      auth: "{{ nuage_auth }}"
      type: "{{ event.full_data.entityType | capitalize }}"
      command: find
      id: "{{ event.full_data.entities[0].ID }}"
    register: entity
  - debug: var=entity

Summary

The example playbook above demonstrates how trivial it is to run your custom workload upon the EMS event. Having the xlab_si.nuage_miq_automate role required you don't even need to worry about Automation Workspace etc. and instead focus on implementing whatever the playbook is supposed to do.

In this blog post we focused on explaining how the xlab_si.nuage_miq_automate role works and how can it be consumed by playbooks. Check out the CloudForms: Ansible Playbook as a Callback to Nuage Event video where we demonstrate the entire integration from zero to the state where the playbook gets triggered upon the event.

Contact Us

Need support getting your Ansible playbooks work with ManageIQ/CloudForms? Get in touch with us and we’ll be happy to help you out. Just drop an email to our software defined data centers team sddc@xlab.si. Additionally, you can ping us on Twitter or leave a comment on Reddit.