Site icon Karneliuk

Automation 12. Automated EVPN Customer Deployment with Ansible, NETCONF, and NetBox. 6WIND version.

Hello my friend,

We’ve been preparing this blogpost for quite a while, but for various reasons it was put on the back burner. Now we finally are bringing this back to light. We’ll go over a practical use case of automation of 6WIND configuration with Ansible and NetBox relying NETCONF.


1
2
3
4
5
No part of this blogpost could be reproduced, stored in a
retrieval system, or transmitted in any form or by any
means, electronic, mechanical or photocopying, recording,
or otherwise, for commercial purposes without the
prior permission of the author.

Do I Need to Automate Everything?

The answer is, as usual: it depends. With our passion to automation, we would say: yes, definitely you should automate everything. But this is possible, only if you have unlimited resources (time, money, people). In reality, all the resources are limited and, moreover, may be even scarce. In such a case you would need to choose, where would you obtain the biggest leverage from automation. For example, some tasks are more frequent or time consuming than others. Clearly they are to be automated.

How to find them? Join our automation training and you will find that out!

We offer the following training programs:

During these trainings you will learn the following topics:

Moreover, we put all mentions technologies in the context of real use cases, which our team has solved and are solving in various projects in the service providers, enterprise and data centre networks and systems across the Europe and USA. That gives you opportunity to ask questions to understand the solutions in-depts and have discussions about your own projects. And on top of that, each technology is provided with online demos and labs to master your skills thoroughly. Such a mixture creates a unique learning environment, which all students value so much. Join us and unleash your potential.

Start your automation training today.

Brief Description

Following approach mentioned above, what may be a task or tasks, which are used the most for authentication in any Service Provider network?

By service provider we mean a company, which provides any sort of connectivity and/or IT infrastructure services to other companies (e.g., communication/Internet service providers (CSP/ISP), hosting providers, cloud providers, etc).

If a Service Provider is successful, the most widely used operation is an onboarding of a new users or a modification of the configuration for the existing one. Time to time, it would also need to remove the configuration, when customers are leaving. These three operations would be by far most widely used than any other operations, which change configuration at the network devices. As such, we would focus on them. To be precise, we will focus on the customer on-boarding.

What does customer onboarding mean? It means that the service for a new customer shall be provisioned in a network. However, before we can provision the service, we need to know how it shall look like. Therefore, the customer’s on-boarding will consist from a few steps:

  1. Documentation of the customer configuration in some database.
  2. Validation of the documented information.
  3. Preparing configuration for a deployment
  4. Rollout of the configuration in a live network.
  5. Post-rollout validation, if the desired state is achieved.

At each of this step there are various tools and techniques existing.

Enrol to our zero-to-hero network automation training to get practical knowledge how to efficiently perform each of these tasks.

For the purpose of this blogpost, we’ll focus on the 1st, 4th, and bit of the 5th steps.

However, the story is incomplete until we put it into the proper context. Our context is a service provider, which operates 6WIND-based network, both inside data centres and for DCI purpose. The service provider implements multi-tenant architecture with EVPN/VXLAN providing data and control planes and with tenant’s separation implemented via placement customers in different VRFs and terminating all their servers in those VRFs. That’s fairly standard data centre deployment these days both in the could providers and in enterprise worlds. Let’s see how that can be automated.

Lab Setup

The original scenario is quite a big one and is worth of having a standalone blogpost. For the purpose of the lab, we will use the one we created in one of the previous 6WIND blogposts:

Here is what we run:

Other network devices are out of scope for this blogpost.

But in scope for our network automation training, which you can start today.

We also have a management host running Debian 11.1 with:

On top of that, as a source of truth for the network we are using:

Let’s get started.

Scenario Description

Based on the high-level description above, here is the list of questions we are to cover in the blogpost

Enrol to our Zero-to-Hero Network Automation Training to master practical skills in NETCONF/YANG.

Step #1. Approach for a Traffic Separation in a Multi-Tenant Service Provider

First thing first, how is the traffic of one traffic is separated from another customer’s traffic? As you may know, one the most popular and widely used methods of serration is a VLAN tagging. It works as this:

Strictly speaking, it is possible to stitch two separate VLANs together via VLAN-tag rewrite, but we will put this outside of our discussion.

