Data Center Automation via Ansible

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
    tasks:
  • 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
    tasks:
  • 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
    tasks:
  • 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
    tasks:
  • 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

[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 :

Leave a Reply

Your email address will not be published. Required fields are marked *