• Synchronising CloudVision Portal Configlets with Ansible

 
 
Print Friendly, PDF & Email

Introduction

As customers deploy Arista devices across multiple locations it becomes important to consider where and how these are managed. In most circumstances more than one instance of CloudVision Portal (CVP) will be required as this allows for multiple fault domains and redundancy within the management plane.

This article will explore the use of the Arista CloudVision Ansible modules to synchronise a designated set of CVP Configlets across multiple CVP instances. This ability to synchronise Configlets provides an efficient way of ensuring organisational policies and security requirements can be quickly deployed across an entire Arista estate in a consistent automated manner. The aim will be to deploy and synchronise a set of configlets that could be updated from any instance of CVP or via an Ansible PlayBook. This provides the most flexible method of managing the configlets without imposing any requirements to exclusively use either CVP or Ansible for updating them.

The Ansible CloudVision modules described in this article can be found on the Arista GitHub site aristanetworks/ansible_cvp or in Ansible Galaxy as arista.cvp. The modules were tested against CloudVision Portal 2019.1.1 deployed as two separate instances each managing a separate set of test switches. In this article we will create a small lab to demonstrate this functionality and provide directions for using the Ansible modules and playbooks created in it.

An example of the Lab Setup can be found here – Ansible-Sync-Configlets 

Lab Setup

In this lab Ansible 2.9.2 was installed in to a virtual python environment running python 2.7.9 although the modules have also been tested with python 3.x. To create the virtual environment and install Ansible and any required modules the following commands were used. The commands were issued from the directory in which the lab was to be executed. In this case it was in a directory called “Ansible_Sand_Pit”:

> pwd
~/Ansible_Sand_Pit
> virtualenv --no-site-packages -p $(which python2.7) .venv
> source .venv/bin/activate
> pip install --user ansible
> pip install netaddr requests treelib
> ansible-galaxy collection install arista-cvp-1.0.0.tar.gz -p collections

In addition to the above packages SSHPASS will also be required, this can be installed using one of the following methods depending on the Operating System of the Ansible host:

UBUNTU:
> apt-get install sshpass

MACOS:
> brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb

Once the lab has been installed the Ansible configuration files can then be updated:

> pwd
~/Ansible_Sand_Pit
> vi ./ansible.ini

inventory.ini
[cvp_servers]
cvp_server_1    ansible_httpapi_host={{IP ADDRESS CVP SERVER 1}}
cvp_server_2    ansible_httpapi_host={{IP ADDRESS CVP SERVER 2}}

[cvp_servers:vars]
ansible_connection = 'httpapi'
ansible_httpapi_use_ssl = True
ansible_httpapi_validate_certs = False
ansible_user = '{{CVP USER NAME}}'
ansible_password = '{{CVP PASSWORD}}'
ansible_network_os = 'eos'
ansible_httpapi_port = 443
# Configuration to get Virtual Env information
ansible_python_interpreter = $(which python)

Having configured Ansible to enable access to the CVP servers two roles are required for the PlayBooks, these roles will be created in a subdirectory called roles:

> pwd
~/Ansible_Sand_Pit 

> mkdir ./roles
> ansible-galaxy init ./roles/cvp.sync
- Role ./roles/cvp.sync was created successfully
> ansible-galaxy init ./roles/cvp.refresh
- Role ./roles/cvp.refresh was created successfully

The role directories contain a template structure for the two Ansible roles required, these will be described in more detail later.

In addition to the Ansible roles a set of directories and data stores are required to store the variables created and used by the PlayBook. These data stores are in the form of YAML files and located in a directory structure under generated_vars:

> pwd
~/Ansible_Sand_Pit 

> mkdir ./generated_vars
> mkdir ./generated_vars/common_configlets
> mkdir ./generated_vars/containers
> mkdir ./generated_vars/cvp_servers

The common_configlets directory contains details of the configlets that are to be synchronised across the CVP instances.
The containers directory contains details of the provisioning hierarchies for each CVP server in order to be able to deploy the synchronised (shared) configlets on each CVP server.
The cvp_servers directory contains details of which configlets are to be deployed to the CVP servers. This directory can be used by other PlayBooks to deploy configlets and provision devices.
The group_vars directory is used to share data between Ansible roles.
The YAML files in the directories and their usage will be described in more detail later.