Such separation works well, if all you need is to interconnect multiple customer’s endpoint and provide them L2 connectivity in a small domain. What if the customer requires multiple different subnets to be interconnected?

Here the routing comes to the stage. But it may be, that two different customers have the same IP address schema and, therefore, overlapping IP address. The solution to that is VRF, where we create a virtual router for each customer. There are two 2 key parameters associated with each VRF:

The next piece is to span multiple distant customer’s locations into a single instance, so that a customer can have L2 or L3 connectivity service between sites, depending on their needs. There are multiple ways, how this can be achieved these days:

There are some other types of data planes possible, such as GENEVE, but we will put it aside, at least for the time being.

EVPN/VXLAN is a clear leader in a data centre segment for a simple reason: it is much easier (hence, cheaper) to build router or switch, which can produce a high-performant VXLAN encapsulation/decapsulation than a device doing similar operation in regards of MPLS. That’s why, started in data centres, EVPN/VXLAN spread its influence into Campus networking (same EVPN/VXLAN fabric as in data centres), SD-WAN (EVPN/VXLAN over IPSec) and even service providers, where capacity is more important than MPLS Traffic Engineering capabilities.

As such, the last piece for the information we need to document and then to configure for the customer’s onboarding is the VNI ID, which is a unique identifier used to separate customers traffic in the routed domain.

Bringing all the pieces together, you could imagine the following picture:

The described flow was very much simplified, and there are a lot of details about EVPN/VXLAN design and operation. Reach us out to learn more.

Step #2. Documentation of a Customer Service in NetBox

Summing the previous step, we need to document the following parameters for each customer:

ParameterDescription
tenant idCustomer’s unique ID in the Service Provider network
interface idCustomer’s facing interface per each provider’s network device
vlan idIf customer’s connectivity if done in SVI/BVI, the associated VLAN ID
vrf namethe name of the VRF associated with the customer
rt Route Targets associated with customer routes
rdRoute Distinguisher associated with customer routes
vni idthe ID of the customer’s VXLAN

Now, let’s start documenting these details.

Step #2.1. Create a Tenant in NetBox

In NetBox, navigate choose “Tenant” tab from “Organisations” category. Press “+” to add customer. In the opened window, provide a customer name.

Adding Tenant in NetBox

Step #2.2. Create a Route Target in NetBox

In NetBox, naviaged to “Route Targets” tab in “IPAM” category. Press “+” to add a new Route Target. In the opened window, provide its value and map the created tenant.

Adding Route Target in NetBox

Step #2.3. Create a VRF in NetBox

In NetBox, naviaged to “VRF” tab in “IPAM” category. Press “+” to add a new VRF. In the opened window, provide its name, create a Route Distinguisher (RD), associate the created Route Targets and map it to the tenant.

Creating VRF in NetBox

Step #2.4. Create a Tenant’s VLAN in NetBox

In NetBox, naviaged to “VLAN” tab in “IPAM” category. Press “+” to add a new VLAN. In the opened window, provide its ID, name, create a Route Distinguisher (RD), and map it to the tenant.

Creating VLAN in NetBox

Step #2.5. Create a Tenant’s Prefix in NetBox

In NetBox, naviaged to “Prefix” tab in “IPAM” category. Press “+” to add a new Prefix. In the opened window, provide the IP prefix and prefix length, map it to VRF, associate with the created IP Prefix and the tenant.

Creating IP Prefix in NetBox – 1
Creating IP Prefix in NetBox – 2

Step #2.6 Add to the PE Device Tenant’s Interfaces

The last in the device’s modelling is to use create tenant’s interfaces. In the vendor we use in this blogpost, which is 6WIND, the following interfaces are needed (some key elements are highlighted as well):


1
2
3
4
5
6
7
8
+--bridgeXXX
   +--ip_address
   +--vrrp
   +--children:
     +--vxlanYYY
     |  +--vxlan_id
     +--physicalZZZ
        +--vlan_id

First, let’s create a bridge interface. To do that, naviaged to “Interface” tab of the chosen device in the “Devices” category. Press “+ Add Components” to add a new Interface.

Choosing PE to Add Tenant in NetBox
Adding New Interface in NetBox

In the opened window, provide the interface’s name and type, as well as assign a corresponding VLAN to it.

Creating New Interface in NetBox – 1
Creating New Interface in NetBox – 2

In the similar way, create also physical interface and VXLAN interface. The key difference for them is to add a parent interface, which shall be the created bridge:

