Image by: Andrew Neel - Pexels

PoC setup Ansible (cli)

the poc Sep 12, 2022

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 and ansible-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 :)

Tags

Riccardo B.

Riccardo is an all round Linux Systems Engineer with over 20 years of experience and a knack for Automation. Favoring acronyms like NAO, IaC, SRE and more. Also hardly ever writes in third person :)