Pages

4.20.2017

Current Trends in DC Networking - Cumulus Config w/ Ansible Roles

This post will finish up the networking side of this series. Up till now we have learned about VxLAN and deploying it in both Arista and Cumulus spine/leaf fabrics. We also learned how to automate the creation of configuration files and how to deploy them onto Arista gear using Ansible and NAPALM.

Next we need to expand the Ansible playbooks we have created to include the configuration of Cumulus switches. I will also take this opportunity to cover Ansible roles.

I was hoping to cover the Cumulus Ansible module for this post, but at the time of this writing (April 2017) the current version does not support VxLAN configuration. So we will have to just work with static files.

So lets get started!

We are working with the same topology from this series and all prior configurations can be found on my github. We will need them.

I have wiped the configuration off all fabric switches outside of the management interface for basic connectivity. The Ansible setup is on Host2 which was configured in the previous posts here and here

With Cumulus, since we are interacting with Linux, Ansible has the capability to ssh directly into the switch and modify the configuration files and reboot services. This is simpler and more reliable than pushing configurations and hoping they take. Yo actually get interaction with the switch.

Here is the plays and tasks needed to make this happen,

  - name: Configure Cumulus Leafs
    hosts: cumulus-leaf
    become: yes

    tasks:
      - name: copy interfaces
        copy: src=config/{{ansible_hostname}}/interfaces dest=/etc/network/
      - name: copy Quagga daemons
        copy: src=config/{{ansible_hostname}}/daemons dest=/etc/quagga/
      - name: copy Quagga conf
        copy: src=config/{{ansible_hostname}}/Quagga.conf dest=/etc/quagga/
      - name: reload networking
        command: ifreload -a
      - name: reload quagga
        service: name=quagga state=restarted
        tags: push_cumulus

Name and hosts are the same as discussed in previous post.

Notice how "connection: local" is not used. This means Ansible will login to the server with the user provided and execute commands listed in tasks.

Become is how we tell Ansible to change to root after connecting to the host. Pretty much the same as you needing to use "sudo" to elevate privileges.

The task uses copy to add the config files from the local directory to the destination. In this example we would create folders for each switch inside the config directory along with folders for each file we need to modify.

You can find the configuration of each switch and file from the Cumulus directory in the root of this project here. You will then need to break them up into individual configuration files.

After the files are updated both the networking and quagga service are reloaded to apply changes. And that's it.

Roles


As you work more and more with Ansible you will notice you start to reuse tasks over and over. Roles are a way to better organize and share tasks between playbooks. Instead of building out each task of a play within a playbook you move the task to a new yaml file and just call the role with a single line.

roles:
      - eos-leaf-config

In this example eos-leaf-config is a role with all of the tasks moved into a roles directory. Roles have a specific directory structure used by Ansible. I highly recommend spending some time reading through the Ansible documentation on roles to get a better understanding of the directory structure and how roles function.

But we are going to keep it simple and just work with what we need.

First we will build out the roles directory for each of the Cumulus tasks and might as well do the Arista tasks the same way.

Create a directory named roles inside dc-network. Inside roles you will create a sub-directory for each task you are moving to a role.

cd dc-network
mkdir roles
cd roles
mkdir cumulus-leaf-config
mkdir cumulus-spine-config
mkdir eos-leaf-config
mkdir eos-spine-config

Inside each of the roles directories a number of sub-directories needs to exist. A main.yml file also needs to be created within the tasks directory.

cd cumulus-leaf-config
mkdir files
mkdir tasks
cd tasks
touch main.yml

files is used to store all the configuration files I mentioned above. Each device must have a directory matching its name from the hosts file.

tasks/main.yml is where the tasks will be moved.

NOTE: Ansible by default looks for the file main.yml when calling a role. If you name your yaml file something different you will then be required to point the role to the specific yaml file. Annoying I know.

When finished, the roles directory should look like this:





There are a number of other sub-directories you can use such as vars to store variables and defaults for common configuration among tasks within the role.

Next move the tasks into the main.yml file for each role. To do this simply cut the tasks section from the playbook and paste it into main.yml. Remove the tasks: line and adjust your spacing.

Here is cumulus-leaf-config for example.

---

- name: copy interfaces
  copy: src=files/{{ansible_hostname}}/interfaces dest=/etc/network/
- name: copy Quagga daemons
  copy: src=files/{{ansible_hostname}}/daemons dest=/etc/quagga/
- name: copy Quagga conf
  copy: src=files/{{ansible_hostname}}/Quagga.conf dest=/etc/quagga/
- name: reload networking
  command: ifreload -a
- name: reload quagga
  service: name=quagga state=restarted
  tags: push_cumulus

Then inside the playbook you replace the missing tasks section with the roles lines I showed above.

Here is the complete playbook (config-push-roles) once finished.

---

  - name: Build Arista Spine Configuration
    hosts: eos-spine
    connection: local
    gather_facts: no

    roles:
      - eos-spine-config

  - name: Build Arista leaf Configuration
    hosts: eos-leaf
    connection: local
    gather_facts: no

    roles:
      - eos-leaf-config

  - name: Configure Cumulus Spines
    hosts: cumulus-spine
    become: yes

    roles:
      - cumulus-spine-config

  - name: Configure Cumulus Leafs
    hosts: cumulus-leaf
    become: yes

    roles:
      - cumulus-leaf-config

Much cleaner and easier to follow!

Now we can run our playbook using the Cumulus tags and we are set. Notice the tags were moved with the tasks.

ansible-playbook config-push-roles.yml --tags=push_cumulus

As always the full project covering this post and all previous post can be found on my Github.


Conclusion

And that is it for the network part of this series. Moving forward we will be focusing in on the server side of the house. More specifically, containers! 

Even though I have no clue what Im about to get myself into I look forward to the challenge of digging into containers from a network engineers focus.