Ansible Roles

This lab will use two Ansible Roles:

cvp.sync

cvp.sync connects to each of the CVP instances, locates the configlets with “shared_” in their name and updates the shared Configlet data (config, last time changed, associated containers, associated devices) for each CVP instance. This data is stored in the generated_vars directory as a YAML file with the CVP instance name. An example is shown below:

> more ./generated_vars/common_configlets/cvp_server_1.yml
'shared_LoginBanner':
   config: "! banner login ! ******************************************************************************** LEGAL NOTICE\nYOU MAY COMMIT A CRIMINAL OFFENCE IF YOU ACT OUTSIDE YOUR AUTHORITY IN RELATION TO THIS EQUIPMENT. THE PENALTY WILL INCLUDE DISCIPLINARY ACTION, DISMISSAL, FINES, OR PROSECUTION. IF YOU ARE ACTING OUTSIDE YOUR AUTHORITY, DO NOT PROCEED ANY FURTHER. IF YOU ARE ACTING WITHIN YOUR AUTHORITY, PLEASE NOTE THAT YOUR USE OF THIS SYSTEM MAY BE MONITORED FOR OPERATIONAL OR BUSINESS REASONS.\n******************************************************************************** ! EOF ! banner motd ! ********************************************************************************\nYOU ARE CONNECTED TO PRIVATE DEVICE PLEASE ENSURE YOU ARE ACTING WITHIN YOUR AUTHORITY ACCESS TO THE CLI SHOULD BE USED FOR TROUBLESHOOTING AND SERIOUS INCIDENTS ONLY CONFIGURATION MUST BE APPLIED USING AUTHORISED TOOLS ONLY.\nTHIS DEVICE IS CONFIGURED AND MONITORED BY CLOUDVISION PORTAL. CHANGES MADE ON THE CLI WILL BE OVERWRITTEN IF NOT APPLIED TO CVP\n******************************************************************************** ! EOF !"
   last_changed: 1578924679973
   devices: []
   containers: ['CTL1_TempTest']

This file contains a YAML list of configlets, each entry has the configuration associated with the configlet, the timestamp of when the configlet was last updated on the CVP server and lists of associated devices and containers. The devices and containers are not strictly needed for this example but they might be useful for future expansion of the use case.

The cvp.sync role contains a task file located in the “tasks” directory. This Ansible role will be imported into the main playbook in the Ansible_Sand_Pit directory. The role has been broken down into 8 plays as follows:

> more ./roles/cvp.sync/tasks/main.yml---
# tasks file for cvp.sync

- name: "collect CVP Facts"
  tags:
    - sync
    - check
  arista.cvp.cv_facts:
  register: CVP_FACTS

- name: "Extract shared Configlets"
  tags:
     - sync
     - check
  template:
    src: "template.shared_configlets.j2"
    dest: "./generated_vars/common_configlets/{{inventory_hostname}}.yml"
  delegate_to: localhost
  run_once: False

- name: "Check for shared_master"
  tags:
     - sync
     - check
  stat: path=./generated_vars/common_configlets/master.yml
  register: status_shared_master
  delegate_to: localhost

- name: "Create common_configlets master.yml if not exist"
  tags:
    - sync
    - check
  file:
     path: ./generated_vars/common_configlets/master.yml
     state: touch
     mode: u=rw,g=r,o=r
  when: status_shared_master.stat.exists == false
  delegate_to: localhost

- name: "Add YAML designators to shared_master.yml"
  tags:
    - sync
    - check
  copy: content="---" dest="./generated_vars/common_configlets/master.yml"
  when: status_shared_master.stat.exists == false
  delegate_to: localhost

- name: "Load Common CVP Servers Configlet Data"
  tags:
    - sync
    - check
  include_vars:
     file: './generated_vars/common_configlets/master.yml'
     name: 'shared_master'
  delegate_to: localhost

- name: "Load CVP Instance Shared Configlet Data"
  tags:
    - sync
    - check
  include_vars:
     file: "./generated_vars/common_configlets/{{inventory_hostname}}.yml"
     name: 'shared_server'
  delegate_to: localhost

