This repository is deprecated; please follow the main search page or use the ‘Related code repos’ widget on the right side of the current page.

Build Status

published

MPLS L3VPN Manager (vpnm)

This playbook is true infrastructure-as-code. Users declare a list of VRFs
under Ansible's control, then specify which route-targets should exist.
Any unspecified route-targets are automatically and idempotently removed.
Whenever changes occur, routing and ping reachability is validated.

Contact information:
Email: njrusmc@gmail.com
Twitter: @nickrusso42518

Supported platforms

At present, only Cisco IOS platforms are supported. Cisco IOS-XR may
be added in the future.

Testing was conducted on the following platforms and versions:

  • Cisco CSR1000v, version 16.08.01a, running in AWS
  • Cisco CSR1000v, version 16.09.02, running in AWS
  • Cisco CSR1000v, version 16.12.01a, running in AWS
$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.4 (Maipo)

$ uname -a Linux ip-10-125-0-100.ec2.internal 3.10.0-693.el7.x86_64 #1 SMP Thu Jul 6 19:56:57 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux

$ ansible --version ansible 2.8.7 config file = /home/ec2-user/racc/ansible.cfg configured module search path = ['/home/ec2-user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /home/ec2-user/environments/racc287/lib/python3.7/site-packages/ansible executable location = /home/ec2-user/environments/racc287/bin/ansible python version = 3.7.3 (default, Aug 27 2019, 16:56:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]

Variables

For each host (or group of hosts), a vrf list is defined. This list of
dictionaries has the following format:

---
vrfs:
  - name: "VRF1"
    description: "first VRF"
    rd: "65000:1"
    route_import:
      - "65000:1"
    route_export:
      - "65000:2"
    check:
      routes:
        - "10.3.3.0/30"
        - "10.4.4.0/24"
      pings:
        - "10.3.3.1"
        - "10.4.4.44"
  - name: "VRF2"
    description: "second VRF"
    rd: "65000:2"
    route_import:
      - "65000:1"
    route_export:
      - "65000:2"
    check:
      routes:
        - "10.3.3.0/30"
        - "10.4.4.0/24"
      pings:
        - "10.3.3.1"
        - "10.4.4.44"

The individual components in each dictionary are as follows:

  • name: The name of the VRF. Numbers can be used, but should be quoted
    as strings to prevent type mismatches later.
  • description: The description of the VRF.
  • rd: The BGP route distinguisher that makes all routes in this VRF
    unique from the perspective of BGP.
  • route_import: The list of route target (RT) extended communities,
    ideally quoted as strings, which should be imported. Any import RTs not
    in this list that are present on the target host are removed.
  • route_export: The list of route target (RT) extended communities,
    ideally quoted as strings, which should be exported. Any export RTs not
    in this list that are present on the target host are removed.
  • check: Optional nested dictionary that helps with verification. To
    disable checking entirely, remove this dictionary or set it to false.
    • routes: List of prefixes in CIDR notation which should be present
      in the VRF FIB (CEF table) after RT changes are made. This ensures
      that the configuration actually work, and may help surface unrelated
      issues, such as a BGP VPN route advertisement problem.
    • pings: List of single IP addreses which should be pinged from
      within the VRF. Often this will be an IP from inside one of the
      prefixes specified in the routes key, but it does not have to be.
      This helps surface reachability problems or routing loops.

Task summary

The playbook begins by collecting the existing VRF configuration and parsing
it to retrieve the currently configured import and export RTs for all VRFs
on the router, even those not being managed by this playbook. Next, the
parsed RT information from the router is compared against the user-provided
intended RT configuration. For each user-defined VRF, the playbook determines
which RTs must be added or deleted. RTs absent from the intended RT
configuration are automatically and idempotently removed.

The playbook also configures VRFs in BGP and redistributes any connected
routes. If a user-defined VRF does not exist in the current configuration, it
is added, along with all defined RTs. If a VRF exists in the current
configuration but does not exist in the user-defined configuration, it is
ignored. This conservative behavior allows some VRFs to remain outside of
Ansible's control (for example, a management VRF).

If any changes were made, the system waits for a configurable amount of time,
with a default of 60 seconds. This allows the router to import new routes into
the VRF and affix new exported RTs. It also accounts for the time needed for
VRF FIBs to install their routes upon receipt from BGP. The system also
prints the changes made to stdout. When there are no changes, there is no
wait period and no stdout output.

Last, the routing and ping verification runs. These test cases are run
regardless of whether changes occurred or not.

Please see the outputs in the samples/ directory to see the playbook output.

Testing

This playbook comes with three test phases, executed in sequence:

  1. Linting: Perform YAML and Python linting, as well as Python static code
    analysis first. Immediately fail if linting fails to prevent executing
    insecure or syntactically incorrect code. Uses the pylint package.
  2. Formatting: Ensure Python files are formatted in a simple, consistent
    way using the black package.
  3. Unit tests: Perform regression testing on custom Python filters with mock
    inputs. Immediately fail if unit tests fail to prevent playbook issues.
  4. Integration tests: These tests the entire system minus the actual
    login to a network device. All actions requiring network device interaction
    are tagged with do_ssh which is skipped when these tests are run. Mock
    inputs are supplied as variables when the playbook is invoked through the
    test playbook wrapper.

To simplify testing both for CI and for manual executions, a GNU Makefile
with phony targets is used. Use the following shortcuts to test the playbook.
It is recommend to run all tests immediately after cloning to save yourself
the pain of discovering bugs during development.

  1. make lint: Runs the linting process
  2. make unit: Runs the unit tests
  3. make pb: Runs the playbook tests
  4. make test: Runs all tests (linting, unit, and playbook, in that order)

Please see .travis.yml for more details on how the tests are executed.

Use Case

This playbook is a true infrastructure-as-code. Users declare a list of VRFs under Ansible's control and specify which route-targets should exist. Any unspecified route-targets are automatically and idempotently removed. Whenever changes occur, routing and ping reachability is validated.

Objectives

  • Helps to achieve a continuous integration process using Ansible and manage MPLS Layer 3 VPNs.
  • Collects all the required VPN routing and VRF instances.
  • Performs all the testing in series like lint, unit tests, and playbook tests.
  • Ensures that each route and target should exist.

Requirements

  • Ansible 2.6+
  • Virtual Machine or Hyper-V(if you are a Windows user).

Learning Labs

Introduction to Ansible for IOS XE Configuration Management

View code on GitHub

Code Exchange Community

Get help, share code, and collaborate with other developers in the Code Exchange community.View Community
Disclaimer:
Cisco provides Code Exchange for convenience and informational purposes only, with no support of any kind. This page contains information and links from third-party websites that are governed by their own separate terms. Reference to a project or contributor on this page does not imply any affiliation with or endorsement by Cisco.