Ansible
Execution

Step 1 - Create ansible configuration file

A good practice is to setup a configuration file for Ansible. This file is called ansible.cfg . Some of the important configuration items for the ansible.cfg file is the definition of callbacks that allow to expand the playbook output which is very useful when troubleshooting.


cat << EOF > /home/pod04/ltrdcn-3225/ansible/playbooks/aci/ansible.cfg 
[defaults]
callback_whitelist=ansible.posix.timer,ansible.posix.profile_tasks,ansible.posix.profile_roles
callbacks_enabled=ansible.posix.timer,ansible.posix.profile_tasks,ansible.posix.profile_roles
callback_result_format=yaml
EOF

Step 2 - Run the Ansible playbook

To execute an Ansible playbook you simply just use ansible-playbook. You are going to use our own host file, so you must specify -i hosts.yml, where -i is for inventory and hosts is the inventory file name. Lastly, you must specify the playbook file, site.yml.

In the terminal window in the ansible directory you should run the following command:


cd  ~/ltrdcn-3225/ansible/playbooks/aci
ansible-playbook -i hosts.yml site.yml

This command should produce the following output:

PLAY [APIC Tenant Configuration playbook] *******************************************************************************************************************************************************************************

TASK [apic : CREATE ACI TENANT VRF(S)] **********************************************************************************************************************************************************************************
Saturday 08 February 2025  17:53:37 -0500 (0:00:00.016)       0:00:00.016 ***** 
Saturday 08 February 2025  17:53:37 -0500 (0:00:00.015)       0:00:00.015 ***** 
changed: [apic -> localhost] => (item=[{'name': 'aciproglab04', 'vrfs': [{'name': 'POD04_vrf_1', 'bridge_domains': [{'name': 'web', 'description': 'POD04 Web front end Bridge Domain', 'subnet': {'name': 'POD04_web_subnet', 'description': 'POD04 Subnet for Web front end', 'gateway': '10.100.04.1', 'mask': 24}}, {'name': 'database', 'description': 'POD04 Database Bridge Domain', 'subnet': {'name': 'POD04_db_subnet', 'description': 'POD04 Subnet for Database Bridge Domain', 'gateway': '10.100.104.1', 'mask': 24}}]}, {'name': 'POD04_vrf_2'}], 'app_profiles': [{'name': 'POD04_APP', 'description': 'POD04 Application Profile', 'endpoint_groups': [{'name': 'web', 'bd': 'web', 'description': 'POD04 WEB EPG'}, {'name': 'database', 'bd': 'database', 'description': 'POD04 Database EPG'}]}]}, {'name': 'POD04_vrf_1', 'bridge_domains': [{'name': 'web', 'description': 'POD04 Web front end Bridge Domain', 'subnet': {'name': 'POD04_web_subnet', 'description': 'POD04 Subnet for Web front end', 'gateway': '10.100.04.1', 'mask': 24}}, {'name': 'database', 'description': 'POD04 Database Bridge Domain', 'subnet': {'name': 'POD04_db_subnet', 'description': 'POD04 Subnet for Database Bridge Domain', 'gateway': '10.100.104.1', 'mask': 24}}]}])
changed: [apic -> localhost] => (item=[{'name': 'aciproglab04', 'vrfs': [{'name': 'POD04_vrf_1', 'bridge_domains': [{'name': 'web', 'description': 'POD04 Web front end Bridge Domain', 'subnet': {'name': 'POD04_web_subnet', 'description': 'POD04 Subnet for Web front end', 'gateway': '10.100.04.1', 'mask': 24}}, {'name': 'database', 'description': 'POD04 Database Bridge Domain', 'subnet': {'name': 'POD04_db_subnet', 'description': 'POD04 Subnet for Database Bridge Domain', 'gateway': '10.100.104.1', 'mask': 24}}]}, {'name': 'POD04_vrf_2'}], 'app_profiles': [{'name': 'POD04_APP', 'description': 'POD04 Application Profile', 'endpoint_groups': [{'name': 'web', 'bd': 'web', 'description': 'POD04 WEB EPG'}, {'name': 'database', 'bd': 'database', 'description': 'POD04 Database EPG'}]}]}, {'name': 'POD04_vrf_2'}])

TASK [apic : GENERATE BRIDGE DOMAIN(S)] *********************************************************************************************************************************************************************************
Saturday 08 February 2025  17:53:38 -0500 (0:00:01.572)       0:00:01.589 ***** 
Saturday 08 February 2025  17:53:38 -0500 (0:00:01.572)       0:00:01.588 ***** 
ok: [apic]