Creating New Interface in NetBox – 3

Finally, add the IP address (in fact, 2 IP addresses: virtual IP and interface IP) to a bridge interface:

Adding IP Address to a New Interface in NetBox

NetBox is a truly powerful tool for modelling. At our Network Automation Training you will master it in-depth.

Step #3. Create Customer’s Configuration at 6WIND with Ansible and NETCONF/YANG

In one of the previous blogposts about 6WIND, we have shown some details about its NETCONF implementation and shared a basic playbook to collect YANG modules. Now we will extend it to create a configuration.

The components for our automation:

Putting that together, we create the following structure for our Ansible automation (it is very simplified):


1
2
3
4
5
6
7
8
9
10
11
12
13
+--configurator.yaml
+--roles
   +--300_prepare_vars
   |  +--tasks
   |  | +--main.yaml
   |  +--templates
   |     +--interface_vrf_mapping.j2
   +--301_push_config
      +--tasks
      |  +--change.yaml
      |  +--main.yaml
      +--templates
         +--{... multiple config templates}

Enrol to our Network Automation Training to master Ansible skills to be able create carrier-grade automation.

Step #4. Verify the Automation’s Operation

We have created the VRF with scalability in mind. Therefore, we have introduced two variables, which needs to be filled in:

Let’s run the provisioning for the network device, where we have added the tenant’s interfaces:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# ansible-playbook configurator.yaml --limit vr01-a --tags customer -e 'target_vrf=imba-vrf'
[DEPRECATION WARNING]: [defaults]callback_whitelist option, normalizing names to new standard, use callbacks_enabled instead. This feature will be removed
from ansible-core in version 2.15. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
[WARNING]: An error occurred while calling ansible.utils.display.initialize_locale (unsupported locale setting). This may result in incorrectly calculated
text widths that can cause Display to print incorrect line lengths

PLAY [CONFIGURATION OF 6WIND ROUTER] **************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************
Sunday 06 March 2022  20:57:59 +0000 (0:00:00.023)       0:00:00.023 **********
ok: [vr01-a]

TASK [100_collect_netbox : 10. POLL SITE DATA] ****************************************************************************************************************
Sunday 06 March 2022  20:58:01 +0000 (0:00:02.460)       0:00:02.483 **********
ok: [vr01-a]

TASK [100_collect_netbox : 20. POLL VRFS DATA] ****************************************************************************************************************
Sunday 06 March 2022  20:58:03 +0000 (0:00:01.548)       0:00:04.031 **********
ok: [vr01-a]

TASK [300_prepare_vars : 300.10. MAP INTERFACES TO VRFS] ******************************************************************************************************
Sunday 06 March 2022  20:58:04 +0000 (0:00:01.405)       0:00:05.437 **********
ok: [vr01-a]

TASK [301_push_config : 301.10. CREATE TEMPORARY DIRECTORY] ***************************************************************************************************
Sunday 06 March 2022  20:58:05 +0000 (0:00:00.967)       0:00:06.405 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20. RUN CONFIGURATION LOOP] *******************************************************************************************************
Sunday 06 March 2022  20:58:06 +0000 (0:00:00.615)       0:00:07.021 **********
included: /root/6wind-automation/roles/301_push_config/tasks/change.yaml for vr01-a => (item=vrf)
included: /root/6wind-automation/roles/301_push_config/tasks/change.yaml for vr01-a => (item=vrrp)
included: /root/6wind-automation/roles/301_push_config/tasks/change.yaml for vr01-a => (item=interface)
included: /root/6wind-automation/roles/301_push_config/tasks/change.yaml for vr01-a => (item=bgp)

