You are on page 1of 26

Creating Reusable

Ansible Code
Ivan Pepelnjak (ip@ipSpace.net)
Network Architect

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
Creating Reusable Ansible Code
Challenges:
• Create reusable bits of code
• Use the same modules in multiple projects
Ansible Includes
• Playbook-level includes (include plays or whole playbooks)
• Play-level includes (include tasks)
Ansible Roles
• Include tasks, templates, plugins
• Specify default variables
• Overwrite variables
Further options
• Plugins
• Jinja2 macros

2 This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Includes

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
Ansible Include Functionality
Include command
• Playbook-level: include plays
• Play-level: include tasks

Features
• Specify included file name as an expression
• Specify variables (parameters) for included tasks/plays
• Use looping construct (with_*) on included tasks for complex loops

4 This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Example: Create Device Configurations
configs-initial.yml
---
- hosts: localhost
name: Create directory
tasks:
- file: path=configs state=directory

- hosts: all
tasks:
- template: src=ios/common.j2 dest=configs/{{inventory_hostname}}.txt
name: create configuration for IOS devices
when: ansible_os == 'ios'

- hosts: all
tasks:
- template: src=nxos/common.j2 dest=configs/{{inventory_hostname}}.txt
name: create configuration for Nexus devices
when: ansible_os == 'nxos'

5 This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Extract Common Play into an Included File
configs-setup.yml
---
- include: setup-directory.yml
Playbook-level include
name: set up working directories

- hosts: all
tasks:
- template: src=ios/common.j2 dest=configs/{{inventory_hostname}}.txt
when: ansible_os == 'ios'

setup-directory.yml
---
- hosts: localhost Included file contains
name: Create directory one or more plays
tasks:
- file: path=configs state=absent
when: cleanup is defined
- file: path=configs state=directory

6 This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Parametrized Include
configs-setup.yml
---
- include: setup-directory.yml
name: set up working directories
vars:
cleanup is set only within
cleanup: 1
included file
- hosts: all

setup-directory.yml
---
- hosts: localhost
name: Create directory
tasks:
- file: path=configs state=absent Directory is removed
when: cleanup is defined (cleanup is defined)
- file: path=configs state=directory

7 This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Include File Specified In an Expression
configs-tasks.yml
---
- include: setup-directory.yml
name: set up working directories

- hosts: all Play-level include. Included


tasks: file contains tasks
- include: tasks/{{ansible_os}}-config.yml

Specify included file name with an expression

ios-config.yml
Included file contains list of tasks
---
- template: template path based on included file path
src: ../ios/common.j2
dest: configs/{{inventory_hostname}}.txt
name: create configuration for IOS devices

8 This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Included Files and Paths
Challenge:
• Tasks or plays included from a different directory

Input files are relative to the new directory


• Included variable files
• Further includes
• Templates…

Output files that are normally on remote host are relative to the original
directory
• Destination in template module
• Files managed with file module or changed with lineinfile or blockinfile
module

9 This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Complex Loops
Implemented with
Ansible Includes

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
Includes and Loops
Sad fact
• Ansible loops repeat a single task
• Loops don’t work with blocks
• You must use includes to loop over more than one task

How-to:
• Specify with_* iterator on an include directive
• Included task list is executed multiple times
• Use item variable in included tasks like you would in a single task

11This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Example: Ping Multiple Targets from All Devices
check-connectivity.yml
---
- hosts: ios
tasks:
- ios_command:
commands: ping {{item}}
provider: "{{cli}}"
with_items: "{{ping_target}}"
register: result
failed_when: "not '!!' in result.stdout[0]"

- hosts: nxos
tasks:
- nxos_command:
commands: ping {{item}}
provider: "{{cli}}"
with_items: "{{ping_target}}"
register: result
failed_when: "not 'icmp_seq' in result.stdout[0]"

12This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Create IOS (and NX-OS) Ping Module
ios-ping.yml
---
- name: "Ping {{item}} from IOS devices"
ios_command:
commands: ping {{item}}
provider: "{{cli}}" item will be set in parent playbook
ignore_errors: yes
register: result

- assert:
that: result.stdout[0] is defined
msg: Ping command crashed

- assert:
that: "'!!' in result.stdout[0]"
msg: "Cannot ping {{item}} from {{ansible_host}}"

13This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Execute Ping Multiple Times
ping.yml
---
- hosts: all
name: ping specified destinations from all hosts
tasks:
- name: Read the list of targets
include_vars: file=ping-targets.yml

- include: exec/{{ansible_os}}-ping.yml
with_items: targets
OS-specific ping command is
executed once for each target

