PoC setup Ansible (cli)
This will describe actions to install Ansible for Command Line and use with Cisco Equipment. I will assume that you would add this data to Git yourselves :)
Since Cisco still uses Diffie Hellman kex and my regular Gentoo box doesn't support this i'm using CentOS-Stream 8 for the initial set-up.
Note: Some settings are specifically for Cisco devices. To use this for just Linux, change the ssh args in ansible.cfg and dont install the requirements.
Initial Setup
Lets start with the directory structure. Create, or have, a generic non-root user. Log in to this user.
For my own set-up i am placing my directories inside the poc
directory, so its nested one level deeper than required.
Directories
mkdir -p ~/Repos/poc/{ansible,ansible-facts,ansible-inventory}
cd ~/Repos/poc/ansible
mkdir -p {collections,playbooks,roles,scripts,log}
cd ~/Repos/poc/ansible-inventory
mkdir {host_vars,group_vars}
mkdir group_vars/all
mkdir ~/Repos/ansible-facts/old
cd ~/Repos/poc
find ./ -mindepth 1 -type d -empty -exec touch {}/.keep \;
Gitignore
Place a simple gitignore file in the Ansible directory
*.bak
*.db
*.db-journal
*.pyc
*.sql
*.swp
*.tmp
*.xls*
venv/*
collections/*
log/*
Packages
The following packages are needed to be installed
sudo yum install python39 sshpass
Note: Everyone on the internet adds '-y' to yum install
commands. Dont do this, it's bad practice. It will remove the ability for you to review what is being done, so it can be potentially dangerous to do so.
Setup Ansible
To install Ansible the following actions are required.
Pip
cd ~/Repos/poc/ansible
python3.9 -m venv venv # this will create the virtual environment
source venv/bin/activate # Activate the virtual environment
pip install ansible
pip install paramiko
pip install ansible-pylibssh
pip freeze | tee requirements.txt
Scripts
I always bring a few scripts with me for convenience. Honestly havent looked at these in a while, i just change them to suit my needs when they dont work any more :)
Save the one below as scripts/update-facts.sh
#!/bin/bash
SGIT=`which git|head -n 1`
WORKDIR="~/Repos/poc/ansible"
if [[ -d $WORKDIR ]] ; then
cd $WORKDIR
factsdir=$(grep fact_caching_connection ansible.cfg | awk -F '=' '{print $2}')
update=$(date +%Y%m%d)
if [[ $factsdir != "" ]] ; then
cd $factsdir
find ./ -maxdepth 1 -mindepth 1 -type f -mtime +30 -exec mv {} old/ \;
$SGIT add -A ./
$SGIT commit -a -m "${update}"
$SGIT push
fi
fi
Save the one below as scripts/update-inventory.sh
#!/bin/bash
CURDIR=`pwd`
DATUM=`date`
cd ~/Repos/poc/ansible-inventory
git add -A ./
git commit -a -m "${DATUM}"
git push
cd $CURDIR
Save the one below as scripts/update-pip-environment.sh
#!/bin/bash
# XXX This script will update the software packages installed in the virtual environment.
# Ensure venv is running.
venvon=`set |grep -q "^deactivate"`
if [[ ${venvon} -eq 0 ]] ; then
echo "Updating installed packages."
pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U
if [[ -f requirements.txt ]] ; then
pip freeze | sort | tee requirements.txt
echo "updated requirements.txt"
fi
else
echo "The virtual environment is not running."
echo "Make sure to do: "
echo " source venv/bin/activate"
echo "first before running this script."
exit 1
fi
Edit
The last scripts is also one of convenience, its is more intended for editing files that contain sensitive data, for instance inventory files
since they usually contain passwords etc.
Save the one below as scripts/edit.sh
#!/bin/bash
if [[ $1 != "" ]]; then
if [[ -f $1 ]] ; then
head -n 1 $1 | grep -q AES256 ; if [[ $? -eq 0 ]]; then
echo "Encrypted"
sleep 0.5
ansible-vault edit $1
else
vim $1
fi
else
echo "Creating new Encrypted file"
sleep 0.5
ansible-vault create $1
fi
fi
edit the file ~/.bashrc
if [[ -f ~/Repos/poc/ansible/scripts/edit.sh ]] ; then
alias edit='~/Repos/poc/ansible/scripts/edit.sh'
fi
and since we dont like to logout/login nor reload our virtual environment, run the following on the command line:
alias edit='~/Repos/poc/ansible/scripts/edit.sh'
Config
By default ansible will look in /etc/ansible for files and then several other directories and our working directory.
We will have to create our own in ~/Repos/poc/ansible
Create the file ansible.cfg
[defaults]
inventory = ../ansible-inventory
nocolor=1
nocows=1
remote_user = cisco
retry_files_enabled = true
retry_files_save_path = /tmp/
roles_path = ./roles/
collections_paths = ./collections/
forks = 5
log_path = ./log/ansible.log
vault_password_file = ~/.ansible_vault_pass
stdout_callback = skippy
deprecation_warnings=False
fact_caching = jsonfile
fact_caching_connection = ../ansible-facts/
fact_caching_timeout = 3600
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False
[ssh_connection]
pipelining = true
ssh_args = -C -o KexAlgorithms=+diffie-hellman-group-exchange-sha256 -o Ciphers=aes128-ctr,aes192-ctr,aes256-ctr
Password
Execute the following to set the ansible encryption key. Be sure to save the file somewhere safe, otherwise you'll end up reverse engineering a lot of data if you lose it.
openssl rand -hex 16 > ~/.ansible_vault_pass
chmod 600 ~/.ansible_vault_pass
Collections
Before we do, do the following first. I've run into this issue numerous times and it's silly this hasnt been fixed yet. But collections demands to look in the /etc/ansible
directory. Strict settings prohibit this from working.
chmod 755 /etc/ansible
Save the file below as collections/requirements.yml
---
collections:
- name: cisco.nxos
- name: cisco.ios
- name: cisco.iosxr
Execute the following to install the collections:
ansible-galaxy collection install -r collections/requirements.yml
Fin
So by now all directories, files, modules etc have been installed.
The next part will be to start creating roles and configuring routers.
To explain, or mansplain :) , some of the directories.
playbooks
or plays in the main working directory are just messy, its better to give them a separate directory and work with them relative from where you are. F.i.ansible-playbook playbooks/blah.yml
- separate
ansible-inventory
andansible-facts
directories, this is mainly for a later intended use with Ansible Tower (AWX), or as someone from RedHat told me, its called AAP now. (In dutch this means Monkey and its a name i can totally agree with)
So the fun part will be next :)