Cisco ACI Automation With Ansible: CSV-to-ACI Ansible loops

When we need to automate Cisco ACI with Ansible, CSV-to-ACI Ansible loops become essential because CSV files are the simplest input format for “flat” data. In this guide, we treat CSV files as the handoff between teams and use Ansible loops to turn CSV rows into real ACI objects, ensuring they are clean, reviewable, and idempotent.

Cisco ACI Variable Files (CSV vs. YAML)

CSV is a lightweight file that can be used for passing intent and variables from other teams to network engineers. It’s friendly to Excel, easy to validate, and perfect for bulk creation of simple, repeatable objects.

YAML is better suited for very nested intents, but CSV shines for “flat tables” such as Cisco ACI tenants, VRFs, BDs, EPGs, VLANs, and interfaces. I recommend using CSV files for ACI variables input when:

  • You’re deploying many similar ACI objects quickly.
  • The hand-off comes from non-automation teams (Excel users).

Below, we have YAML and CSV files that contain the same variables with their attributes. We will use the CSV file (Leaf_Interface_Profiles.csv) in the upcoming examples.

A YAML snippet lists interface profiles: Leaf1-IntPrf (profile name Leaf1-Prf, description Leaf1 Interface Profile), Leaf2-IntPrf (profile name Leaf2-Prf, description Leaf2 Interface Profile), and Leaf3-IntPrf (profile name Leaf3-Prf, description Leaf3 Interface Profile).
A YAML Snippet Lists three Cisco ACI Interface Profiles
A CSV spreadsheet displays three columns: int_prf_name, leaf_prf_name, and description. Rows 2–4 list profiles: Leaf1–IntPrf, Leaf2–IntPrf, Leaf3–IntPrf; matching leaf_prf_name and descriptions (Leaf1 Interface Profile, etc.). This image is used as an example to demonstrate the "CSV-to-ACI Ansible loops: Cisco ACI Automation With Ansible"
A CSV Spreadsheet Displays Three Cisco ACI Interface Profiles
A table with three columns: int_prf_name, leaf_prf_name, and description. Three rows list Leaf1-IntPrf, Leaf1-Prf, Leaf1 Interface Profile; Leaf2-IntPrf, Leaf2-Prf, Leaf2 Interface Profile; and Leaf3-IntPrf, Leaf3-Prf, Leaf3 Interface Profile.
A CSV File Showed as a TXT File

When using CSV files, we need to ensure the following: (otherwise, an error will be raised)

  • The CSV headers are case-sensitive, so the header names have to match the references in the loop.
  • Ensure there is no whitespace in the CSV headers and ACI object names.

The CSV Ansible Module

The community.general.read_csv Ansible module reads a CSV file and returns a list of dictionaries that we can loop over. Each dictionary’s keys are the CSV headers.

Example:- Using the Leaf_Interface_Profiles.csv file mentioned above.

---
<snip>
vars:
csv_path: "./Leaf_Interface_Profiles.csv"
<snip>
tasks:
- name: Read CSV values as a list of dictionaries
community.general.read_csv:
path: "{{ csv_path }}"
register: new_interface_profiles
<snip>
  • name: a human-readable label for the run output.
  • community.general.read_csv: runs the CSV module (not a lookup) that parses the file.
  • path: the path of the CSV file with respect to the playbook file; in the above example, they both are in the same directory. (You can provide the path directly, but for reusability, it is better to make it portable using a variable such as csv_path)
  • register: saves the module’s return object into a variable (new_interface_profiles) so you can use it later in the ACI modules (looping).

The module returns a JSON object. Its most useful field is the “list“, which is a list of dictionaries; one dict per CSV row. Each dictionary’s keys are exactly the CSV headers (case-sensitive), and the values are strings.

The community.general.read_csv module is part of the general community, and it is most likely to be part of the Ansible core installation. If, for any reason, you need to install it, use the command: ansible-galaxy collection install community.general

The CSV Parsed Data (How .list looks)

TASK [Parse CSV Rows As A List of Dicts] ****************************************************************************
ok: [apic-1] => {
"new_interfaces.list": [
{
"description": "Leaf1 Interface Profile",
"int_prf_name": "Leaf1-IntPrf",
"leaf_prf_name": "Leaf1-Prf"
},
{
"description": "Leaf2 Interface Profile",
"int_prf_name": "Leaf2-IntPrf",
"leaf_prf_name": "Leaf2-Prf"
},
{
"description": "Leaf3 Interface Profile",
"int_prf_name": "Leaf3-IntPrf",
"leaf_prf_name": "Leaf3-Prf"
}
]
}

Using the (.list) in Ansible Loops

Each item in the new_interfaces.list is a single row (a dict) from the CSV file. You reference columns by the header name:

---
tasks:
<snip>
- name: "Add New Leaf Interface Profiles"
cisco.aci.aci_interface_policy_leaf_profile:
host: "{{ ansible_host }}"
username: "{{ user }}"
password: "{{ pass }}"
state: "present"
validate_certs: false
interface_profile: "{{ item.int_prf_name }}"
description: "{{ item.description }}"
loop: "{{ new_interfaces.list }}"

- name: "Associating Interface Profiles to Leaf Profiles"
cisco.aci.aci_interface_selector_to_switch_policy_leaf_profile:
host: "{{ ansible_host }}"
username: "{{ user }}"
password: "{{ pass }}"
state: "present"
validate_certs: false
leaf_profile: "{{ item.leaf_prf_name }}"
interface_profile_name: "{{ item.int_prf_name }}"
loop: "{{ new_interfaces.list }}"

Practical Example (LAB Demo)

In this Lab demo, we will load the CSV file using the community.general.read_csv module, loop through the CSV records, create ACI objects, and verify them in APIC.

Need Comprehensive Cisco ACI Content?

I hope this article was helpful. If you want comprehensive content about Cisco ACI, check out my Udemy course:

Cisco Data Centers | ACI Core

Cisco Data Centers | ACI Automation With Ansible

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Scroll to Top