Ansible Playbook as an Event Callback in CloudForms
September 18, 2018 - Words by Miha Pleško - 6 min read
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 theevent
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.
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:
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 Steampunk team [email protected] or visit us at steampunk.si . Additionally, you can ping us on Twitter or leave a comment on Reddit .