TASK [apic : CREATE BRIDGE DOMAIN(S)] ***********************************************************************************************************************************************************************************
Saturday 08 February 2025  17:53:39 -0500 (0:00:00.057)       0:00:01.646 ***** 
Saturday 08 February 2025  17:53:39 -0500 (0:00:00.057)       0:00:01.645 ***** 
changed: [apic -> localhost] => (item={'tenant': 'aciproglab04', 'vrf': 'POD04_vrf_1', 'bd': {'name': 'web', 'desc': 'POD04 Web front end Bridge Domain', 'subnet': {'name': 'POD04_web_subnet', 'desc': 'POD04 Subnet for Web front end', 'gateway': '10.100.04.1', 'mask': 24}}})
changed: [apic -> localhost] => (item={'tenant': 'aciproglab04', 'vrf': 'POD04_vrf_1', 'bd': {'name': 'database', 'desc': 'POD04 Database Bridge Domain', 'subnet': {'name': 'POD04_db_subnet', 'desc': 'POD04 Subnet for Database Bridge Domain', 'gateway': '10.100.104.1', 'mask': 24}}})

TASK [apic : CREATE SUBNET(S) FOR BRIDGE DOMAIN(S)] *********************************************************************************************************************************************************************
Saturday 08 February 2025  17:53:40 -0500 (0:00:01.561)       0:00:03.207 ***** 
Saturday 08 February 2025  17:53:40 -0500 (0:00:01.561)       0:00:03.206 ***** 
changed: [apic -> localhost] => (item={'tenant': 'aciproglab04', 'vrf': 'POD04_vrf_1', 'bd': {'name': 'web', 'desc': 'POD04 Web front end Bridge Domain', 'subnet': {'name': 'POD04_web_subnet', 'desc': 'POD04 Subnet for Web front end', 'gateway': '10.100.04.1', 'mask': 24}}})
changed: [apic -> localhost] => (item={'tenant': 'aciproglab04', 'vrf': 'POD04_vrf_1', 'bd': {'name': 'database', 'desc': 'POD04 Database Bridge Domain', 'subnet': {'name': 'POD04_db_subnet', 'desc': 'POD04 Subnet for Database Bridge Domain', 'gateway': '10.100.104.1', 'mask': 24}}})

TASK [apic : CREATE TENANT APPLICATION PROFILE(S)] **********************************************************************************************************************************************************************
Saturday 08 February 2025  17:53:42 -0500 (0:00:01.521)       0:00:04.729 ***** 
Saturday 08 February 2025  17:53:42 -0500 (0:00:01.521)       0:00:04.727 ***** 
changed: [apic -> localhost] => (item=[{'name': 'aciproglab04', 'vrfs': [{'name': 'POD04_vrf_1', 'bridge_domains': [{'name': 'web', 'description': 'POD04 Web front end Bridge Domain', 'subnet': {'name': 'POD04_web_subnet', 'description': 'POD04 Subnet for Web front end', 'gateway': '10.100.04.1', 'mask': 24}}, {'name': 'database', 'description': 'POD04 Database Bridge Domain', 'subnet': {'name': 'POD04_db_subnet', 'description': 'POD04 Subnet for Database Bridge Domain', 'gateway': '10.100.104.1', 'mask': 24}}]}, {'name': 'POD04_vrf_2'}], 'app_profiles': [{'name': 'POD04_APP', 'description': 'POD04 Application Profile', 'endpoint_groups': [{'name': 'web', 'bd': 'web', 'description': 'POD04 WEB EPG'}, {'name': 'database', 'bd': 'database', 'description': 'POD04 Database EPG'}]}]}, {'name': 'POD04_APP', 'description': 'POD04 Application Profile', 'endpoint_groups': [{'name': 'web', 'bd': 'web', 'description': 'POD04 WEB EPG'}, {'name': 'database', 'bd': 'database', 'description': 'POD04 Database EPG'}]}])

TASK [apic : GENERATE ENDPOINT GROUP(S)] ********************************************************************************************************************************************************************************
Saturday 08 February 2025  17:53:43 -0500 (0:00:01.029)       0:00:05.758 ***** 
Saturday 08 February 2025  17:53:43 -0500 (0:00:01.029)       0:00:05.757 ***** 
ok: [apic]

