Ansible & Cisco ACI
This is a straight forward guide on getting started with Ansible on Ubuntu with Cisco ACI APIC.
This guide uses;
- VMware Workstation 12 Pro 12.5.2 build-4638234
- Ubuntu 16.04.3
- Python 2.7
- Ansible 2.3.2.0
- Cisco ACI 2.x => 3.x. (dcloud virtual & real deployments)
Install Ubuntu Server
Install Ubuntu Server 16.04.3 LTS in VMware workstation using the Ubuntu ISO downloaded from https://www.ubuntu.com/download/server.
After installation, within console on Ubuntu, install ssh and change root password
# apt-get install ssh
# sudo passwd root
Install Python 2.7
Python 2.7 is likely to be installed already with the install of Ubuntu. Typing “python –version” at the command prompt will provide you with the currently installed version if it installed.2.7.x is required, if python is not installed or is not at version 2.7.x then follow the next steps to install.
# apt-get install python
# apt-get install python-pip
# pip install –upgrade pip
Install Ansible
The ansible installation guide can be found here, although the required steps are given below. This will install the latest version available through apt-get.
# apt-get install software-properties-common
# apt-add-repository ppa:ansible/ansible
# apt-get update
# apt-get install ansible
At this stage typing “ansible –version” at the command prompt will give you the version number which for this installation is 2.3.2.0.
Install Cisco APIC Python Eggs
These eggs are the Cisco Cobra files which provide the interface between Python and the APIC. Create a temporary directory for downloads, in this install I created a folder on the root called \apicsetup, within this I created a folder called \eggs. The Cisco APIC controller provides the required version of the eggs, these are available via HTTP from the APIC.
Download the two .egg files from APIC (http://aa.bb.cc.dd/cobra/_downloads/ to the current directory, i.e. /apicsetup/eggs/, example below for an APIC controller on v3.0.1k.
# wget “http://198.19.254.61/cobra/_downloads/acicobra-3.0_1k-py2.7.egg”
# wget “http://198.19.254.61/cobra/_downloads/acimodel-3.0_1k-py2.7.egg”
If you are not in the correct directory, adding ‘-O /apicsetup/eggs/’ will put in the /apicsetup/eggs/ folder
Both eggs files needs to be installed. The ‘acicobra’ egg must be installed first. Install the eggs;
# easy_install -Z /apicsetup/eggs/acicobra-X.Y_Zj-py2.7.egg
# easy_install -Z /apicsetup/eggs/acimodel-X.Y_Zj-py2.7.egg
This will complete the installation of the eggs for Cobra. The full installation guide can be found on the APIC controller at http://aa.bb.cc.dd/cobra/install.html
Install Cisco Ansible Python Scripts
Cisco provides Python scripts to be used with Ansible and are available at Github. These files relate to each of the modules documented at ansible.com, the Cisco module documentation for these modules is here. We will use the git command to clone the git repository into a new subdirectory (/aci-ansible) our temporary directory we created earlier (/apicsetup/aci-ansible). Before we clone the repository we need to install the git tools.
# apt-get install git
Then clone the repo. into /apicsetup/aci-ansible
# git clone https://github.com/datacenter/aci-ansible /apicsetup/aci-ansible
We need to copy some files from this cloned repo into the python folders as follows:
# cp /apicsetup/aci-ansible/module_utils/aci.py /usr/lib/python2.7/dist-packages/ansible/module_utils/aci.py
# mkdir /usr/lib/python2.7/dist-packages/ansible/modules/network/aci-ansible
# cp /apicsetup/aci-ansible/library/* /usr/lib/python2.7/dist-packages/ansible/modules/network/aci-ansible/
In Ansible v2.4, Cisco scripts will be installed along with Ansible, although the above method will apply to new module scripts or to new modules for other systems.It is possible to place other module scripts into the same directories as the playbooks which restricts the use to those local playbooks. Ansible documentation provides more details on this.
Basic Ansible Configuration
We now have a running setup of Ansible with the files needed to support the Cisco ACI APIC. We now configure ansible with some basic information to allow ansible to connect to the Cisco APIC. The ansible getting started documentation can be foundhere.
Ansible Hosts File
The ansible hosts file contains at a minimum a list of hosts / devices that ansible will connect to. It may also contain passwords for logging (SSH) into those hosts. In this basic connectivity case we are going to add the Cisco APIC IP address and the user credentials. The ansible hosts file is located at /etc/ansible/hosts. We will replace all the content of the default file with the following. Replace the APIC IP, username & password with your own system information.
[apic] 192.168.133.200 [apic:vars] ansible_connection = local aci_username = admin aci_password = C1sco12345
This configuration sets up a group called ‘apic’ which we will refer to on our scripts and the section [apic:vars] provides a variables that can be used in scripts that refer to the [apic] hosts. So aci_username is a variable that can be refered to in a playbook (ansible script). Save the hosts file and check ansible can communicate wiith the APIC. We can check ansible can contact this host by using the following command.
# ansible apic -m ping
The ‘apic’ refers to the hosts listed in the [apic] group section of the hosts file. You may get a prompt to accept the certificate provided by the APIC, the APIC uses locally signed certificates when installes so unless publicly signed ones have been installed, you will need to verify the certificate fingerprint and accept if it is valid. This happens once only.
Creating Basic Playbooks
A playbook is (quoting from ansible.com)
At a basic level, playbooks can be used to manage configurations of and deployments to remote machines. At a more advanced level, they can sequence multi-tier rollouts involving rolling updates, and can delegate actions to other hosts, interacting with monitoring servers and load balancers along the way.
We will create two basic playbooks, one to create a bridge domain within an existing tenant on the APIC, the second to grab all of the bridge domains on the APIC and return them to us in JSON format. Keeping playbooks organised is important, there are a few recommended ways discussed at ansible.com generally directory structures are created under /etc/ansible/… for example /etc/ansible/playbooks/
Creating a Bridge Domain
Create a new file in your chosen directory named newDB.yml. The syntax is YAML and is indent sensitive and does not allow tabs, indents must be spaces usually 2 per indent. In this file we will add the following content.
- name: apic bridge domains hosts: apic gather_facts: no vars: aci_login: &aci_login hostname: '{{ inventory_hostname }}' username: '{{ aci_username }}' password: '{{ aci_password }}' validate_certs: no tasks: - name: Creating BD aci_bd: <<: *aci_login tenant: HugeCustomer bd: IntranetWebFront vrf: InternalNetwork delegate_to: localhost
This playbook creates a Bridge Domain called ‘IntranetWebFront’ in a VRF(Context) called ‘InternalNetwork’ in a tenant called ‘HugeCustomer’. The variables for the username and password will look familiar from the /etc/ansible/hosts file. The ‘inventory_hostname’ variable is an internal ansible variable which provides the current host ansible is working with from the ‘apic’ groups in the host file. The ‘apic’ groups is defined at the top of the playbook as ‘hosts: apic’. The ‘aci_bd’ refers to a python script called aci_bd.py which was copied from the Cisco git clone into the ‘/usr/lib/python2.7/dist-packages/ansible/modules/network/aci-ansible’ directory earlier. Take a look at this (and other) python files as they are usually documented with addtional parameters that can be used. This bridge domain script is also documented at the ansible website here as mentioed earlier.
To run this playbook, use the following command.
# ansible-playbook newBD.yml
This should complete with no errors. If errors occur they will likely be due to invalid credentials or syntax in the playbook with idents being the likely cause so review these first.
Get all Bridge Domains in Raw JSON Format
This time we will create a playbook to return all the bridge domains configured on the APIC. Create a new playbook called bridge.yml and add the following YAML.
- name: apic bridge domains hosts: apic gather_facts: no vars: aci_login: &aci_login hostname: '{{ inventory_hostname }}' username: '{{ aci_username }}' password: '{{ aci_password }}' validate_certs: no tasks: - name: Get RAW APIC REST Data aci_rest: <<: *aci_login method: get path: /api/node/class/fvBD.json register: raw delegate_to: localhost - debug: var=raw
Run the following command.
# ansible-playbook getbridge.yml
which will return all the bridge domains configured on the APIC in JSON format. Grep’ing for the DN of each bridge domain provides a brief list of the full DN’s.
# ansible-playbook getbridge.yml | grep dn
For example:
"dn": "uni/tn-common/BD-default", "dn": "uni/tn-common/BD-BD_Common", "dn": "uni/tn-coke/BD-bd_ansible_1a", "dn": "uni/tn-infra/BD-default", "dn": "uni/tn-TSW_Tenant0/BD-tsw0ctx0BD0", "dn": "uni/tn-TSW_Tenant0/BD-tsw0ctx0BD1", "dn": "uni/tn-mgmt/BD-inb", "dn": "uni/tn-HugeCustomer/BD-IntranetWebFront",
Pingback: Ansible Tower REST API Part 1 - Haystack Networks