14This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Ansible Roles

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
What Are Ansible Roles?

A role is the Ansible way of bundling automation content and


making it reusable.

galaxy.ansible.com/about

Roles are ways of automatically loading certain vars_files,


tasks, and handlers based on a known file structure.

Roles are just automation around ‘include’ directives […]


and really don’t contain much additional magic beyond some
improvements to search path handling for referenced files.

docs.ansible.com/ansible/playbooks_roles.html

16This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Roles Directory Structure
ping.yml
roles
├── network_device
│ ├── tasks
│ │ └── main.yml Included tasks
│ └── templates
│ ├── ios-common.j2 Role-specific templates
│ └── nxos-common.j2
└── ospf_router
├── defaults
│ └── main.yml Default variable values
├── meta
│ └── main.yml Role dependencies
├── tasks
│ └── main.yml
└── templates
├── ios-ospf.j2
└── nxos-ospf.j2

17This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Using Roles
config-example.yml
---
- include: setup-directory.yml
- hosts: all
vars:
configs: configs
roles:
- network_device
- { role: ospf_router, ospf_area: 1 }

• Include roles into a play by specifying roles parameter


• You can include multiple roles into a play
• You can set variables in included roles

18This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
What Really Happens Behind the Scenes
• Further roles are included based on dependencies listed in
meta/main.yml
• Variables are included from defaults/main.yml and vars/main.yml
• Role tasks are included into play from tasks/main.yml before any tasks
specified with the tasks parameter
• Play handlers are included from handlers/main.yml

Search paths include files, templates and tasks directories


• Jinja2 template can reference files in templates directory
• Tasks can include further files from tasks directory
• Copy and script modules can reference files from files directory

Role-specific search paths are enabled only for tasks included from the role

19This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Revised: Ansible Variable Precedence
Role defaults (defaults/main.yml) Play variables
Inventory file • Set with vars argument
• All group variable • Included with vars_files argument
• Group variables Inter-task variables
• Host variables • Registered results
Groups and hosts variable files • Variable set with set_fact
• group_vars/all.yml Role variables (vars/main.yml)
• group_vars/group.yml
Task block and individual task
• host_vars/host.yml
variables
Host facts
Extra variables passed via CLI

20This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Example: Using a Simple Role
config-simple.yml
- hosts: all
vars:
configs: configs
roles:
- network_device

roles/network_device/tasks/main.yml
--- Template fetched from role
- template: templates directory
src: {{ansible_os}}-common.j2
dest: {{configs}}/00-common-{{inventory_hostname}}.inc
name: create common device configuration
Output file is still relative to
original working directory

21This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Example: Using Multiple Roles
config-ospf.yml
- hosts: all
vars:
configs: configs
roles:
- network_device
…/defaults/main.yml
- ospf_router
---
roles/ospf_router/tasks/main.yml ospf_area: 0

---
- template:
src: {{ansible_os}}-ospf.j2
dest: {{configs}}/10-ospf-{{inventory_hostname}}.inc
name: create OSPF routing process

22This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Example: Role Dependencies
config-ospf-2.yml
- hosts: all
vars:
configs: configs
roles:
- ospf_router

roles/ospf_router/meta/main.yml
---
OSPF router is a network device
dependencies:
- network_device

Tasks from network_device role will be included


before tasks from ospf_router role. By default
every role is included only once

23This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Pre_tasks and Post_tasks
You might want to execute specific tasks before or after all other tasks:
• pre_tasks specifies a list of tasks that are executed first
• post_tasks specifies a list of tasks that are executed last

Order of task execution:


• pre_tasks
• Handlers notified from pre_tasks tasks
• Tasks included from roles tasks/main.yml files
• Tasks from roles specified in dependencies are included before tasks from the
parent role
• Handlers notified from roles tasks
• Tasks specified in tasks parameter and notified handlers
• post_tasks and notified handlers

24This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Complete Example
config-complete.yml
---
- hosts: all
vars:
configs: configs/{{inventory_hostname}}

pre_tasks:
- file: path={{configs}} state=directory

roles:
- ospf_router

post_tasks:
- assemble:
src: "{{configs}}"
dest: "configs/{{inventory_hostname}}.cfg"

25This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars
Questions?

Send them to ip@ipSpace.net or @ioshints

26This material is copyrighted


© ipSpace.net 2017 and licensed for the sole use by Mikel Maeso
Create(mikel.maeso@gmail.com
Reusable Ansible Code [85.87.178.33]). More information at http://www.ipSpace.net/Webinars

You might also like