- name: "Compare shared Configlets"
  tags:
    - sync
    - check
  template:
    src: "template.compare_configlets.j2"
    dest: "./generated_vars/common_configlets/master.yml"
  delegate_to: localhost

collect CVP Facts – uses the cv_facts Ansible module to interrogate the CVP instances and gather information about devices, configlets, containers, image bundles, and tasks. This information is stored in the ansible_facts variable for each CVP server session and in turn is used by the subsequent sections of the role.

Extract shared Configlets – uses ansible_facts and the template “shared_configlets.j2” in the “cvp.sync/templates/” directory to extract a list of Configlets that have “shared_” in their names. These will be the Configlets to be shared and synchronised across CVP instances. The template is written in Jinja2 as follows:

> more ./roles/cvp.sync/templates/template.shared.configlets.j2
---
{% for configlet in ansible_facts['configlets'] %}
{% if 'shared_' in configlet['name'] %}
'{{configlet["name"]}}':
   config: "{{ configlet['config'] | replace('\n', '\\n')}}"
   last_changed: {{configlet['dateTimeInLongFormat']}}
   devices: {{configlet['devices'] | replace("u'", "'")}}
   containers: {{configlet['containers'] | replace("u'", "'")}}
{% endif %}
{% endfor %}

This list of Configlets is stored in the common_configlets directory in a YAML file named after the CVP instance. An example of which has been shown previously (cvp_server_1.yml).

Load Common CVP Servers Configlet Data and Load CVP Instance Shared Configlet Data – create Ansible variables that are used by “Compare shared Configlets” to create a list of the most recent versions of the shared Configlets. This list is then stored in “./generated_vars/common_configlets/master.yml”

Check for shared_master, create common_configlets master.yml if not exist, and Add YAML designators to shared_master.yml check for the existence of the list created in the previous plays and create an empty YAML file if it does not. This ensures that the playbook will execute correctly if the master file has not been created.

Compare shared Configlets takes the variables created above and parses them through the “compare_configlets” template to create or update the master.yml file with the latest shared Configlet version. The latest Configlet is determined by comparing the timestamps for the same Configlet in each CVP instance and the master.yml file. The Configlet with the latest timestamp becomes the master configlet. As the Configlets use a Linux type timestamp the Configlet with the largest value will be assumed to be the latest one.

The comparison template is shown below:

> more ./roles/cvp.sync/templates/template.compare.configlets.j2
---
{% for configlet in shared_server %}
{% if shared_master[configlet] is defined %}
{% if shared_master[configlet]['last_changed'] < shared_server[configlet]['last_changed'] %}
{{configlet}}:
   source: "updated_by_{{inventory_hostname}}"
   config: "{{ shared_server[configlet]['config'] | replace('\n', '\\n')}}"
   last_changed: {{shared_server[configlet]['last_changed']}}
   devices: {{shared_server[configlet]['devices'] | replace("u'", "'")}}
   containers: {{shared_server[configlet]['containers'] | replace("u'", "'")}}
{% else %}
{{configlet}}:
   source: "updated_by_common_master"
   config: "{{ shared_master[configlet]['config'] | replace('\n', '\\n')}}"
   last_changed: {{shared_master[configlet]['last_changed']}}
   devices: {{shared_master[configlet]['devices'] | replace("u'", "'")}}
   containers: {{shared_master[configlet]['containers'] | replace("u'", "'")}}
{% endif %}
{% else %}
{{configlet}}:
   source: "add_by_{{inventory_hostname}}"
   config: "{{ shared_server[configlet]['config'] | replace('\n', '\\n')}}"
   last_changed: {{shared_server[configlet]['last_changed']}}
   devices: {{shared_server[configlet]['devices'] | replace("u'", "'")}}
   containers: {{shared_server[configlet]['containers'] | replace("u'", "'")}}
{% endif %}
{% endfor %}
{% for configlet in shared_master %}
{% if shared_server[configlet] is not defined %}
{{configlet}}:
   source: "added_by_common_master"
   config: "{{ shared_master[configlet]['config'] | replace('\n', '\\n')}}"
   last_changed: {{shared_master[configlet]['last_changed']}}
   devices: {{shared_master[configlet]['devices'] | replace("u'", "'")}}
   containers: {{shared_master[configlet]['containers'] | replace("u'", "'")}}
{% endif %}
{% endfor %}

