Testing Arista AVD with GNS3 and EOS


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…

gns3 avd ceos 1

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.