Develop and Deploy Network Templates Before Automating
Date: 2022-05-26
Subject: Network Templating
Version 1.0
Automation is the number one topic in networking today. Automation allows a team to lean left, moving simple troubleshooting to the NOC, it allows the team to do more with less, and it allows for repeatable deployments. A good place to start is to think about many of the day to day work that gets done, how much of this work is simply applying the same changes over and over. These tasks are a great place to start with templating.
I think an obvious task to start for automation is VPN deployments. This is a task that involved touching at least 2 routers and possibly 4 routers if redundant VPN’s are the standard for your company. This usually also involves configuring an IGP or BGP instance or both on each router, as well as modifying multiple Access lists. It is also a task where small inconsistencies can lead to hours of troubleshooting.
What’s Needed
- Python 3.x
- Jinja support
- Yaml support
- Yaml Answer File
- Jinja Template for each router
- python script to render
- First we need to create a template for each router. I am only providing a single template here instead of four. Although this is a working correct template, configuring VPN’s is beyond the scope of this tutorial. Anyone with a few years of experience should be able to build the missing files in a lab based on whats provided.
- cisco.j2
!Configure GRE
interface {{ loopback_interface }}
ip address {{ loopback_address }}
interface {{ tunnel_interface}}
no shutdown
ip address 10.10.100.1 255.255.255.0
tunnel source {{loopback_interface }}
tunnel destination {{ tunnel_destination }}
tunnel path-mtu-discovery
tunnel protection ipsec profile ikev2_TP
exit
!Configure Ike Policy
crypto ikev2 keyring {{ ike_keyring_name }}
peer {{ ike_keyring_peer }}
address {{ ike_keyring_address }}
pre-shared-key {{ ike_keyring_preshared_key }}
crypto ikev2 proposal {{proposal_name }}
encryption {{ proposal_encryption }}
integrity {{ proposal_integrity }}
group {{ proposal_group }}
crypto ikev2 profile {{ profile_name }}
match identity remote address {{ profile_remote_address }}
authentication local {{ profile_authentication_local }}
authentication remote {{ profile_authentication_remote }}
keyring local {{ profile_keyring_local }}
crypto ikev2 policy {{ crypto_policy_name }}
proposal {{ crypto_policy_proposal }}
ip access-list extended {{ crypto_match_acl_name }}
permit ip host {{ crypto_match_acl_local }} host {{ crypto_match_acl_remote }}
permit ip host {{crypto_match_acl_remote }} host {{ crypto_match_acl_local }}
crypto ipsec transform-set {{ transformset_data }}
! Define Crypto map and Ipsec
crypto map {{ cryptomap_name }} ipsec-isakmp
set peer {{ cryptomap_peer }}
set security-association lifetime seconds 3600
set transform-set {{ cryptomap_tset }}
set pfs {{ cryptomap_group }}
set ikev2-profile {{ cryptomap_profile }}
match address {{ cryptomap_match }}
interface {{ interface_name }}
ip address 1.1.1.1 255.255.255.224
negotiation auto
{{ interface_crypto }}
- Yaml Answer file
---
loopback_interface: Loopback0
loopback_address: "10.1.1.1 255.255.255.0"
tunnel_interface: Tunnel100
tunnel_destination: 10.2.2.2
ike_keyring_name: HQ
ike_keyring_peer: HQ
ike_keyring_address: 2.2.2.2
ike_keyring_preshared_key: cisco1234
proposal_name: Prop-HQ
proposal_encryption: aes-cbc-256
proposal_integrity: sha256
proposal_group: 19
profile_name: PROFILE-HQ
profile_remote_address: "2.2.2.2 255.255.255.255"
profile_authentication_local: pre-share
profile_authentication_remote: pre-share
profile_keyring_local: HQ
crypto_policy_name: POL-HQ
crypto_policy_proposal: Prop-HQ
crypto_match_acl_name: VPNACL-HQ
crypto_match_acl_local: 10.2.2.2
crypto_match_acl_remote: 10.1.1.1
transformset_data: "TS-HQ esp-aes 256 esp-sha256-hmac"
cryptomap_name: "CMAP-HQ 10"
cryptomap_peer: 2.2.2.2
cryptomap_tset: TS-HQ
cryptomap_pfs: group19
cryptomap_profile: PROFILE-HQ
cryptomap_match: VPNACL-HQ
interface_name: GigabitEthernet0/0/0
interface_crypto: "crypto map CMAP-HQ"
- script.py
#Imports
import yaml
from jinja2 import Environment, FileSystemLoader
# Load yaml template into memory
config = yaml.load(open('./answer.yaml','r'), Loader=yaml.FullLoader)
# Load jinja template into memory
env = Environment(loader = FileSystemLoader('./'), trim_blocks=True, lstrip_blocks=True)
template = env.get_template('cisco.j2')
# Render template to file
with open("cisco-out.txt",'w') as f:
f.write(template.render(config))
- Output
!Configure GRE
interface Loopback0
ip address 10.1.1.1 255.255.255.0
interface Tunnel100
no shutdown
ip address 10.10.100.1 255.255.255.0
tunnel source Loopback0
tunnel destination 10.2.2.2
tunnel path-mtu-discovery
tunnel protection ipsec profile ikev2_TP
exit
!Configure Ike Policy
crypto ikev2 keyring HQ
peer HQ
address 2.2.2.2
pre-shared-key cisco1234
crypto ikev2 proposal Prop-HQ
encryption aes-cbc-256
integrity sha256
group 19
crypto ikev2 profile PROFILE-HQ
match identity remote address 2.2.2.2 255.255.255.255
authentication local pre-share
authentication remote pre-share
keyring local HQ
crypto ikev2 policy POL-HQ
proposal Prop-HQ
ip access-list extended VPNACL-HQ
permit ip host 10.2.2.2 host 10.1.1.1
permit ip host 10.1.1.1 host 10.2.2.2
crypto ipsec transform-set TS-HQ esp-aes 256 esp-sha256-hmac
! Define Crypto map and Ipsec
crypto map CMAP-HQ 10 ipsec-isakmp
set peer 2.2.2.2
set security-association lifetime seconds 3600
set transform-set TS-HQ
set pfs
set ikev2-profile PROFILE-HQ
match address VPNACL-HQ
interface GigabitEthernet0/0/0
ip address 1.1.1.1 255.255.255.224
negotiation auto
crypto map CMAP-HQ