Ansible with Brocade/DellEMC Connectrix

In the previous post I covered how to install the Cisco Ansible modules and provided some lessons learned. Today we will do the same with Brocade.

This article consists of 4 sections:

  1. Installation of PyFOS library
  2. Installation of Brocade Ansible modules
  3. Sample playbooks

1 – Installation of PyFOS library

In the Cisco blog post we saw how there are multiple methods to connect to the switch, including the REST API. However the only one I could get working was the SSH method. An important thing to understand is that the Brocade Ansible modules talk to the switches via the REST API. However the Brocade team created a Python library called “PyFOS” to simplify access to the REST API. The Ansible modules use this Python library instead of talking to the REST API directly. Therefore, before we install the Ansible modules we need to install the PyFOS library

If you want to learn more about how to use the Brocade FOS REST API you can see our previous article

One thing I have noticed is that the PyFOS installation craves for a modern version of “pip” (which is Python’s package manager) to help it solve all the dependencies. I still have some CentOS 7 VMs around but I have seen the same behavior with CentOS 8. In CentOS 7 the default version of pip is 8.1.2. If you try to install without upgrading it will fail and will prompt you to do the upgrade, so you might as well skip the hassle and upgrade pip in first place

How to upgrade Python pip

The steps to do the do upgrade of pip vary depending on the version of Python you are running.

Python 3

[root@alb-ansible ~]# python3 -m pip install -U pip3

Python 2.7

Here we have to be more careful because pip version 21 doesn’t work with Python 2.7. So we have to specify a recent version but not as recent as 21.0. Luckily we can use this handy pip syntax. Notice how this installed pip 20.3.4 in my system

[root@alb-ansible ~]# pip install --upgrade "pip < 21.0"
[root@alb-ansible ~]# pip -V
pip 20.3.4 from /usr/lib/python2.7/site-packages/pip (python 2.7)

Once you have upgraded pip the installation of the PyFOS library should be straight forward

[root@alb-ansible ~]# pip install pyfos

2 – Installation of Brocade Ansible modules

You can approach this two ways: installing the Ansible modules from the Github repo or installing the collection from Galaxy

Install Ansible modules from Github

The first step is to open a terminal session to your Ansible server and navigate to the directory where you want to install the modules. In my case I want AWX to run the playbooks so I am installing them in in the home folder of the “awx” user inside the “awx_task” container. Now is time to clone the repo from Brocade’s Github site

[root@alb-awx ~]# docker exec -it awx_task /bin/bash
bash-4.2# pwd
bash-4.2# git clone
Cloning into 'ansible'...
remote: Enumerating objects: 2290, done.
remote: Counting objects: 100% (276/276), done.
remote: Compressing objects: 100% (129/129), done.
remote: Total 2290 (delta 200), reused 212 (delta 147), pack-reused 2014
Receiving objects: 100% (2290/2290), 583.25 KiB | 640.00 KiB/s, done.
Resolving deltas: 100% (1813/1813), done.
bash-4.2# ls
ansible  ansible-powerstore  supervisord.log
bash-4.2# cd ansible
bash-4.2# ls
ag_disable.yml         facts_snmp.yml                template_switch_initial_config.yml
ag_enable.yml          facts_sshutil_public_key.yml  utils

Now we need to make Ansible aware of the installation directory. We do this by adding the installation path to the “library” and “module_utils” variables inside the “ansible.cfg” file. Make a note of the “ansible” and the “utils” directories

bash-4.2# pwd
bash-4.2# cd utils
bash-4.2# pwd

Now we need to open the ansible.cfg file to add the paths

vi /etc/ansible/ansible.cfg

These two variables need to look as follows

library        = /home/awx/ansible
module_utils   = /home/awx/ansible/utils

You can specify multiple paths by simply separating them with “:”. You can find more details about the correct syntax of the “ansible.cfg” file in the Ansible configuration settings page. So for example if you had already another path they would look like this

library        = /my/other/path:/home/awx/ansible
module_utils   = /my/other/path/utils:/home/awx/ansible/utils

