With the increasing size and complexity of modern enterprise networks, the demand on simplifying the networks management becomes more intense. The introduction of resources modules with Ansible Engine 2.9 provide a path to users to ease the network management, especially across multiple different product vendors.
In the past, we’ve already covered resource modules for OSPF management and for ACLs. However, simplifying network management is not limited to rather local network setups or intra domain routing only. “Border Gateway Protocol (BGP) is a standardized exterior gateway protocol designed to exchange routing and reachability information between autonomous systems (AS) on the internet. The protocol is often classified as a path vector protocol but is sometimes also classed as a distance-vector routing protocol.” It is used in larger network setups, as the NetworkWorld so aptly observes:
BGP has been called the glue of the Internet and the postal service of the internet. One comparison likens BGP to GPS applications on mobile phones.
Managing BGP manually for a network device can be a very difficult and tedious task, and more often this needs to be performed carefully, as the manual process is more prone to human error.
This blog post goes through the BGP resource module for the Juniper Networks Junos Network Management Platform. We will walk through several examples and describe the use cases for each state parameter and how we envision these being used in real world scenarios.
BGP Global resource modules example: Junos
The goal of BGP resource modules is to make sure configurations are consistently applied across the infrastructure with less effort. It simplifies management and makes it faster and easier to scale without worrying about the actual implementation details of the network platforms working under the hood.
Ansible content refers to Ansible Playbooks, modules, module utilities and plugins. Basically all of the Ansible tools that users utilize to create their Ansible automation. BGP resource module is part of Ansible Content Collections. To learn more about Ansible Content Collections, you can check out two of our blogs: Getting Started with Ansible Content Collections and The Future of Ansible Content Delivery.
Let’s have a closer look at how the BGP resource modules work. As an example, we pick the junos_bgp_global
resource module. In this blog, we’ll be using a Junos device model vSRX with version 18.4R1-S3.1 for all the configuration management specific operations. Also, to better showcase the effect of the modules, we will start with some BGP global config specific attributes already configured.
Accessing and using the Junos Collection
To download the Junos Collection, refer to Automation Hub (fully supported, requires a Red Hat Ansible Automation Platform subscription) or Ansible Galaxy (upstream community supported):
- Automation Hub Collection:
junipernetworks.junos
- Ansible Galaxy Collection:
junipernetworks.junos
To learn more about how to configure downloading via the ansible.cfg
file or requirements.yml
file, please refer to the blog, Hands On With Ansible Collections.
Before we get started, let’s quickly explain the rationale behind naming the network resource modules. Notice for resource modules that configure BGP routes, the newly added modules will be named based on their behaviour or impact. To manage global BGP config we have separate resource module junos_bgp_global
and for address family configuration we have separate resource module junos_bgp_address_family
. This was done so that those using existing network modules would not have their Ansible Playbooks stop working and have sufficient time to migrate to the new network automation modules.
A module to configure global BGP attributes is also available for the following supported platforms:
- Arista EOS (arista.eos.eos_bgp_global)
- Cisco IOS (cisco.ios.ios_bgp_global)
- Cisco IOSXR (cisco.ios.iosxr_bgp_global)
- Cisco NX-OS (cisco.nxos.nxos_bgp_global)
- Juniper Junos (junipernetwork.junos.junos_bgp_global)
- VyOS (vyos.vyos.vyos_bgp_global)
The BGP resource module provides the same level of functionality that a user can achieve when configuring manually on the JuniperJunos device with all advantages of Ansible automation, plus with an added edge of Ansible fact gathering and resource module approach, which is more closely aligned with network professionals day to day working.
In Ansible core 2.10 and newer, short names are supported with the meta/runtime.yml
file for any Ansible Collection. For more information on redirects read the documentation here.
Long name: junipernetworks.junos.junos_bgp_global
Short Name: junipernetworks.junos.bgp_global
However we will maintain backwards compatibility to make sure your automation does not lose functionality.
There is also an online webinar that goes into more details on webinar naming and fully qualified collection names (FQCN): Webinar: Migrating to Ansible Collections.
Use Case: BGP configuration changes
Using state gathered - Building an Ansible inventory
Resource modules allow the user to read in existing network configuration and convert that into a structured data model. The state: gathered
is the equivalent for gathering Ansible facts for this specific resource. This example will read in the existing network configuration and store it as a flat-file.
Here is an Ansible Playbook example of using state: gathered
and storing the result as YAML into host_vars
. If you are new to Ansible inventory and want to learn about group_vars
and host_vars
, please refer to the documentation here.
Some Ansible Network platforms support multiple connection types, privilege escalation or other options. To learn more about different platform options, please refer to platform options documentation.
---
- name: convert configured BGP resource to structured data
hosts: junos
vars:
inventory_dir: "lab_inventory"
inventory_hostname: "junos"
gather_facts: false
tasks:
- name: Use the bgp_global resource module to gather the current config
junipernetworks.junos.junos_bgp_global:
state: gathered
register: bgp_global
- name: Create inventory directory
file:
path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}"
state: directory
- name: Write the BGP GLOBAL configuration to a file
copy:
content: "{{ {'bgp_global': bgp_global['gathered']} | to_nice_yaml }}"
dest: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}/bgp_global.yaml"
Execute the Ansible Playbook with the ansible-playbook
command:
$ ansible-playbook example.yml
Here is the data structure that was created from reading/gathered operation in a brown-field configuration:
$ cat lab_inventory/host_vars/junos/bgp_global.yaml
bgp_global:
accept_remote_nexthop: true
add_path_display_ipv4_address: true
advertise_from_main_vpn_tables: true
advertise_inactive: true
as_number: '65534'
asdot_notation: true
authentication_algorithm: md5
bgp_error_tolerance:
malformed_route_limit: 20000000
bmp:
monitor: true
damping: true
description: This is configured with Junos_bgp resource module
egress_te_sid_stats: true
groups:
- name: internal
out_delay: 12
hold_time: 5
You can check out the full detailed listing of the output of this example in the state: gathered reference gist.
Using state merged - Pushing configuration changes
The state: merged
will take your Ansible configuration data (i.e. Ansible variables) and merges them into the network device’s running configuration. This will not affect existing configuration not specified in your Ansible configuration data. Let’s walk through an example.
We will modify the flat-file created in the first example with a configuration to be merged. Here are the most important pieces:
groups:
- name: internal
out_delay: 22
- name: external
out_delay: 20
hold_time: 15
holddown_all_stale_labels: true
include_mp_next_hop: true
loops: 5
no_advertise_peer_as: true
no_aggregator_id: true
Now let’s create an Ansible Playbook to merge this new configuration into the network device’s running configuration:
---
- name: Merged state play
hosts: junos
gather_facts: false
tasks:
- name: Merge BGP config with device existing BGP global config
junipernetworks.junos.junos_bgp_global:
state: merged
config: "{{ bgp_global }}"
Execute the Ansible Playbook with the ansible-playbook command:
$ ansible-playbook merged.yml
And, once we run the respective merge play, all of the provided parameters will be configured on the Junos appliance with Ansible changed=True
.
Note the network configuration after the merge operation:
vagrant@vsrx# show protocols bgp
include-mp-next-hop;
group internal {
out-delay 22;
}
group external {
out-delay 20;
}
Note that this listing only shows a few highlights; the full listing is available in the merged gist.
Let’s take a look at what has changed through this operation: if we go through the device output, there are a few observations:
- Attribute group with name
external
was added to the BGP group list. Mtu-discovery
,keep
andno-precision-timers
got configured.- If there was an already configured BGP group with
out_delay
and the user wanted to update any parameter for that particular group, then the user can also use the merged state to update the group under BGP.
With the second run, the respective merge play runs again and Ansible charm of idempotency comes to picture. If nothing’s changed, play run results into changed=False
, which confirms to the user that all of the provided configurations in the play are already configured on the Junos appliance.
Using state replaced - Replacing configuration
If the user wants to re-configure the Junos appliance entirely existing BGP configuration with the provided BGP configuration, then the resource module replaced
state comes into picture.
The scope of the replaced operation is up to BGP global attributes accept address_family
or bgp_group
address family. In the case of Juniper Junos vSRX only a single BGP instance is supported. As a result, the replaced state acts similar to the overridden state. For that reason a dedicated overridden state is not required with the Junos modules. Other network platforms that support multiple BGP instances do have the overridden state operation.
Using the replaced state, a user can override all BGP resource global attributes with user-provided BGP configuration. Since this resource module state overrides all pre-existing attributes of the resource module, the replaced state should be used cautiously; if all the configurations are mistakenly replaced with the play input configuration, it might create unnecessary issues for the network administrators.
In this scenario, BGP with ‘n’ number GROUPs are already configured on the Junos appliance, and now the user wants to update the GROUP list with a new set of GROUPs and discard all the already configured BGP GROUPs. Here, the resource module replaced state will be an ideal choice and, as the name suggests, the replaced state will replace BGP existing GROUP list with a new set of GROUPSs given as input by the user.
If a user tries to configure any new BGP GROUP/attribute that’s not already pre-configured on the device, it’ll act as a merged state and the junos_bgp_global
module will try to configure the BGP GROUPs given as input by the user inside the replace play.
We will modify the flat-file created in the first example:
groups:
- name: inter
out_delay: 22
description: "This is internal group"
keep: all
- name: external
out_delay: 20
- name: extbound
accept_remote_nexthop: true
add_path_display_ipv4_address: true
out_delay: 10
description: "External bound"
keep: all
Check out the full input config structure if you want to learn more details.
Again, we create an Ansible Playbook to replace this new configuration into the network device’s running configuration:
---
- name: Replaced state play
hosts: junos
gather_facts: false
tasks:
- name: Replace running BGP global config with provided config
junipernetworks.junos.junos_bgp_global:
state: replaced
config: "{{ bgp_global }}"
Once we run the respective replaced play, all of the provided parameters will override all the existing BGP resource specific config on the Junos appliance with Ansible changed=True
.
The Juniper network device configuration after the replaced operation:
vagrant@vsrx# show protocols bgp
group extbound {
description "External bound";
accept-remote-nexthop;
keep all;
out-delay 10;
add-path-display-ipv4-address;
}
Check out the corresponding gist for full Juniper device configuration.
If we dig into the above output, we note the following changes:
- Replaced negates all of the pre-existing BGP resource-specific attributes (except address family in case that exists).
- For any non-existing BGP specific attribute, the replaced state will configure the BGP in the same manner as the merged state. In the above example, a new BGP group configured for BGP groups list.
With the second run of the above play, there are no changes reported which satisfies the Ansible idempotency.
Using state purged - Purge configuration
We can purge the pre-configured BGP instance attribute with the purge operational state for the user.
Purging ALL BGP (GLOBAL and ADDRESS-FAMILY) config in one go leads to deleting all the pre-configured BGP-specific attributes from the Junos appliance. But that said, this is a very critical delete operation and if not used judiciously, it has the power to delete all pre-configured BGP (GLOBAL and ADDRESS-FAMILY) and can result in the production environment with the router having no pre-configured BGP attributes.
Let’s create an Ansible Playbook to purge running BGP configuration.
Note: Running BGP configuration includes bgp address family resources.
vagrant@vsrx# show routing-options autonomous-system
65534 loops 3 asdot-notation;
vagrant@vsrx# show protocols bgp
damping;
bgp-error-tolerance {
malformed-route-limit 20000000;
}
family inet {
unicast {
local-ipv4-address 9.9.9.9;
extended-nexthop;
extended-nexthop-color;
}
Check out the full running-config including address-family resource.
---
- name: Purged state play
hosts: Junos
gather_facts: false
tasks:
- name: Purge Complete BGP config
junipernetworks.junos.junos_bgp_global:
state: purged
After we execute the playbook, the network device configuration changed:
vagrant@vsrx# show protocols bgp
vagrant@vsrx#
vagrant@vsrx# show routing-options autonomous-system
vagrant@vsrx#
Make sure to look at the full listing of the changed values. If we dig into the above output briefly, we can see that all the BGP resource-specific config(bgp-global
, bgp-address-family
, bgp-groups
, bgp-groups-address-family
) has been removed from the network configuration.
Using state deleted - Delete configuration
Now that we’ve talked about how we can purge BGP instances attributes on the Junos appliance by using junos_bgp_global
resource module purged state, I’d like to note that purged operation is only something that needs to be performed in extreme use cases. You might want to use delete
operation more often than purge, as delete
will only affect global configuration and won’t affect
address-family resource configuration (which also includes BGP groups AF or neighbors AF).
Deleting BGP global configuration leads to deleting all the pre-configured BGP GLOBAL resource specific attributes from the Junos appliance and won’t delete address-family resource attributes.
Note: Running BGP configuration includes BGP address family resources.
vagrant@vsrx# show routing-options autonomous-system
65534 loops 3 asdot-notation;
vagrant@vsrx# show protocols bgp
bgp-error-tolerance {
malformed-route-limit 20000000;
}
family inet {
unicast {
local-ipv4-address 9.9.9.9;
Check out the full running-config including address-family resource.
Let’s create an Ansible Playbook to delete running BGP global resource configuration.
---
- name: Deleted state play
hosts: Junos
gather_facts: false
tasks:
- name: Delete BGP global resource config
junipernetworks.junos.junos_bgp_global:
state: deleted
After we execute the playbook, the network device configuration changed:
$vagrant@vsrx# show protocols bgp
vagrant@vsrx#
vagrant@vsrx# show routing-options autonomous-system
vagrant@vsrx# vagrant@vsrx# show protocols bgp
family inet {
unicast {
local-ipv4-address 9.9.9.9;
extended-nexthop;
extended-nexthop-color;
}
Make sure to look at the full listing of the changed values. If we dig into the above output briefly, we can observe following:
- all the BGP global resource-specific config has been removed from the network configuration.
- Unlike
purged
state operation,deleted
state operation doesn’t removeaddress-family
resource config, which is still part of Junos network device running config. This means purged impacts the whole BGP resource while delete impacts only the global level attributes and doesn’t affect BGP address-family resources. This is what differentiatespurged
anddeleted
state operations from each other.
If you want to see more differences between purged
and deleted
operations functionality, you can observe the commands/XML tree generated in the above listed changed values for both operations.
Using state rendered - Development and working offline
Ansible renders the provided configuration in the task in the device-native format (for example, Junos XML). Ansible returns this rendered configuration in the rendered key in the result. Note this state does not communicate with the network device and can be used offline.
To have a config to be rendered, modify the YAML file created in the first scenario. For example, if this is the junos_bgp_global
module, you can just add a few more attributes to show we change the data model yet again.
groups:
- name: inter
out_delay: 22
description: "This is internal group"
keep: "all"
See the full listing in the corresponding rendered gist.
We create a playbook to execute this:
---
- name: Rendered state play
hosts: junos
gather_facts: false
tasks:
- name: Render the provided configuration
junipernetworks.junos.junos_bgp_global:
config: "{{ bgp_global }}"
state: rendered
This produces the following output:
"rendered": [
<nc:protocols xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">
<nc:bgp>
<nc:accept-remote-nexthop/>
<nc:add-path-display-ipv4-address/>
Check out the corresponding gist for more details.
If we dig into the above output, we can see that nothing has changed at all; rendered doesn’t even require the connection establishment with an actual network device.
Using state parsed - Development and working offline
Ansible parses the configuration from the running_configuration
option into Ansible structured data in the parsed
key in the result. Note this does not gather the configuration from the network device, so this state can be used offline.
As the config to be parsed we take XML format configuration as device support netconf
:
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="urn:uuid:0cadb4e8-5bba-47f4-986e-72906227007f">
<configuration changed-seconds="1590139550" changed-localtime="2020-05-22 09:25:50 UTC">
<version>18.4R1-S2.4</version>
<protocols>
<bgp>
See the full listing in the corresponding parsed gist.
The playbook to apply this configuration is:
---
- name: Parsed state play
hosts: junos
gather_facts: false
tasks:
- name: Parse the provided BGP global configuration
junipernetworks.junos.junos_bgp_global:
running_config: "{{lookup('file', './bgp_global.cfg')}}"
state: parsed
Execute the playbook generates the structured output:
"parsed": {
"accept_remote_nexthop": true,
"add_path_display_ipv4_address": true,
"advertise_bgp_static": {
"policy": "static-to-bgp"
},
"advertise_from_main_vpn_tables": true,
"advertise_inactive": true,
See the full listing in the corresponding gist.
If we dig into the above output, we can see that nothing has changed at all; parsed operation doesn’t even require the connection establishment with an actual network device.
Note: parsed input to be provided as value to running_config
key.
Takeaways & Next Steps
As shown above, with the help of the resource modules management of BGP, resource-specific configurations can be greatly simplified. Users don't need to bother much about BGP implementation details for each platform, they can just enter the actual data. By using the merged, replaced and overridden parameters, we allow much more flexibility for network engineers to adopt automation in incremental steps. The other operations like gathered, rendered and parsed allow a better, user friendly handling of the facts and the data managed within these tasks.
If you want to learn more about the Red Hat Ansible Automation Platform and network automation, you can check out these resources:
執筆者紹介
チャンネル別に見る
自動化
テクノロジー、チームおよび環境に関する IT 自動化の最新情報
AI (人工知能)
お客様が AI ワークロードをどこでも自由に実行することを可能にするプラットフォームについてのアップデート
オープン・ハイブリッドクラウド
ハイブリッドクラウドで柔軟に未来を築く方法をご確認ください。
セキュリティ
環境やテクノロジー全体に及ぶリスクを軽減する方法に関する最新情報
エッジコンピューティング
エッジでの運用を単純化するプラットフォームのアップデート
インフラストラクチャ
世界有数のエンタープライズ向け Linux プラットフォームの最新情報
アプリケーション
アプリケーションの最も困難な課題に対する Red Hat ソリューションの詳細
オリジナル番組
エンタープライズ向けテクノロジーのメーカーやリーダーによるストーリー
製品
ツール
試用、購入、販売
コミュニケーション
Red Hat について
エンタープライズ・オープンソース・ソリューションのプロバイダーとして世界をリードする Red Hat は、Linux、クラウド、コンテナ、Kubernetes などのテクノロジーを提供しています。Red Hat は強化されたソリューションを提供し、コアデータセンターからネットワークエッジまで、企業が複数のプラットフォームおよび環境間で容易に運用できるようにしています。
言語を選択してください
Red Hat legal and privacy links
- Red Hat について
- 採用情報
- イベント
- 各国のオフィス
- Red Hat へのお問い合わせ
- Red Hat ブログ
- ダイバーシティ、エクイティ、およびインクルージョン
- Cool Stuff Store
- Red Hat Summit