This template checks to see if a CVP server Configlet was defined in master.yml referred to as “shared_master”. If it was the time stamps are then compared between the “shared_master” and “shared_server” Configlets. The latest version of the Configlet is then stored in master.yml. If the Configlet is not defined then the “shared_server” Configlet is used. Any Configlets that are not defined on the CVP server, “shared_server”, but are defined in “shared_master” are also written back to master.yml. The master.yml file is always updated to have the latest complete set of shared Configlets. Missing or older Configlets are always updated on the CVP servers.

cvp.refresh

cvp.refresh connects to each of the CVP instances and updates the shared configlets on each one using the information provided by cvp.sync:

> more ./roles/cvp.refresh/tasks/main.yml---
# tasks file for cvp.refresh

- name: "collect CVP Facts"
  tags:
    - sync
  arista.cvp.cv_facts:
  register: CVP_FACTS

- name: "Load Shared Configlet Data"
  tags:
    - sync
  include_vars:
     file: './generated_vars/common_configlets/master.yml'
     name: 'shared_configlets'
  delegate_to: localhost

- name: 'Refresh Shared configlet files for CVP'
  tags:
    - sync
  template:
    src: "./roles/cvp.provision/templates/template.shared_configlets.j2"
    dest: './generated_vars/cvp_servers/{{inventory_hostname}}_shared.yml'
  delegate_to: localhost
  run_once: False

- name: "Load refreshed Shared Configlet information for CVP"
  tags:
    - sync
  include_vars: './generated_vars/cvp_servers/{{inventory_hostname}}_shared.yml'
  delegate_to: localhost

- name: 'Update Shared configlets on CVP Servers.'
  tags:
    - sync
  arista.cvp.cv_configlet:
    cvp_facts: "{{CVP_FACTS.ansible_facts}}"
    configlets: "{{CVP_CONFIGLET}}"
    configlet_filter: ["shared"]

collect CVP Facts – uses the cv_facts Ansible module to interrogate the CVP instances and gather information about devices, configlets, containers, image bundles, and tasks.

Load Shared Configlet Data – creates a Playbook variable called “shared_configlets” from the master.yml file that will be used in later templates.

Refresh Shared configlet files for CVP – updates the shared Configlet information for the CVP servers in case it has changed during the PlayBook execution.

Load refreshed Shared Configlet information for CVP – creates a PlayBook variable to be used in the final template. The variable uses the data from the YAML file created in the step previously.

Update Shared configlets on CVP Servers – attaches to the CVP servers and updates the shared Configlets on each one using the cv_configlet Ansible module.

Ansible PlayBook

This lab combines the two Ansible Roles in one PlayBook:

playbook.demo

playbook.demo is the main PlayBook, it consists of two plays that import the previously described roles:

> more ./playbook.demo.yml
---
- name: Check Shared Configlets across CVP clusters
  hosts: cvp_servers
  serial: true
  gather_facts: no
  tasks:
    - name: Sync Shared Configlets
      tags:
        - check
        - sync
      import_role:
         name: cvp.sync

- name: Update Shared Configlets across CVP clusters
  hosts: cvp_servers
  gather_facts: no
  tasks:
    - name: Sync Shared Configlets
      tags:
        - sync
      import_role:
         name: cvp.refresh

Check Shared Configlets across CVP clusters imports the the cvp.sync role and runs it against each CVP server in turn. Unlike other plays this play serialises the execution of the role for each CVP server. This means that cvp_server_1 has to complete before the playbook will move onto cvp_server_2. This avoids a race condition where both CVP server plays try to update the master.yml file at the same time. If this happens they will not compare Configlet time stamps correctly. This race condition can cause the wrong Configlets (not the latest) to be stored in the file.

Update Shared Configlets across CVP clusters imports the cvp.refresh role and uses it to push configlet updates to each of the CVP servers. This play runs in parallel allowing both CVP servers to be updated simultaneously.

Lab Execution

The playbook can now be executed!! Shown below are the outputs for the two runs through the PlayBook.
The first run uses the “check” flag to gather the shared Configlet information and update the master.yml file:

(virtEnv) :> ansible-playbook playbook.demo.yml --tags check

PLAY [Check Shared Configlets across CVP clusters] 
********************************************************************************