TASK [301_push_config : 301.20.10. PRE-CHANGE // COLLECT CONFIG OF non_main vrf] ******************************************************************************
Sunday 06 March 2022  20:58:06 +0000 (0:00:00.118)       0:00:07.140 **********
ok: [vr01-a]

TASK [301_push_config : 301.20.20. PRE-CHANGE // SAVING CONFIG] ***********************************************************************************************
Sunday 06 March 2022  20:58:09 +0000 (0:00:02.924)       0:00:10.065 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.30. CHANGE // PREPARE NETCONF MESSAGE BODY] ************************************************************************************
Sunday 06 March 2022  20:58:10 +0000 (0:00:01.071)       0:00:11.137 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.40. CHANGE // APPLY CONFIGURATION FOR non_main vrf] ****************************************************************************
Sunday 06 March 2022  20:58:11 +0000 (0:00:00.620)       0:00:11.757 **********
changed: [vr01-a]

TASK [301_push_config : 301.20.50. POST-CHANGE // COLLECT CONFIG OF non_main vrf] *****************************************************************************
Sunday 06 March 2022  20:58:13 +0000 (0:00:02.730)       0:00:14.487 **********
ok: [vr01-a]

TASK [301_push_config : 301.20.60. POST-CHANGE // SAVING CONFIG] **********************************************************************************************
Sunday 06 March 2022  20:58:16 +0000 (0:00:02.655)       0:00:17.143 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.70. COMPARING PRE AND POST CHANGE] *********************************************************************************************
Sunday 06 March 2022  20:58:17 +0000 (0:00:00.685)       0:00:17.828 **********
--- before
+++ after
@@ -1,4 +1,6 @@
 {
+    "data.config.vrf.name": "imba-vrf",
+    "data.config['@xmlns']": "urn:6wind:vrouter",
     "data['@xmlns']": "urn:ietf:params:xml:ns:netconf:base:1.0",
     "data['@xmlns:nc']": "urn:ietf:params:xml:ns:netconf:base:1.0"
 }

changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.80. SAVING DIFF] ***************************************************************************************************************
Sunday 06 March 2022  20:58:17 +0000 (0:00:00.115)       0:00:17.944 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.10. PRE-CHANGE // COLLECT CONFIG OF non_main vrrp] *****************************************************************************
Sunday 06 March 2022  20:58:17 +0000 (0:00:00.634)       0:00:18.578 **********
ok: [vr01-a]

TASK [301_push_config : 301.20.20. PRE-CHANGE // SAVING CONFIG] ***********************************************************************************************
Sunday 06 March 2022  20:58:20 +0000 (0:00:02.430)       0:00:21.009 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.30. CHANGE // PREPARE NETCONF MESSAGE BODY] ************************************************************************************
Sunday 06 March 2022  20:58:21 +0000 (0:00:00.665)       0:00:21.674 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.40. CHANGE // APPLY CONFIGURATION FOR non_main vrrp] ***************************************************************************
Sunday 06 March 2022  20:58:21 +0000 (0:00:00.716)       0:00:22.391 **********
changed: [vr01-a]

TASK [301_push_config : 301.20.50. POST-CHANGE // COLLECT CONFIG OF non_main vrrp] ****************************************************************************
Sunday 06 March 2022  20:58:23 +0000 (0:00:01.984)       0:00:24.376 **********
ok: [vr01-a]

TASK [301_push_config : 301.20.60. POST-CHANGE // SAVING CONFIG] **********************************************************************************************
Sunday 06 March 2022  20:58:26 +0000 (0:00:02.608)       0:00:26.984 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.70. COMPARING PRE AND POST CHANGE] *********************************************************************************************
Sunday 06 March 2022  20:58:27 +0000 (0:00:00.641)       0:00:27.625 **********
--- before
+++ after
@@ -1,4 +1,28 @@
 {
+    "data.config.vrf.interface.vrrp.enabled": "true",
+    "data.config.vrf.interface.vrrp.mtu": "9000",
+    "data.config.vrf.interface.vrrp.name": "vrrp101",
+    "data.config.vrf.interface.vrrp.preempt": "true",
+    "data.config.vrf.interface.vrrp.priority": "150",
+    "data.config.vrf.interface.vrrp.version": "2",
+    "data.config.vrf.interface.vrrp.vrid": "2",
+    "data.config.vrf.interface.vrrp['@xmlns']": "urn:6wind:vrouter/vrrp",
+    "data.config.vrf.interface.vrrp['advertisement-interval']": "1000",
+    "data.config.vrf.interface.vrrp['garp-delay']": "5",
+    "data.config.vrf.interface.vrrp['init-state']": "backup",
+    "data.config.vrf.interface.vrrp['link-interface']": "bridge101",
+    "data.config.vrf.interface.vrrp['preempt-delay']": "120",
+    "data.config.vrf.interface.vrrp['track-fast-path']": "true",
+    "data.config.vrf.interface.vrrp['track-link-interface']": "true",
+    "data.config.vrf.interface.vrrp['use-vmac']": "false",
+    "data.config.vrf.interface.vrrp['virtual-address'].ip": "10.100.11.1/32",
+    "data.config.vrf.interface.vrrp['vmac-xmit-base']": "false",
+    "data.config.vrf.interface['@xmlns']": "urn:6wind:vrouter/interface",
+    "data.config.vrf.name": "imba-vrf",
+    "data.config.vrf.vrrp.enabled": "true",
+    "data.config.vrf.vrrp['@xmlns']": "urn:6wind:vrouter/vrrp",
+    "data.config.vrf.vrrp['router-id']": "10.100.1.0",
+    "data.config['@xmlns']": "urn:6wind:vrouter",
     "data['@xmlns']": "urn:ietf:params:xml:ns:netconf:base:1.0",
     "data['@xmlns:nc']": "urn:ietf:params:xml:ns:netconf:base:1.0"
 }

changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.80. SAVING DIFF] ***************************************************************************************************************
Sunday 06 March 2022  20:58:27 +0000 (0:00:00.117)       0:00:27.743 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.10. PRE-CHANGE // COLLECT CONFIG OF non_main interface] ************************************************************************
Sunday 06 March 2022  20:58:27 +0000 (0:00:00.649)       0:00:28.392 **********
ok: [vr01-a]

TASK [301_push_config : 301.20.20. PRE-CHANGE // SAVING CONFIG] ***********************************************************************************************
Sunday 06 March 2022  20:58:30 +0000 (0:00:02.569)       0:00:30.961 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.30. CHANGE // PREPARE NETCONF MESSAGE BODY] ************************************************************************************
Sunday 06 March 2022  20:58:30 +0000 (0:00:00.607)       0:00:31.569 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.40. CHANGE // APPLY CONFIGURATION FOR non_main interface] **********************************************************************
Sunday 06 March 2022  20:58:31 +0000 (0:00:00.726)       0:00:32.295 **********
changed: [vr01-a]

TASK [301_push_config : 301.20.50. POST-CHANGE // COLLECT CONFIG OF non_main interface] ***********************************************************************
Sunday 06 March 2022  20:58:34 +0000 (0:00:02.384)       0:00:34.680 **********
ok: [vr01-a]

TASK [301_push_config : 301.20.60. POST-CHANGE // SAVING CONFIG] **********************************************************************************************
Sunday 06 March 2022  20:58:36 +0000 (0:00:02.541)       0:00:37.221 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.70. COMPARING PRE AND POST CHANGE] *********************************************************************************************
Sunday 06 March 2022  20:58:37 +0000 (0:00:00.640)       0:00:37.861 **********
--- before
+++ after
@@ -1,4 +1,22 @@
 {
+    "data.config.vrf.interface.bridge.enabled": "true",
+    "data.config.vrf.interface.bridge.ipv4.address.ip": "10.100.11.2/24",
+    "data.config.vrf.interface.bridge.ipv4.enabled": "true",
+    "data.config.vrf.interface.bridge.ipv6.enabled": "true",
+    "data.config.vrf.interface.bridge.mtu": "9000",
+    "data.config.vrf.interface.bridge.name": "bridge101",
+    "data.config.vrf.interface.bridge['@xmlns']": "urn:6wind:vrouter/bridge",
+    "data.config.vrf.interface.bridge['link-interface'][0].learning": "true",
+    "data.config.vrf.interface.bridge['link-interface'][0].slave": "lag0.101",
+    "data.config.vrf.interface.bridge['link-interface'][1].learning": "false",
+    "data.config.vrf.interface.bridge['link-interface'][1].slave": "vxlan101",
+    "data.config.vrf.interface.vlan.enabled": "true",
+    "data.config.vrf.interface.vlan.mtu": "9000",
+    "data.config.vrf.interface.vlan.name": "lag0.101",
+    "data.config.vrf.interface.vlan['@xmlns']": "urn:6wind:vrouter/vlan",
+    "data.config.vrf.interface.vlan['link-interface']": "lag0",
+    "data.config.vrf.interface.vlan['link-vrf']": "main",
+    "data.config.vrf.interface.vlan['vlan-id']": "101",
     "data.config.vrf.interface.vrrp.enabled": "true",
     "data.config.vrf.interface.vrrp.mtu": "9000",
     "data.config.vrf.interface.vrrp.name": "vrrp101",
@@ -17,6 +35,13 @@
     "data.config.vrf.interface.vrrp['use-vmac']": "false",
     "data.config.vrf.interface.vrrp['virtual-address'].ip": "10.100.11.1/32",
     "data.config.vrf.interface.vrrp['vmac-xmit-base']": "false",
+    "data.config.vrf.interface.vxlan.enabled": "true",
+    "data.config.vrf.interface.vxlan.mtu": "9000",
+    "data.config.vrf.interface.vxlan.name": "vxlan101",
+    "data.config.vrf.interface.vxlan.vni": "101",
+    "data.config.vrf.interface.vxlan['@xmlns']": "urn:6wind:vrouter/vxlan",
+    "data.config.vrf.interface.vxlan['link-interface']": "loopback0",
+    "data.config.vrf.interface.vxlan['link-vrf']": "main",
     "data.config.vrf.interface['@xmlns']": "urn:6wind:vrouter/interface",
     "data.config.vrf.name": "imba-vrf",
     "data.config['@xmlns']": "urn:6wind:vrouter",

changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.80. SAVING DIFF] ***************************************************************************************************************
Sunday 06 March 2022  20:58:37 +0000 (0:00:00.119)       0:00:37.981 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.10. PRE-CHANGE // COLLECT CONFIG OF non_main bgp] ******************************************************************************
Sunday 06 March 2022  20:58:38 +0000 (0:00:00.655)       0:00:38.637 **********
ok: [vr01-a]

TASK [301_push_config : 301.20.20. PRE-CHANGE // SAVING CONFIG] ***********************************************************************************************
Sunday 06 March 2022  20:58:40 +0000 (0:00:02.539)       0:00:41.176 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.30. CHANGE // PREPARE NETCONF MESSAGE BODY] ************************************************************************************
Sunday 06 March 2022  20:58:41 +0000 (0:00:00.629)       0:00:41.805 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.40. CHANGE // APPLY CONFIGURATION FOR non_main bgp] ****************************************************************************
Sunday 06 March 2022  20:58:41 +0000 (0:00:00.654)       0:00:42.460 **********
changed: [vr01-a]

TASK [301_push_config : 301.20.50. POST-CHANGE // COLLECT CONFIG OF non_main bgp] *****************************************************************************
Sunday 06 March 2022  20:58:44 +0000 (0:00:02.528)       0:00:44.988 **********
ok: [vr01-a]

TASK [301_push_config : 301.20.60. POST-CHANGE // SAVING CONFIG] **********************************************************************************************
Sunday 06 March 2022  20:58:46 +0000 (0:00:02.555)       0:00:47.543 **********
changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.70. COMPARING PRE AND POST CHANGE] *********************************************************************************************
Sunday 06 March 2022  20:58:47 +0000 (0:00:00.641)       0:00:48.185 **********
--- before
+++ after
@@ -1,4 +1,20 @@
 {
+    "data.config.vrf.name": "imba-vrf",
+    "data.config.vrf.routing.bgp.as": "65000",
+    "data.config.vrf.routing.bgp.enabled": "true",
+    "data.config.vrf.routing.bgp['@xmlns']": "urn:6wind:vrouter/bgp",
+    "data.config.vrf.routing.bgp['address-family']['ipv4-unicast'].redistribute.protocol": "connected",
+    "data.config.vrf.routing.bgp['address-family']['l2vpn-evpn'].advertise": "ipv4-unicast",
+    "data.config.vrf.routing.bgp['address-family']['l2vpn-evpn'].enabled": "true",
+    "data.config.vrf.routing.bgp['address-family']['l2vpn-evpn'].export['route-distinguisher']": "65000:100",
+    "data.config.vrf.routing.bgp['address-family']['l2vpn-evpn'].export['route-target']": "65000:100",
+    "data.config.vrf.routing.bgp['address-family']['l2vpn-evpn'].flooding": "head-end-replication",
+    "data.config.vrf.routing.bgp['address-family']['l2vpn-evpn'].import['route-target']": "65000:100",
+    "data.config.vrf.routing.bgp['address-family']['l2vpn-evpn']['advertise-all-vni']": "false",
+    "data.config.vrf.routing.bgp['address-family']['l2vpn-evpn']['auto-route-target']": "disabled",
+    "data.config.vrf.routing.bgp['router-id']": "10.100.1.0",
+    "data.config.vrf.routing['@xmlns']": "urn:6wind:vrouter/routing",
+    "data.config['@xmlns']": "urn:6wind:vrouter",
     "data['@xmlns']": "urn:ietf:params:xml:ns:netconf:base:1.0",
     "data['@xmlns:nc']": "urn:ietf:params:xml:ns:netconf:base:1.0"
 }

changed: [vr01-a -> localhost]

TASK [301_push_config : 301.20.80. SAVING DIFF] ***************************************************************************************************************
Sunday 06 March 2022  20:58:47 +0000 (0:00:00.120)       0:00:48.306 **********
changed: [vr01-a -> localhost]

PLAY RECAP ****************************************************************************************************************************************************
vr01-a                     : ok=41   changed=25   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

Sunday 06 March 2022  20:58:48 +0000 (0:00:00.811)       0:00:49.118 **********
===============================================================================
301_push_config : 301.20.10. PRE-CHANGE // COLLECT CONFIG OF non_main vrf ------------------------------------------------------------------------------ 2.93s
301_push_config : 301.20.40. CHANGE // APPLY CONFIGURATION FOR non_main vrf ---------------------------------------------------------------------------- 2.73s
301_push_config : 301.20.50. POST-CHANGE // COLLECT CONFIG OF non_main vrf ----------------------------------------------------------------------------- 2.66s
301_push_config : 301.20.50. POST-CHANGE // COLLECT CONFIG OF non_main vrrp ---------------------------------------------------------------------------- 2.61s
301_push_config : 301.20.10. PRE-CHANGE // COLLECT CONFIG OF non_main interface ------------------------------------------------------------------------ 2.57s
301_push_config : 301.20.50. POST-CHANGE // COLLECT CONFIG OF non_main bgp ----------------------------------------------------------------------------- 2.56s
301_push_config : 301.20.50. POST-CHANGE // COLLECT CONFIG OF non_main interface ----------------------------------------------------------------------- 2.54s
301_push_config : 301.20.10. PRE-CHANGE // COLLECT CONFIG OF non_main bgp ------------------------------------------------------------------------------ 2.54s
301_push_config : 301.20.40. CHANGE // APPLY CONFIGURATION FOR non_main bgp ---------------------------------------------------------------------------- 2.53s
Gathering Facts ---------------------------------------------------------------------------------------------------------------------------------------- 2.46s
301_push_config : 301.20.10. PRE-CHANGE // COLLECT CONFIG OF non_main vrrp ----------------------------------------------------------------------------- 2.43s
301_push_config : 301.20.40. CHANGE // APPLY CONFIGURATION FOR non_main interface ---------------------------------------------------------------------- 2.38s
301_push_config : 301.20.40. CHANGE // APPLY CONFIGURATION FOR non_main vrrp --------------------------------------------------------------------------- 1.98s
100_collect_netbox : 10. POLL SITE DATA ---------------------------------------------------------------------------------------------------------------- 1.55s
100_collect_netbox : 20. POLL VRFS DATA ---------------------------------------------------------------------------------------------------------------- 1.41s
301_push_config : 301.20.20. PRE-CHANGE // SAVING CONFIG ----------------------------------------------------------------------------------------------- 1.07s
300_prepare_vars : 300.10. MAP INTERFACES TO VRFS ------------------------------------------------------------------------------------------------------ 0.97s
301_push_config : 301.20.80. SAVING DIFF --------------------------------------------------------------------------------------------------------------- 0.81s
301_push_config : 301.20.30. CHANGE // PREPARE NETCONF MESSAGE BODY ------------------------------------------------------------------------------------ 0.73s
301_push_config : 301.20.30. CHANGE // PREPARE NETCONF MESSAGE BODY ------------------------------------------------------------------------------------ 0.72s

During the execution cycle, the new configuration is being applied to the 6WIND network device. This Ansible automation is created in a way that you can you see the changes, of which exactly new configuration (key-value pairs) is applied. Moreover, this information is stored in the the new directory with the timestamp of execution:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
+--.ops
   +--20220306T205801667717
      +--vr01-a_non_main_bgp_change.json
      +--vr01-a_non_main_interface_change.json
      +--vr01-a_non_main_vrf_change.json
      +--vr01-a_non_main_vrrp_change.json
      +--vr01-a_non_main_bgp_diff.json
      +--vr01-a_non_main_interface_diff.json
      +--vr01-a_non_main_vrf_diff.json
      +--vr01-a_non_main_vrrp_diff.json
      +--vr01-a_non_main_bgp_post_change.json
      +--vr01-a_non_main_interface_post_change.json
      +--vr01-a_non_main_vrf_post_change.json  
      +--vr01-a_non_main_vrrp_post_change.json
      +--vr01-a_non_main_bgp_pre_change.json
      +--vr01-a_non_main_interface_pre_change.json
      +--vr01-a_non_main_vrf_pre_change.json
      +--vr01-a_non_main_vrrp_pre_change.json

Each of these files contains one of four item types:

In our Network Automation Training you will learn how to create such automation yourself.

Final touch if to check how the configuration looks like from the 6WIND router itself:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
pod-013-6wind1> show config / vrf imba-vrf
vrf imba-vrf
    routing
        bgp
            enabled true
            as 65000
            always-compare-med false
            bestpath
                as-path
                    confederation false
                    ignore false
                    ..
                compare-routerid false
                ..
            client-to-client
                reflection true
                ..
            deterministic-med false
            ebgp-connected-route-check true
            fast-external-failover true
            graceful-shutdown false
            listen
                limit 100
                ..
            log-neighbor-changes false
            network-import-check false
            route-reflector-allow-outbound-policy false
            reject-as-sets false
            packet-rw-quantum
                read 10
                write 64
                ..
            router-id 10.100.1.0
            ebgp-requires-policy false
            address-family
                ipv4-unicast
                    enabled true
                    redistribute connected
                    maximum-path
                        ebgp 16
                        ibgp 16
                        equal-cluster-length false
                        ..
                    bgp-distance
                        external-routes 20
                        internal-routes 200
                        local-routes 200
                        ..
                    ..
                l2vpn-evpn
                    enabled true
                    advertise ipv4-unicast
                    advertise-all-vni false
                    auto-route-target disabled
                    flooding head-end-replication
                    export
                        route-target 65000:100
                        route-distinguisher 65000:100
                        ..
                    import
                        route-target 65000:100
                        ..
                    ..
                ..
            ..
        ..
    interface
        vxlan vxlan101
            mtu 9000
            enabled true
            ipv4
                enabled true
                ..
            ipv6
                enabled true
                ..
            vni 101
            link-interface loopback0
            link-vrf main
            learning true
            gbp false
            dst 4789
            src-range
                49152
                65535
                ..
            ..
        bridge bridge101
            mtu 9000
            enabled true
            ipv4
                address 10.100.11.2/24
                enabled true
                ..
            ipv6
                enabled true
                ..
            link-interface lag0.101 learning true
            link-interface vxlan101 learning false
            ..
        vlan lag0.101
            mtu 9000
            enabled true
            ipv4
                enabled true
                ..
            ipv6
                enabled true
                ..
            vlan-id 101
            link-interface lag0
            protocol 802.1q
            link-vrf main
            ..
        vrrp vrrp101
            mtu 9000
            enabled true
            version 2
            link-interface bridge101
            garp-delay 5
            use-vmac false
            vmac-xmit-base false
            vrid 2
            priority 150
            init-state backup
            preempt true
            preempt-delay 120
            advertisement-interval 1000
            track-link-interface true
            track-fast-path true
            virtual-address 10.100.11.1/32
            ..
        ..
    vrrp
        enabled true
        router-id 10.100.1.0
        traps-enabled false
        vrrp-startup-delay 0
        ..
    ..

Examples in GitHub

You can find this and other examples in our GitHub repository.

Lessons Learned

It took us to prepare the proper Ansible automation for two main reasons:

Conclusion

Automation of reputable tasks, such as customers onboarding or decommissioning is a vital step in service providers development to free up network engineering resources and provide a consistent and deterministic quality for customers. Relying leading open source tools, such as Ansible and NetBox, as well as standardised management frameworks, such as NETCONF/YANG, it is possible to achieve it. Take care and good bye.

Need Help? Contract Us

If you need a trusted and experienced partner to automate your network and IT infrastructure, get in touch with us.

P.S.

If you have further questions or you need help with your networks, we are happy to assist you, just send us a message. Also don’t forget to share the article on your social media, if you like it.

BR,

Anton Karneliuk

Exit mobile version