Professional Documents
Culture Documents
Extending Ansible
Extending Ansible
ipSpace.net AG
This material is copyrighted and licensed for the sole use by Mikel Maeso (mikel.maeso@gmail.com [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Do’s and Don’t’s of Ansible
Ansible is automation engine
Ansible is not
• Generic programming language
• Data manipulation tool
• Database
Alternatives:
• Use Ansible Tower
• Use add_host action to create groups and hosts for later plays in the
same playbook
More @ http://docs.ansible.com/ansible/intro_dynamic_inventory.html
5 This material is copyrighted
© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso (mikel.maeso@gmail.com
Extending Ansible [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Existing Dynamic Inventory Scripts
Most inventory scripts are third-party contributions
• CloudStack, Docker, LXC, Nova, OpenStack, OpenShift, OVirt
• Azure, Digital Ocean, EC2, GCE
• Consul
• MDT
• Nagios
• NSoT
• Vagrant
• VirtualBox, VMware
More @ https://github.com/ansible/ansible/tree/devel/contrib/inventory
6 This material is copyrighted
© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso (mikel.maeso@gmail.com
Extending Ansible [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Dynamic Hosts
Use add_host module to add dynamic hosts to Ansible inventory
• Create new hosts
• Create a dynamic group
• Add Ansible variables (including ansible_host or ansible_user) to dynamic hosts
More @ http://docs.ansible.com/ansible/add_host_module.html
7 This material is copyrighted
© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso (mikel.maeso@gmail.com
Extending Ansible [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Example: Provision Service on a Subset of Nodes
transaction.yml
---
- hosts: localhost
name: Select network nodes participating in transaction
tasks:
- include: read-transaction-file.yml
- name: Build the list of participating network nodes
add_host:
name: "{{item.node}}"
groups: "deploy"
with_items: "{{transaction.ports}}"
- hosts: deploy
name: configure a single VLAN transaction
tasks:
- include: read-transaction-file.yml
- set_fact: data="{{lookup('template',…
This material is copyrighted and licensed for the sole use by Mikel Maeso (mikel.maeso@gmail.com [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Callback Plugins
Define the callback plugin to use in ansible.cfg
• callback_plugins: path for callback plugins
• callback_whitelist: list of enabled plugins
• stdout_callback: callback used to print to stdout
Useful callbacks:
• json: display playbook results in JSON format
• dense: display the minimal amount of information
• mail: send emails on failed tasks/plays
• selective: print tasks that have been marked with tag print_action
$ export ANSIBLE_STDOUT_CALLBACK=dense
$ export ANSIBLE_STDOUT_CALLBACK=selective
$ export ANSIBLE_STDOUT_CALLBACK=json
Sample results
{
"play": {
"id": "5e379943-5d6c-42aa-9b83-76bfd94c358e",
"name": "configure VLAN service"
},
"tasks": [
{
"hosts": {
"leaf-1": {
"_ansible_no_log": false,
"ansible_facts": {
"services": {
"ACME": {
…
$ export ANSIBLE_STDOUT_CALLBACK=json
Sample results
"stats": {
"leaf-1": {
"changed": 2,
"failures": 1,
"ok": 12,
"skipped": 7,
"unreachable": 0
},
"leaf-2": {
"changed": 2,
"failures": 1,
"ok": 10,
"skipped": 6,
"unreachable": 0
}}
This material is copyrighted and licensed for the sole use by Mikel Maeso (mikel.maeso@gmail.com [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Extending Ansible with Jinja2 Filters and Tests
Jinja2 plugins are the easiest way to extend Ansible
• Simple interface
• No asynchronous/distributed code
• Easy to test – you can test them in Python
A few ideas
• Get data from database/IPAM
• Transform data
• Complex data formatting
• Perform complex checks
class FilterModule(object):
def filters(self):
return { 'append': list_append }
Challenge: pollution of global namespace move filter methods into the class
17This material is copyrighted
© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso (mikel.maeso@gmail.com
Extending Ansible [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Simple Jinja2 Filter: Append to List
List.py (simple)
class FilterModule(object):
def list_append(self,l,*argv):
for element in argv:
l.append(element)
return l
def filters(self):
return { 'append': self.list_append }
Jinja2 filter moved into the class (no longer visible from the outside)
• Filter method has to specify an extra argument (self = object reference)
• Filter method reference has to use self (method within a class)
Based on http://www.dasblinkenlichten.com/creating-ansible-filter-plugins/
18This material is copyrighted
© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso (mikel.maeso@gmail.com
Extending Ansible [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Simple Jinja2 Filter: Error Handling
List.py
from jinja2 import TemplateError
class FilterModule(object):
def list_append(self,l,*argv):
if type(l) is not list:
raise TemplateError("First argument must be a list")
for element in argv:
l.append(element)
return l
def filters(self):
return { 'append': self.list_append }
class FilterModule(object):
def list_append(self,l,*argv):
if type(l) is not list:
raise TemplateError("First argument must be a list")
for element in argv:
if type(element) is list:
l.extend(element)
else:
l.append(element)
return l
def filters(self):
return { 'append': self.list_append }
def device_type(self,show_ver,*deftype):
if "Cisco IOS" in show_ver: return "ios"
if "NX-OS" in show_ver: return "nx-os"
def filters(self):
return {
'device_type': self.device_type
}
This material is copyrighted and licensed for the sole use by Mikel Maeso (mikel.maeso@gmail.com [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Connecting to External Databases
Ansible has no database connection module