TASK [cvp.sync : collect CVP Facts] 
********************************************************************************
Friday 17 January 2020  17:28:38 +0000 (0:00:00.159)       0:00:00.159 ******** 
ok: [cvp_server_1]

TASK [cvp.sync : Extract shared Configlets] 
********************************************************************************
Friday 17 January 2020  17:29:23 +0000 (0:00:45.792)       0:00:45.952 ******** 
ok: [cvp_server_1 -> localhost]

TASK [cvp.sync : Check for shared_master] 
********************************************************************************
Friday 17 January 2020  17:29:24 +0000 (0:00:00.861)       0:00:46.813 ******** 
ok: [cvp_server_1 -> localhost]

TASK [cvp.sync : Create common_configlets master.yml if not exist] 
********************************************************************************
Friday 17 January 2020  17:29:25 +0000 (0:00:00.297)       0:00:47.110 ******** 
skipping: [cvp_server_1]

TASK [cvp.sync : Add YAML designators to shared_master.yml] 
********************************************************************************
Friday 17 January 2020  17:29:25 +0000 (0:00:00.109)       0:00:47.220 ******** 
skipping: [cvp_server_1]

TASK [cvp.sync : Load Common CVP Servers Configlet Data] 
********************************************************************************
Friday 17 January 2020  17:29:25 +0000 (0:00:00.115)       0:00:47.335 ******** 
ok: [cvp_server_1 -> localhost]

TASK [cvp.sync : Load CVP Instance Shared Configlet Data] 
********************************************************************************
Friday 17 January 2020  17:29:25 +0000 (0:00:00.085)       0:00:47.420 ******** 
ok: [cvp_server_1 -> localhost]

TASK [cvp.sync : Compare shared Configlets] 
********************************************************************************
Friday 17 January 2020  17:29:25 +0000 (0:00:00.121)       0:00:47.542 ******** 
ok: [cvp_server_1 -> localhost]

PLAY [Check Shared Configlets across CVP clusters] 
********************************************************************************

TASK [cvp.sync : collect CVP Facts] 
********************************************************************************
Friday 17 January 2020  17:29:25 +0000 (0:00:00.474)       0:00:48.017 ******** 
ok: [cvp_server_2]

TASK [cvp.sync : Extract shared Configlets] 
********************************************************************************
Friday 17 January 2020  17:30:08 +0000 (0:00:42.630)       0:01:30.647 ******** 
ok: [cvp_server_2 -> localhost]

TASK [cvp.sync : Check for shared_master] 
********************************************************************************
Friday 17 January 2020  17:30:09 +0000 (0:00:00.561)       0:01:31.209 ******** 
ok: [cvp_server_2 -> localhost]

TASK [cvp.sync : Create common_configlets master.yml if not exist] 
********************************************************************************
Friday 17 January 2020  17:30:09 +0000 (0:00:00.321)       0:01:31.531 ******** 
skipping: [cvp_server_2]

TASK [cvp.sync : Add YAML designators to shared_master.yml] 
********************************************************************************
Friday 17 January 2020  17:30:09 +0000 (0:00:00.129)       0:01:31.660 ******** 
skipping: [cvp_server_2]

TASK [cvp.sync : Load Common CVP Servers Configlet Data] 
********************************************************************************
Friday 17 January 2020  17:30:09 +0000 (0:00:00.127)       0:01:31.788 ******** 
ok: [cvp_server_2 -> localhost]

TASK [cvp.sync : Load CVP Instance Shared Configlet Data] 
********************************************************************************
Friday 17 January 2020  17:30:09 +0000 (0:00:00.090)       0:01:31.879 ******** 
ok: [cvp_server_2 -> localhost]

TASK [cvp.sync : Compare shared Configlets] 
********************************************************************************
Friday 17 January 2020  17:30:09 +0000 (0:00:00.132)       0:01:32.011 ******** 
ok: [cvp_server_2 -> localhost]

PLAY [Update Shared Configlets across CVP clusters] 
********************************************************************************
PLAY RECAP 
*********************************************************************
cvp_server_1 : ok=6    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   
cvp_server_2 : ok=6    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   

