Files
taodengandClaude Fable 5 7e9a175ce6 Initial public release — aci-sim v0.16.0
aci-sim is a stateful REST simulator of a 2-site Cisco ACI fabric
(per-site APIC + ND/NDO management planes) — for testing ACI automation
(Ansible cisco.aci / cisco.mso, aci-py, custom REST clients) and CI gates
without real hardware.

Highlights: APIC + NDO REST surface served from one in-memory MIT built
from a declarative topology.yaml; port mode + sandbox (real per-device IPs
on :443) run modes; LLDP/CDP neighbor visibility; NDO->APIC deploy mirror
(multi-site templates materialize onto the target sites' APIC stores);
real-APIC fvBD default attributes; file-backed state save/restore; an
`aci-sim` CLI (validate/show/graph/run/new/init/lldp); and an 888-test suite.

History squashed for the public release.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 20:06:36 +10:00

3.7 KiB

Ansible cisco.aci examples

This directory contains a small, validated cisco.aci playbook set that exercises aci-sim the same way you'd exercise a real APIC: create a tenant/VRF/BD/AP/EPG, confirm idempotency (re-apply reports no change), then tear it all down.

Prerequisites

pip install ansible
ansible-galaxy collection install cisco.aci

The sim must be running first — see the main README.md §4 Usage/Quickstart.

Files

File Purpose
inventory.ini Example inventory — one host (sim-apic-a) pointed at the sim, with connection vars set as group vars.
smoke.yml Creates SMOKE-TN1 (tenant) → SMOKE-VRF1 (VRF) → SMOKE-BD1 (BD) → SMOKE-AP1 (AP) → SMOKE-EPG1 (EPG), then re-applies every task and asserts changed=false on the second pass.
teardown.yml Removes everything smoke.yml created, in reverse dependency order, then asserts that deleting an already-absent tenant is idempotent (changed=false).

Running against port mode (default)

Port mode is what bash scripts/run.sh starts: one shared bind address (127.0.0.1 by default), APIC site A on :8443.

# from the repo root, in one terminal:
bash scripts/run.sh

# in another terminal:
cd examples/ansible
ansible-playbook -i inventory.ini smoke.yml
ansible-playbook -i inventory.ini teardown.yml

inventory.ini already points sim-apic-a at 127.0.0.1:8443 with admin/cisco and validate_certs=false (the sim's TLS cert is self-signed — see main README.md §5 Configuration). If you changed APIC_A_PORT or SIM_USERNAME/SIM_PASSWORD, override the matching aci_port/aci_username/aci_password host/group vars.

Running against sandbox mode

Sandbox mode (sudo bash scripts/sandbox-up.sh) gives each APIC a real IP on the standard port 443 — no port number, like real gear. Point the inventory at that IP instead and drop the port override (or set it to 443 explicitly):

sudo bash scripts/sandbox-up.sh   # from the repo root

Edit inventory.ini (or pass -e overrides on the command line) so ansible_host/aci_hostname is the site's mgmt_ip from topology.yaml (e.g. 10.192.0.11 for LAB1's default topology) and aci_port is 443:

cd examples/ansible
ansible-playbook -i inventory.ini smoke.yml \
  -e aci_hostname=10.192.0.11 -e aci_port=443
ansible-playbook -i inventory.ini teardown.yml \
  -e aci_hostname=10.192.0.11 -e aci_port=443

Tear the sandbox down when done:

sudo bash scripts/sandbox-down.sh

What "idempotent" means here

cisco.aci modules are idempotent at the client level: they GET the existing object, diff it against the desired state, and only issue a POST/DELETE if something actually differs. smoke.yml's second pass and teardown.yml's re-delete both assert changed: false, proving the round trip (create → GET-existing → diff → no-op) behaves the same against aci-sim as it would against a real APIC — this is exactly the GET-before-write contract documented in docs/CONTRACT.md §11 (api_call() treats any non-200 GET as fatal, so a not-yet-created object's GET must be 200 {"imdata":[],"totalCount":"0"}, never 404).

Troubleshooting

  • Connection refused — the sim isn't running, or you're pointed at the wrong host/port for the run mode you started (port mode vs. sandbox mode).
  • fatal: APIC Error 103: Unable to find the object specified on the very first task — this was a real bug class this sim's PR-9 fixed (GET on a nonexistent DN used to 404); if you see it, you're likely running an older checkout — update to the latest main.
  • SSL errors — make sure validate_certs: false (the sim's certificate is self-signed; see scripts/gen_certs.sh).