Install the collection from Galaxy

The other option is to install the collection from Galaxy. Please bear in mind that installing collections with ansible-galaxy is only supported in ansible 2.9+. So if necessary upgrade Ansible as follows:

yum upgrade ansible-2.9.23

Now you can install the Brocade collection

ansible-galaxy collection install brocade.fos

This will install the collection in the “.ansible” folder inside the user’s home folder

bash-4.2# ls /home/awx/.ansible/collections/ansible_collections/brocade/fos/
cheatsheet  FILES.json  MANIFEST.json  meta  playbooks  plugins  roles

3 – Sample playbooks

With most ansible modules you need to define an inventory that contains your target systems. However the modules we just installed use the REST API under the covers, so you can choose to run them in a play where the target is “localhost”, which means you don’t have to manage an inventory. For example the following task will create aliases

- hosts: localhost
  gather_facts: False
  connection: local

  - name: create alias
      credential: "{{ credential }}"
      vfid: -1
      aliases: "{{ aliases }}"
      members_add_only: True

The task requires a “credential” parameter that looks like below. As you can see below, it defines all the details required to connect to it, including the IP address, hence we don’t need to use an inventory if don’t want to. However, you can still use an inventory and specify the target switch in the “hosts” parameter, whatever is more convenient for your use case

  fos_user_name: "admin"
  fos_password: "MyPassword"
  fos_ip_addr: ""
  https: False

With these modules you can manage aliases, zones and configurations. All 3 resources follow the same format which looks like this

  - name: create alias
      credential: "{{ credential }}"
      vfid: -1
        - name: hostalias1
            - 11:22:33:44:55:66:77:88
        - name: arrayalias1
            - 11:11:11:11:11:11:11:11
            - 11:11:11:11:11:11:11:22
      members_add_only: True

You can create multiple resources in the same task, ex: multiple aliases. Each resource has a “name” parameter and a “member” parameter, the only difference is that if you are managing “aliases”, the members will be wwpn’s. If you are managing zones, the members will be aliases or wwpn’s, and so on

The last parameter helps us distiguish between adding and replacing behavior. “members_add_only” specifies that new members will be added, and old members will be kept. This is specially important when managing “cfgs”, because if not specified you might add one zone to the config and accidentally delete all the existing ones

You can get more details and examples from the help of the modules themselves

ansible-doc brocade.fos.brocade_zoning_alias
ansible-doc brocade.fos.brocade_zoning_zone
ansible-doc brocade.fos.brocade_zoning_cfg

From what I have experienced so far, all three modules are idempotent which is nice

Another important feature to bear in mind is that the “brocade_zoning_cfg” module is also used to activate a particular config by using the “active_cfg” parameter. If no cfg is specified, cfgs are only saved (cfg_save)

This is a full example that shows how to:

  • create a new alias for a host
  • create a new zone that contains the host alias and two existing array target aliases
  • add the new zone to the configuration named “cfg” and activate it
- hosts: switch01
  gather_facts: False
  connection: local

    - creds.yml

      - name: albertohost1
          -  11:22:33:44:55:66:77:88
      - name: AlbertoZone1
          - albertohost1
          - P3000T_A_P2
          - P3000T_B_P0
      - name: cfg
          - AlbertoZone1

  - name: create alias
      credential: "{{credential}}"
      vfid: -1
      aliases: "{{ aliases }}"
      members_add_only: True

  - name: Create zones
      credential: "{{credential}}"
      vfid: -1
      zones: "{{zones}}"
      members_add_only: True

  - name: Create cfgs
      credential: "{{credential}}"
      vfid: -1
      cfgs: "{{cfgs}}"
      active_cfg: cfg
      members_add_only: True

In an upcoming blog post and video we will show how to use this dynamically by passing things like host name and wwpn’s at run time

If you want to double check that the changes were effective you can open a terminal session to the switch and issue the “zoneshow” command to show the current config, zoning and alias configurations.

1 reply »

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s