Friday 17 January 2020  17:30:10 +0000 (0:00:00.516)       0:01:32.527 ******** 
=============================================================================== 
cvp.sync : collect CVP Facts ------------------------------------------ 42.63s
cvp.sync : Extract shared Configlets ----------------------------------- 0.56s
cvp.sync : Compare shared Configlets ----------------------------------- 0.52s
cvp.sync : Check for shared_master ------------------------------------- 0.32s
cvp.sync : Load CVP Instance Shared Configlet Data --------------------- 0.13s
cvp.sync : Create common_configlets master.yml if not exist ------------ 0.13s
cvp.sync : Add YAML designators to shared_master.yml ------------------- 0.13s
cvp.sync : Load Common CVP Servers Configlet Data ---------------------- 0.09s
(virtEnv) :>

The second execution uses the “sync” flag to gather the shared Configlet information and update the master.yml file then synchronise the Configlets across the CVP instances:

(virtEnv) :> ansible-playbook playbook.demo.yml --tags sync

PLAY [Check Shared Configlets across CVP clusters] 
*******************************************************************************

TASK [cvp.sync : collect CVP Facts] 
*******************************************************************************
Friday 17 January 2020  18:12:33 +0000 (0:00:00.138)       0:00:00.138 ******** 
ok: [cvp_server_1]

TASK [cvp.sync : Extract shared Configlets] 
*******************************************************************************
Friday 17 January 2020  18:13:16 +0000 (0:00:43.740)       0:00:43.879 ******** 
ok: [cvp_server_1 -> localhost]

TASK [cvp.sync : Check for shared_master] 
*******************************************************************************
Friday 17 January 2020  18:13:17 +0000 (0:00:00.875)       0:00:44.754 ******** 
ok: [cvp_server_1 -> localhost]

TASK [cvp.sync : Create common_configlets master.yml if not exist] 
*******************************************************************************
Friday 17 January 2020  18:13:18 +0000 (0:00:00.300)       0:00:45.054 ******** 
skipping: [cvp_server_1]

TASK [cvp.sync : Add YAML designators to shared_master.yml] 
*******************************************************************************
Friday 17 January 2020  18:13:18 +0000 (0:00:00.116)       0:00:45.171 ******** 
skipping: [cvp_server_1]

TASK [cvp.sync : Load Common CVP Servers Configlet Data] 
*******************************************************************************
Friday 17 January 2020  18:13:18 +0000 (0:00:00.123)       0:00:45.294 ******** 
ok: [cvp_server_1 -> localhost]

TASK [cvp.sync : Load CVP Instance Shared Configlet Data] 
*******************************************************************************
Friday 17 January 2020  18:13:18 +0000 (0:00:00.086)       0:00:45.381 ******** 
ok: [cvp_server_1 -> localhost]

TASK [cvp.sync : Compare shared Configlets] 
*******************************************************************************
Friday 17 January 2020  18:13:18 +0000 (0:00:00.120)       0:00:45.501 ******** 
ok: [cvp_server_1 -> localhost]

PLAY [Check Shared Configlets across CVP clusters] 
*******************************************************************************

TASK [cvp.sync : collect CVP Facts] 
*******************************************************************************
Friday 17 January 2020  18:13:18 +0000 (0:00:00.481)       0:00:45.983 ******** 
ok: [cvp_server_2]

TASK [cvp.sync : Extract shared Configlets] 
*******************************************************************************
Friday 17 January 2020  18:14:00 +0000 (0:00:41.423)       0:01:27.406 ******** 
ok: [cvp_server_2 -> localhost]

TASK [cvp.sync : Check for shared_master] 
*******************************************************************************
Friday 17 January 2020  18:14:00 +0000 (0:00:00.536)       0:01:27.943 ******** 
ok: [cvp_server_2 -> localhost]

TASK [cvp.sync : Create common_configlets master.yml if not exist] 
*******************************************************************************
Friday 17 January 2020  18:14:01 +0000 (0:00:00.305)       0:01:28.248 ******** 
skipping: [cvp_server_2]

TASK [cvp.sync : Add YAML designators to shared_master.yml] 
*******************************************************************************
Friday 17 January 2020  18:14:01 +0000 (0:00:00.117)       0:01:28.366 ******** 
skipping: [cvp_server_2]