TASK [apic : CREATE EPG(S)] *********************************************************************************************************************************************************************************************
Saturday 08 February 2025  17:53:43 -0500 (0:00:00.058)       0:00:05.816 ***** 
Saturday 08 February 2025  17:53:43 -0500 (0:00:00.058)       0:00:05.815 ***** 
changed: [apic -> localhost] => (item={'tenant': 'aciproglab04', 'ap': 'POD04_APP', 'bd': 'web', 'epg': 'web', 'desc': 'POD04 WEB EPG'})
changed: [apic -> localhost] => (item={'tenant': 'aciproglab04', 'ap': 'POD04_APP', 'bd': 'database', 'epg': 'database', 'desc': 'POD04 Database EPG'})

PLAY RECAP **************************************************************************************************************************************************************************************************************
apic                       : ok=7    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


PLAYBOOK RECAP **********************************************************************************************************************************************************************************************************
Playbook run took 0 days, 0 hours, 0 minutes, 7 seconds


TASKS RECAP *************************************************************************************************************************************************************************************************************
Saturday 08 February 2025  17:53:44 -0500 (0:00:01.565)       0:00:07.382 ***** 
=============================================================================== 
apic : CREATE ACI TENANT VRF(S) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1.57s
apic : CREATE EPG(S) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1.57s
apic : CREATE BRIDGE DOMAIN(S) ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1.56s
apic : CREATE SUBNET(S) FOR BRIDGE DOMAIN(S) --------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1.52s
apic : CREATE TENANT APPLICATION PROFILE(S) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1.03s
apic : GENERATE ENDPOINT GROUP(S) -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 0.06s
apic : GENERATE BRIDGE DOMAIN(S) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 0.06s

ROLES RECAP *************************************************************************************************************************************************************************************************************
Saturday 08 February 2025  17:53:44 -0500 (0:00:01.565)       0:00:07.381 ***** 
=============================================================================== 
apic -------------------------------------------------------------------- 7.37s
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
total ------------------------------------------------------------------- 7.37s

And the ACI fabric is now configured. If you run the command again, you will notice that Ansible indicates that the setting is ok:. Which means that the configuration is already at the intended state that you set.

You can re-run the scripts as many times as you wish and Ansible will validate that the configuration is setup this way. If you modify the script in any way, like changing the subnet IP or the mask you will notice that it will indicate changed as it modifies that configuration.

You can also run the playbook in verbose mode by adding the -v option. This will provide more information about the execution of the playbook.


ansible-playbook -i hosts.yml site.yml -v

In the case of ACI this even includes the datastructures that are being sent to the APIC. Since we are using the YAML callback, the data is presented in YAML format.

[TRIM]
TASK [apic : CREATE EPG(S)] *********************************************************************************************************************************************************************************************
Saturday 08 February 2025  18:04:06 -0500 (0:00:00.053)       0:00:05.322 ***** 
Saturday 08 February 2025  18:04:06 -0500 (0:00:00.053)       0:00:05.321 ***** 
ok: [apic -> localhost] => (item={'tenant': 'aciproglab04', 'ap': 'POD04_APP', 'bd': 'web', 'epg': 'web', 'desc': 'POD04 WEB EPG'}) => 
    ansible_loop_var: item
    changed: false
    current:
    -   fvAEPg:
          attributes:
            annotation: orchestrator:ansible
            descr: POD04 WEB EPG
            dn: uni/tn-aciproglab04/ap-POD04_APP/epg-web
            exceptionTag: ''
            floodOnEncap: disabled
            fwdCtrl: ''
            hasMcastSource: 'no'
            isAttrBasedEPg: 'no'
            matchT: AtleastOne
            name: web
            nameAlias: ''
            pcEnfPref: unenforced
            prefGrMemb: exclude
            prio: unspecified
            shutdown: 'no'
            userdom: ':all:common:aciproglab04:'
[TRIM]

Step 3 - Connect to APIC to see the configuration

Click on the following link to connect to the APIC. The credentials for your login are:

  • Username: aciproglab04
  • Password: cisco.123

Note

You may need to close the Meet Cisco APIC x.x(x) by clicking the Let's Go! button, then the Get Started button


Once you logged to the APIC, you will be placed in the System Health page.

Follow these steps to get to your Tenant aciproglab04 :

  1. Click on Tenants
  2. On the seach box enter aciproglab04



The first thing you should notice is the nice message that ACI is providing to the user to highlight how this object was created via Ansible. Then you can verify under the summary page the objects created via the Ansible Playbook which includes Application EPGs, VRFfs, Bridge Domains.

You should notice from the summary page the numbers of Application EPGs, VRFfs, Bridge Domains created via Ansible. You can expand the application profiles and networking menus on the left to further see this configuration if desired.