With help of Ansible programming , we can Automate Nexus switches & ACI , link for videos & Documentation below :
Also find ACI Multi site document below :
Document link :
Lab Examples :
!/usr/bin/env python2
import paramiko # used to create SSH sessions
import time # used to insert pauses in the script
a list of the hosts we wish to access
hosts = [“nxosv1”]
NXOS login details
username = “ansible”
password = “ansible”
Create a new Paramiko SSH connection object
conn = paramiko.SSHClient()
Automatically add SSH hosts keys
conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())
For each host we wish to connect to
for host in hosts:
print “——————–“,host,”——————–“
# create a shell session for multiple commands
conn.connect(host, 22, username, password, look_for_keys=False, allow_agent=False)
remote_shell = conn.invoke_shell()
time.sleep(2)
# receive remote host shell output
output = remote_shell.recv(65535)
# display the output
print output
# send the command "configure terminal"
remote_shell.send("configure terminal\n")
time.sleep(1)
output = remote_shell.recv(65535)
print output
# Enable feature NXAPI
remote_shell.send("feature nxapi\n")
time.sleep(1)
output = remote_shell.recv(65535)
print output
# exit the configuration mode
remote_shell.send("end\n")
time.sleep(1)
output = remote_shell.recv(65535)
print output
time.sleep(1)
# close the SSH session to this host we can re-use the object for the
# next host
conn.close()
[ansible@ansible cli]$ vi enable_feature_cli.py
output = remote_shell.recv(65535)
# display the output
print output
# send the command "configure terminal"
remote_shell.send("configure terminal\n")
time.sleep(1)
output = remote_shell.recv(65535)
print output
# Enable feature NXAPI
remote_shell.send("feature nxapi\n")
time.sleep(1)
output = remote_shell.recv(65535)
print output
# exit the configuration mode
remote_shell.send("end\n")
time.sleep(1)
output = remote_shell.recv(65535)
print output
time.sleep(1)
# close the SSH session to this host we can re-use the object for the
# next host
conn.close()
[ansible@ansible rest]$ vi enable_feature_nxapi.py
“children”: [
{
“fmEntity”: {
“children”: [
{
“fmInterfaceVlan”: {
“attributes”: {
“adminSt”: “enabled”
}
}
}
]
}
}
]
}
}”””
cookie = {'APIC-Cookie': token}
response = requests.post(url, cookies=cookie, data=data, headers={'Content-Type': 'application/json'}, verify=False)
if response.status_code == requests.codes.ok:
print "Interface-VLAN feature enabled successfully on the device!\n"
else:
print "ERROR: Could not enable Interface-VLAN feature!\n"
exit(0)
inventory:
nxosv1
[all:vars]
ansible_connection = local
ansible_ssh_user = ansible
ansible_ssh_pass = ansible
!
[ansible@ansible lab2]$ cat external_vars.yml
vlan30:
id: 30
name: db
!
[ansible@ansible lab2]$ cat external_vars.yml
vlan30:
id: 30
name: db[ansible@ansible lab2]$ cat create_vlans.yml
- name: VLAN creation Playbook
hosts: all # Execute the tasks on all the hosts defined in the inventory file
gather_facts: no vars: # Define variables that will be used in this playbook
vlan20:
id: 20
name: app vars_files: # Import variables defined in an external file- external_vars.yml
- name: Ensure VLAN 10 exists # The configuration values are hardcoded in the script
nxos_vlan:
vlan_id: 10
name: web
transport: nxapi - name: Ensure VLAN 20 exists # The configuration values are defined within the playbook in the vars section
nxos_vlan:
vlan_id: “{{ vlan20.id }}”
name: “{{ vlan20.name }}”
transport: nxapi - name: Ensure VLAN 30 exists # The configuration values are imported from the external_vars file
nxos_vlan:
vlan_id: “{{ vlan30.id }}”
name: “{{ vlan30.name }}”
[ansible@ansible 3.1.loops]$ cat inventory
nxosv1
[all:vars]
ansible_connection = local
ansible_ssh_user = ansible
ansible_ssh_pass = ansible
[ansible@ansible 3.1.loops]$ cat external_vars.yml
vlan_interfaces:
- { name: Vlan10, desc: Web VLAN, ipv4: 10.1.1.1, mask: 24 }
- { name: Vlan20, desc: App VLAN, ipv4: 20.1.1.1, mask: 24 }
- { name: Vlan30, desc: DB VLAN, ipv4: 30.1.1.1, mask: 24 }
[ansible@ansible 3.1.loops]$ cat config_vlan_intf.yml
- name: VLAN Interface Configuration Playbook
hosts: all
gather_facts: no
vars_files:- external_vars.yml
- name: Admin up the VLAN interfaces # The task will execute for each item defined under vlan_interfaces variable
nxos_interface:
interface: “{{ item.name }}”
description: “{{ item.desc }}”
admin_state: up
transport: nxapi
with_items:
“{{ vlan_interfaces }}” - name: IPv4 Address configuration for the VLAN interfaces
nxos_ip_interface:
interface: “{{ item.name }}”
version: v4
addr: “{{ item.ipv4 }}”
mask: “{{ item.mask }}”
transport: nxapi
with_items:
“{{ vlan_interfaces }}”
[ansible@ansible 3.2.conditionals]$ cat inventory
nxosv1
[all:vars]
ansible_connection = local
ansible_ssh_user = ansible
ansible_ssh_pass = ansible[ansible@ansible 3.2.conditionals]$ cat external_vars.yml
physical_interfaces:
- { name: Ethernet1/1 , vlan: 10 }
- { name: Ethernet1/2 , vlan: 10 }
- { name: Ethernet1/3 , vlan: 10 }
- { name: Ethernet1/4 , vlan: 10 }
- { name: Ethernet1/5 , vlan: 10 }
- { name: Ethernet1/6 , vlan: 20 }
- { name: Ethernet1/7 , vlan: 20 }
- { name: Ethernet1/8 , vlan: 20 }
- { name: Ethernet1/9 , vlan: 20 }
- { name: Ethernet1/10 , vlan: 20 }
- { name: Ethernet1/11 , vlan: 30 }
- { name: Ethernet1/12 , vlan: 30 }
- { name: Ethernet1/13 , vlan: 30 }
- { name: Ethernet1/14 , vlan: 30 }
- { name: Ethernet1/15 , vlan: 30 }[ansible@ansible 3.2.conditionals]$
[ansible@ansible 3.2.conditionals]$ cat set_interface_descr.yml
- name: Playbook for setting interface descriptions
hosts: all
gather_facts: no
vars_files:- external_vars.yml
- name: Set the physical ports descriptions for Web interfaces
nxos_interface:
interface: “{{ item.name }}”
description: Web Vlan
transport: nxapi
with_items: # This task will execute for each item defined under physical_interfaces variable
“{{ physical_interfaces }}” # only when the vlan value of each item defined is 10.
when:- item.vlan == 10
- name: Set the physical ports descriptions for App interfaces
nxos_interface:
interface: “{{ item.name }}”
description: App Vlan
transport: nxapi
with_items:
“{{ physical_interfaces }}”
when:- item.vlan == 20
- name: Set the physical ports descriptions for DB interfaces
nxos_interface:
interface: “{{ item.name }}”
description: DB Vlan
transport: nxapi
with_items:
“{{ physical_interfaces }}”
when:- item.vlan == 30
[ansible@ansible 3.3.templates]$ cat inventory
nxosv1
[all:vars]
ansible_connection = local
ansible_ssh_user = ansible
ansible_ssh_pass = ansible[ansible@ansible 3.3.templates]$ cat interface_template.yml
- name: Interface Configuration Playbook
hosts: all
gather_facts: no
vars:
interface: Vlan10 tasks: - name: Get interface details # Fetch Vlan10 interface details and store it in interface_facts variable
nxos_command:
commands: “show ip interface {{ interface }}”
transport: nxapi
register: interface_facts Parse through the JSON and store only the interface related information in fmt_int variable - set_fact: fmt_int=”{{ interface_facts.stdout[0].TABLE_intf.ROW_intf }}” Create a new file using the intf_template.j2 template and substituting the variable values
- template: src=./intf_template.j2 dest=./intf-{{inventory_hostname}}.txt[ansible@ansible 3.3.templates]$ cat interface_ in
interface_json.yml intf-nxosv1.json inventory
interface_template.yml intf_template.j2
[ansible@ansible 3.3.templates]$ cat intf-nxosv1.json
Interface Details:
| Interface | Prefix | Subnet | Mask |
| Vlan10 | 10.1.1.1 | 10.1.1.0 | 24 |
—————————————————[ansible@ansible 3.3.templates]$ cat intf_template.j2
Interface Details:
| Interface | Prefix | Subnet | Mask |
| {{ interface }} | {{ fmt_int.prefix }} | {{ fmt_int.subnet }} | {{ fmt_int.masklen }} |
———————————————[ansible@ansible 3.3.templates]$ cat interface_json.yml
- name: Playbook for getting the Vlan10 interface details in the JSON format
hosts: all
gather_facts: no tasks: - name: Get interface details # Fetch Vlan10 interface details and store it in interface_facts variable
nxos_command:
commands: “show ip interface Vlan10”
transport: nxapi
register: interface_facts Copy the contents of the interface_facts variable into a json file - local_action: copy content={{ interface_facts }} dest=./intf-{{inventory_hostname}}.json[ansible@ansible 3.3.templates]$
apic
[ansible@ansible lab1]$ cat create_tenant.yml
- name: playbook for testing tenants
hosts: apic
connection: local
gather_facts: no tasks: - name: Add a new tenant
aci_tenant:
hostname: apic
username: admin
password: C1sco12345
tenant: ACILab
description: Test tenant
state: present
validate_certs: false
[ansible@ansible lab2]$ cat inventory
apic user=admin pass=C1sco12345
[ansible@ansible lab2]$ cat external_vars.yml
vrf:
name: ACILab_VRF
description: A sample VRF used for ACILab
tenant: ACILab
bd:
name: ACILab_BD1
vrf: ACILab_VRF
tenant: ACILab[ansible@ansible lab2]$ cat create_vrf_bd.yml
- name: playbook for creating bd
hosts: apic
connection: local
gather_facts: no
vars_files:- external_vars.yml
- name: Ensure VRF for tenant exists
aci_vrf:
vrf: “{{ vrf.name }}”
description: “{{ vrf.description }}”
tenant: “{{ vrf.tenant }}”
state: present
host: “{{ inventory_hostname }}”
username: “{{ user }}”
password: “{{ pass }}”
validate_certs: false - name: Ensure Bridge Domain 1 exists
aci_bd:
bd: “{{ bd.name }}”
vrf: “{{ bd.vrf }}”
tenant: “{{ bd.tenant }}”
state: present
host: “{{ inventory_hostname }}”
username: “{{ user }}”
password: “{{ pass }}”
validate_certs: false
[ansible@ansible lab3]$ cat inventory
apic user=admin pass=C1sco12345
[ansible@ansible lab3]$ cat create_contracts.yml
- name: playbook for creating contracts
hosts: apic
connection: local
gather_facts: no tasks:- name: ensure contracts exist aci_contract: name: “{{ item }}” tenant: ACILab host: “{{ inventory_hostname }}” username: “{{ user }}” password: “{{ pass }}” validate_certs: false with_items:
- Web_Con
- App_Con
- DB_Con
- name: ensure contracts exist aci_contract: name: “{{ item }}” tenant: ACILab host: “{{ inventory_hostname }}” username: “{{ user }}” password: “{{ pass }}” validate_certs: false with_items:
[ansible@ansible lab4]$ cat inventory
apic user=admin pass=C1sco12345
[ansible@ansible lab4]$ cat external_vars.yml
epg: Web_EPG
bd: ACILab_BD1
ap: 3Tier_App
tenant: ACILab[ansible@ansible lab4]$ cat create_epg.yml
- name: playbook for creating bd
hosts: apic
connection: local
gather_facts: no
vars_files:- external_vars.ymltasks:
- name: create app network profile
aci_ap:
ap: “{{ ap }}”
tenant: “{{ tenant }}”
state: present
hostname: “{{ inventory_hostname }}”
username: “{{ user }}”
password: “{{ pass }}”
validate_certs: false - name: ensure web epg exists
aci_epg:
epg: “{{ epg }}”
bd: “{{ bd }}”
ap: “{{ ap }}”
tenant: “{{ tenant }}”
state: present
hostname: “{{ inventory_hostname }}”
username: “{{ user }}”
password: “{{ pass }}”
validate_certs: false
[ansible@ansible lab4]$
ACI Multi site document :
Prepare your DC to Crack an Interview :