TASK [cvp.sync : Load Common CVP Servers Configlet Data] 
*******************************************************************************
Friday 17 January 2020  18:14:01 +0000 (0:00:00.118)       0:01:28.484 ******** 
ok: [cvp_server_2 -> localhost]

TASK [cvp.sync : Load CVP Instance Shared Configlet Data] 
*******************************************************************************
Friday 17 January 2020  18:14:01 +0000 (0:00:00.088)       0:01:28.573 ******** 
ok: [cvp_server_2 -> localhost]

TASK [cvp.sync : Compare shared Configlets] 
*******************************************************************************
Friday 17 January 2020  18:14:01 +0000 (0:00:00.125)       0:01:28.698 ******** 
ok: [cvp_server_2 -> localhost]

PLAY [Update Shared Configlets across CVP clusters] 
*******************************************************************************

TASK [cvp.refresh : collect CVP Facts] 
*******************************************************************************
Friday 17 January 2020  18:14:02 +0000 (0:00:00.534)       0:01:29.233 ******** 
ok: [cvp_server_2]
ok: [cvp_server_1]

TASK [cvp.refresh : Refresh Shared Configlet Data] 
*******************************************************************************
Friday 17 January 2020  18:14:42 +0000 (0:00:40.371)       0:02:09.605 ******** 
ok: [cvp_server_1 -> localhost]
ok: [cvp_server_2 -> localhost]

TASK [cvp.refresh : Refresh Shared configlet files for CVP] 
*******************************************************************************
Friday 17 January 2020  18:14:42 +0000 (0:00:00.150)       0:02:09.755 ******** 
ok: [cvp_server_1 -> localhost]
ok: [cvp_server_2 -> localhost]

TASK [cvp.refresh : Load refreshed CVP shared Configlet information] 
*******************************************************************************
Friday 17 January 2020  18:14:43 +0000 (0:00:00.656)       0:02:10.412 ******** 
ok: [cvp_server_1 -> localhost]
ok: [cvp_server_2 -> localhost]

TASK [cvp.refresh : Update Shared configlets on CVP Servers.] 
*******************************************************************************
Friday 17 January 2020  18:14:43 +0000 (0:00:00.196)       0:02:10.609 ******** 
ok: [cvp_server_2]
ok: [cvp_server_1]

PLAY RECAP 
********************************************************************
cvp_server_1 : ok=11   changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   
cvp_server_2 : ok=11   changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   

Friday 17 January 2020  18:14:46 +0000 (0:00:03.379)       0:02:13.988 ******** 
=============================================================================== 
cvp.sync : collect CVP Facts ------------------------------------------ 41.42s
cvp.refresh : collect CVP Facts --------------------------------------- 40.37s
cvp.refresh : Update Shared configlets on CVP Servers. ----------------- 3.38s
cvp.refresh : Refresh Shared configlet files for CVP ------------------- 0.66s
cvp.sync : Extract shared Configlets ----------------------------------- 0.54s
cvp.sync : Compare shared Configlets ----------------------------------- 0.53s
cvp.sync : Check for shared_master ------------------------------------- 0.31s
cvp.refresh : Load refreshed CVP shared Configlet information ---------- 0.20s
cvp.refresh : Refresh Shared Configlet Data ---------------------------- 0.15s
cvp.sync : Load CVP Instance Shared Configlet Data --------------------- 0.13s
cvp.sync : Add YAML designators to shared_master.yml ------------------- 0.12s
cvp.sync : Create common_configlets master.yml if not exist ------------ 0.12s
cvp.sync : Load Common CVP Servers Configlet Data ---------------------- 0.09s
(virtEnv) :>

After the second run the Configlets can be changed on either CVP instance or by manipulating the master.yml file and the playbook executed again using the “sync” flag. Each time the master.yml file is updated the latest version of the shared Configlets is pushed to each of the CVP instances.

Summary

The Arista CloudVision Ansible modules can be used to synchronise a designated set of CVP Configlets across multiple CloudVision instances. The Configlets can be updated on any of the CVP instances or using additional Ansible playbooks. This ability to synchronise Configlets provides an efficient way to ensure that company policies and security requirements can be quickly deployed across an entire Arista estate in a consistent automated manner.

Follow

Get every new post on this blog delivered to your Inbox.

Join other followers: