Arista AVD (Architect, Validate, Deploy) – https://avd.arista.com – is a powerful tool that brings network architecture into the world of Infrastructure-as-Code. I wanted to try it out in a lab setting and see how it works in a non-standard environment.
Since my go-to lab tool is GNS3 with Arista cEOS images — while the AVD documentation is primarily built around vEOS — I ran into a few issues. After some troubleshooting, I got it working, and I’d like to share the process here.
This is not a full deployment guide for AVD. Instead, I’ll walk you through the setup I used to make it work in a test environment using GNS3 and cEOS images.
Prerequisites
Make sure your Ansible host has at least 2048MB of memory — I encountered memory-related errors that were otherwise unrelated to the steps below.
Environment Setup
Make sure you’re in your user’s home directory. In my case, the user is debian on the Ansible host.
cd ~ python3 -m venv .avd source /home/debian/.avd/bin/activate pip install "pyavd[ansible]" ansible-galaxy collection install arista.avd
The above will activate a virtual environment for pip use and install the needed packages. The Ansible collections will under .ansible in the home directory.
Copy the AVD example configurations to a work directory (I chose avd)
mkdir avd cd avd ansible-playbook arista.avd.install_examples
Make sure you are now be in the ~/avd/ directory to avoid future errors.
(.avd) debian@debian:~/avd$ pwd /home/debian/avd
You should see the following directories:
ls -la total 40 drwxr-xr-x 10 debian debian 4096 Jul 24 17:25 . drwxr-xr-x 7 debian debian 4096 Jul 24 17:23 .. drwxr-xr-x 7 debian debian 4096 Jul 24 17:25 campus-fabric drwxr-xr-x 2 debian debian 4096 Jul 24 17:25 common drwxr-xr-x 8 debian debian 4096 Jul 24 17:24 cv-pathfinder drwxr-xr-x 7 debian debian 4096 Jul 24 17:24 dual-dc-l3ls drwxr-xr-x 7 debian debian 4096 Jul 24 17:25 isis-ldp-ipvpn drwxr-xr-x 7 debian debian 4096 Jul 24 17:23 l2ls-fabric drwxr-xr-x 7 debian debian 4096 Jul 24 17:24 single-dc-l3ls drwxr-xr-x 7 debian debian 4096 Jul 24 17:24 single-dc-l3ls-ipv6
Project: single-dc-l3ls
I chose to use the single-dc-l3ls example (https://avd.arista.com/5.5/ansible_collections/arista/avd/examples/single-dc-l3ls/index.html)
My GNS3 topology follows exactly the scenario above in terms of switch number, naming, connections, etc…

Tweak Ansible Config
By default, Ansible only warns when encountering duplicate keys in YAML files. Arista recommends treating this as an error to ensure cleaner configurations.
Update the ansible.cfg in the project folder:
sed -i '/^jinja2_extensions/a\duplicate_dict_key=error' single-dc-l3ls/ansible.cfg
Verify the result:
cat single-dc-l3ls/ansible.cfg [defaults] inventory=inventory.yml jinja2_extensions = jinja2.ext.loopcontrols,jinja2.ext.do,jinja2.ext.i18n duplicate_dict_key=error
Management Interface Considerations: vEOS vs cEOS
AVD examples assume vEOS images, where the management interface is Management1.
In GNS3 with cEOS, the interface varies. If you followed Arista’s guide for cEOS image installation on GNS3 (https://arista.my.site.com/AristaCommunity/s/article/veos-ceos-gns3-labs) then your management interface is likely Ethernet21.
That’s what I used in my setup.
Initial Configurations for GNS3
Before running the playbook, the management connections must be in place and Ansible host reachable — otherwise, the playbook will not work.
Initial configurations are stored here:
ls -la single-dc-l3ls/switch-basic-configurations/ total 40 drwxr-xr-x 2 debian debian 4096 Jul 24 21:18 . drwxr-xr-x 7 debian debian 4096 Jul 24 21:24 .. -rw-rw-r-- 1 debian debian 978 Jul 24 21:18 dc1-leaf1a-basic-configuration.txt -rw-rw-r-- 1 debian debian 978 Jul 24 21:18 dc1-leaf1b-basic-configuration.txt -rw-rw-r-- 1 debian debian 978 Jul 24 21:18 dc1-leaf1c-basic-configuration.txt -rw-rw-r-- 1 debian debian 978 Jul 24 21:18 dc1-leaf2a-basic-configuration.txt -rw-rw-r-- 1 debian debian 978 Jul 24 21:18 dc1-leaf2b-basic-configuration.txt -rw-rw-r-- 1 debian debian 978 Jul 24 21:18 dc1-leaf2c-basic-configuration.txt -rw-rw-r-- 1 debian debian 977 Jul 24 21:18 dc1-spine1-basic-configuration.txt -rw-rw-r-- 1 debian debian 977 Jul 24 21:18 dc1-spine2-basic-configuration.txt
Update the management interface to Ethernet21:
sed -i 's/Management1/Ethernet21/g' single-dc-l3ls/switch-basic-configurations/*.txt
Copy the configs to each switch in the GNS3 lab and make sure they can ping the Ansible host.
Modify inventory.yml
Update the Ansible host IP to match your topology. In my setup, it’s in the 172.16.1.0/24 range:
nano /home/debian/avd/single-dc-l3ls/inventory.yml
Change:
ansible_host: 192.168.1.12
To:
ansible_host: 172.16.1.254
Everything else can remain unchanged if you’re following the same example from Arista’s site.
Update Playbook for Management Interface
The intended/configs/ files also reference Management1. These need to be changed to Ethernet21.
ls -la single-dc-l3ls/intended/configs/ total 80 drwxr-xr-x 2 debian debian 4096 Jul 24 21:18 . drwxr-xr-x 4 debian debian 4096 Jul 24 21:18 .. -rw-rw-r-- 1 debian debian 9098 Jul 24 21:18 dc1-leaf1a.cfg -rw-rw-r-- 1 debian debian 9098 Jul 24 21:18 dc1-leaf1b.cfg -rw-rw-r-- 1 debian debian 1942 Jul 24 21:18 dc1-leaf1c.cfg -rw-rw-r-- 1 debian debian 9106 Jul 24 21:18 dc1-leaf2a.cfg -rw-rw-r-- 1 debian debian 9110 Jul 24 21:18 dc1-leaf2b.cfg -rw-rw-r-- 1 debian debian 1942 Jul 24 21:18 dc1-leaf2c.cfg -rw-rw-r-- 1 debian debian 4187 Jul 24 21:18 dc1-spine1.cfg -rw-rw-r-- 1 debian debian 4191 Jul 24 21:18 dc1-spine2.cfg
Update the management interface:
sed -i 's/Management1/Ethernet21/g' single-dc-l3ls/intended/configs/*.cfg
Also, make Ethernet21 a Layer 3 port:
sed -i '/^interface Ethernet21$/a\ no switchport' single-dc-l3ls/intended/configs/*.cfg
Run the Playbook
Now you’re ready to deploy.
cd single-dc-l3ls ansible-playbook deploy.yml
Expected output:
PLAY RECAP ********************************************************************* dc1-leaf1a : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 dc1-leaf1b : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 dc1-leaf1c : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 dc1-leaf2a : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 dc1-leaf2b : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 dc1-leaf2c : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 dc1-spine1 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 dc1-spine2 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Make sure unreachable, failed, and skipped are all 0 — that’s your confirmation that everything went smoothly.
Summary
While AVD examples are designed around vEOS, it’s perfectly possible to adapt it for cEOS in GNS3 with a few changes. The most important steps involve:
- Updating interface names
- Ensuring management connectivity stays up
- Modifying inventory and config files accordingly
This lab-friendly workflow lets you explore AVD’s potential without dedicated hardware or CVP.