Getting started with Ansible
The below was completed on a bare metal server install of EVE-NG.
EVE-NG is built upon Ubuntu 16.04 so all the below is pretty standard Linux/Ansible configuration.
By completing the below you are in effect creating an Ansible control node. Ansible then communicates with devices over SSH (no agent is needed on the managed devices). Below we are also setting netconf on Juniper devices to leverage the native device API.
As you can imagine Ansible (which is a product of RedHat) has extensive documentation and it can be found here - when getting more serious about Ansible then getting your file structure correct and ready for scaling up will reap dividends - check out this Best Practice guide.
Ansible Tower and now Ansible Engine exists where an organisation would like to pay for a supported GUI based controller for many playbooks and users.
Ansible have just (on the 7th Sept’ 2017) open sourced an upstream version of Ansible Tower and it’s here and it’s called AWX. AWX is a great way for you to try Tower or for an organisation to maintain the code and support it themselves.
An alternative open source GUI controller also exists called Semaphore.
Install steps, dependencies and notes.
Your server will need access to the Internet or locally mirrored repositories to complete all these steps with ease!
Create the Ansible user (you can use any username) while logged in as root and give them sudo access:
adduser ansible
usermod -aG sudo ansible
Login in as the user ansible and test; test by listing files in root:
sudo ls -la /root
Create an SSH key (no passphrase) to access devices using an SSH key - this avoids having credentials in playbooks or stored on the Ansible server:
ssh-keygen -t rsa -b 2048
Do initial updates and upgrades and then all the dependency installs:
sudo apt update
sudo apt upgrade
sudo apt install software-properties-common
sudo apt install -y ansible python-dev libxml2-dev libxslt1-dev zlib1g-dev software-properties-common python-setuptools build-essential
pip is the python installer management app:
sudo easy_install pip
sudo pip install ansible junos-eznc junos-netconify
sudo ansible-galaxy install Juniper.junos
This useful utility allows the SSH key created earlier to be installed on managed devices; see here for usage:
sudo pip install git+https://github.com/networkop/ssh-copy-net.git
Edit Ansible hosts file to work with devices:
sudo nano /etc/ansible/hosts
Example Ansible hosts file (setup Linux hosts file for name resolution or use IP addresses in the Ansible hosts file) - quite often referred to as the inventory. Note the use of different groupings - you can create as many of these as you like so you can target a device or group of devices as desired:
[MX]
vmx1 ansible_connection=local
vmx2 ansible_connection=local
vmx3 ansible_connection=local
vmx4 ansible_connection=local
vmx5 ansible_connection=local
vmx6 ansible_connection=local
vmx7 ansible_connection=local
[SRX]
oak01-r1 ansible_connection=local
ash01-r1 ansible_connection=local
oak02-r1 ansible_connection=local
ash02-r1 ansible_connection=local
[JUNIPER:children]
MX
SRX
[JUNIPER:vars]
juniper_user=ansible
juniper_port=830
As mentioned at the top SSH is used to communicate with a device so a user account on the device called ansible is needed with the SSH key and for Juniper devices we will utilise the netconf API to push and pull from the Juniper devices so that also needs configuring; Juniper example config below:
set system login user ansible uid 2001
set system login user ansible class super-user
set system login user ansible authentication ssh-rsa "ssh-rsa blahblahblah ansible"
set system services ssh
set system services netconf ssh
Check the netconf connection:
ssh -s ansible@vmx2 netconf
Some examples of ansible-playbook command line switches that use the ansible hosts file to target or limit devices or queries:
ansible-playbook get.yml -l JUNIPER -t get-config-system
ansible-playbook get.yml --limit=MX --tags=check-netconf
An example of a raw ad-hoc (single Ansible command line string - no playbook) test to a Cumulus VX:
ansible@eve-ng:/etc/ansible/work$ ansible spine01 -u cumulus --ask-pass -m "raw" -a "net show ver"
SSH password:
spine01 | SUCCESS | rc=0 >>
NCLU_VERSION=1.0
DISTRIB_ID="Cumulus Linux"
DISTRIB_RELEASE=3.3.1
DISTRIB_DESCRIPTION="Cumulus Linux 3.3.1"
Shared connection to spine01 closed.
An Ansible expert and colleague pointed out the following if you come across issues with writing to a device via a raw command or in a playbook, this will give you sudo/root equivalent when running actions against the device (as opposed to just logging into the device):
-b, --become run operations with become (does not imply password prompting)
-K, --ask-become-pass ask for privilege escalation password
Another mention of the above issue and fix in a Cumulus forum post.
The get.yml file content is provided below for reference as it’s mentioned above in the Check Connection section:
---
- name: GET
hosts: JUNIPER
roles:
- Juniper.junos
connection: local
gather_facts: no
# Execute tasks (plays) this way "ansible-playbook <path>/GET.yml --tags <tag-name>"
tasks:
# Check if a device is NETCONF-aware
- name: CHECK-NETCONF
tags: check-netconf
wait_for: host="" port=""
### JUNOS_GET_CONFIG SECTION
# Execute "show configuration" and save output to a file
- name: GET-CONFIG
tags: get-config
junos_get_config: host="" port=""
format=text
dest="/opt/juniper/_get-config.output"
### JUNOS_CLI SECTION
# Get list of interfaces and save output to a file
- name: GET-INTERFACES
tags: get-interfaces
junos_cli: host="" port=""
dest="/opt/juniper/_get-interfaces.output"
cli="show interfaces terse"
### EOF ###
ansible-playbook command line switches:
Usage: ansible-playbook playbook.yml
Options:
--ask-vault-pass ask for vault password
-C, --check don't make any changes; instead, try to predict some
of the changes that may occur
-D, --diff when changing (small) files and templates, show the
differences in those files; works great with --check
-e EXTRA_VARS, --extra-vars=EXTRA_VARS
set additional variables as key=value or YAML/JSON
--flush-cache clear the fact cache
--force-handlers run handlers even if a task fails
-f FORKS, --forks=FORKS
specify number of parallel processes to use
(default=5)
-h, --help show this help message and exit
-i INVENTORY, --inventory-file=INVENTORY
specify inventory host path
(default=/etc/ansible/hosts) or comma separated host
list.
-l SUBSET, --limit=SUBSET
further limit selected hosts to an additional pattern
--list-hosts outputs a list of matching hosts; does not execute
anything else
--list-tags list all available tags
--list-tasks list all tasks that would be executed
-M MODULE_PATH, --module-path=MODULE_PATH
specify path(s) to module library (default=None)
--new-vault-password-file=NEW_VAULT_PASSWORD_FILE
new vault password file for rekey
--output=OUTPUT_FILE output file name for encrypt or decrypt; use - for
stdout
--skip-tags=SKIP_TAGS
only run plays and tasks whose tags do not match these
values
--start-at-task=START_AT_TASK
start the playbook at the task matching this name
--step one-step-at-a-time: confirm each task before running
--syntax-check perform a syntax check on the playbook, but do not
execute it
-t TAGS, --tags=TAGS only run plays and tasks tagged with these values
--vault-password-file=VAULT_PASSWORD_FILE
vault password file
-v, --verbose verbose mode (-vvv for more, -vvvv to enable
connection debugging)
--version show program's version number and exit
Connection Options:
control as whom and how to connect to hosts
-k, --ask-pass ask for connection password
--private-key=PRIVATE_KEY_FILE, --key-file=PRIVATE_KEY_FILE
use this file to authenticate the connection
-u REMOTE_USER, --user=REMOTE_USER
connect as this user (default=None)
-c CONNECTION, --connection=CONNECTION
connection type to use (default=smart)
-T TIMEOUT, --timeout=TIMEOUT
override the connection timeout in seconds
(default=10)
--ssh-common-args=SSH_COMMON_ARGS
specify common arguments to pass to sftp/scp/ssh (e.g.
ProxyCommand)
--sftp-extra-args=SFTP_EXTRA_ARGS
specify extra arguments to pass to sftp only (e.g. -f,
-l)
--scp-extra-args=SCP_EXTRA_ARGS
specify extra arguments to pass to scp only (e.g. -l)
--ssh-extra-args=SSH_EXTRA_ARGS
specify extra arguments to pass to ssh only (e.g. -R)
Privilege Escalation Options:
control how and which user you become as on target hosts
-s, --sudo run operations with sudo (nopasswd) (deprecated, use
become)
-U SUDO_USER, --sudo-user=SUDO_USER
desired sudo user (default=root) (deprecated, use
become)
-S, --su run operations with su (deprecated, use become)
-R SU_USER, --su-user=SU_USER
run operations with su as this user (default=root)
(deprecated, use become)
-b, --become run operations with become (does not imply password
prompting)
--become-method=BECOME_METHOD
privilege escalation method to use (default=sudo),
valid choices: [ sudo | su | pbrun | pfexec | doas |
dzdo | ksu | runas ]
--become-user=BECOME_USER
run operations as this user (default=root)
--ask-sudo-pass ask for sudo password (deprecated, use become)
--ask-su-pass ask for su password (deprecated, use become)
-K, --ask-become-pass
ask for privilege escalation password