Sustainable, Declarative Datacenter Switch Configuration with Arista EOS

In part one of this post, we examined the linux system on the DCS-7048T-A, and got root ssh access directly to bash.

tldr, this is pre-systemd fedora with an ephemeral / filesystem, but we can land arbitrary init script /mnt/flash/rc.eos, and all 52 interfaces are indeed presented to the os and visible with ip link et al.

While I have only EOS 4.15 running on trash, EOS today remains much the same; so this approach should be largely transferable.


Since this is just linux, we can manage this thing like any other linux box on the network; and so i present arista-ansible. This project enables templating of startup-config through standard ansible templates, as if it were any other linux server.

How is this different than the cisco.ios or arista.eos ‘collections’? Said tools provide only an interface for running imperative cli commands through the guise of an ansible playbook. See Ansible for Cisco switch configuration for the issues that arise from such an approach. With the approach I present here, there is no guesswork with regard to the beginning and end state of the config, and its easy to use --check and --diff to confirm changes.

Here I’ve changed the nameserver var:

~/git/arista-ansible$ ansible-playbook main.yml --diff

PLAY [switches] ******************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************
ok: [172.30.184.98]

TASK [eos : declare interfaces list] *********************************************************************************************************
ok: [172.30.184.98]

TASK [eos : detect switchports] **************************************************************************************************************
skipping: [172.30.184.98] => (item=ma1)
skipping: [172.30.184.98] => (item=txraw)
ok: [172.30.184.98] => (item=et34)
ok: [172.30.184.98] => (item=et35)
<truncated>
skipping: [172.30.184.98] => (item=cpu)
skipping: [172.30.184.98] => (item=mirror10)
ok: [172.30.184.98] => (item=et11)

TASK [eos : land startup-config] *************************************************************************************************************
--- before: /mnt/flash/startup-config
+++ after: /home/nhensel/.ansible/tmp/ansible-local-55698442nwcsv9/tmpemk1z5tu/startup-config
@@ -5,7 +5,7 @@
 !
 transceiver qsfp default-mode 4x10G
 !
-ip name-server vrf default 8.8.8.8
+ip name-server vrf default 1.1.1.1
 !
 spanning-tree mode mstp
 !

changed: [172.30.184.98]

TASK [eos : land init script] ****************************************************************************************************************
ok: [172.30.184.98]

RUNNING HANDLER [eos : copy startup-config running-config] ***********************************************************************************
changed: [172.30.184.98]

PLAY RECAP ***********************************************************************************************************************************
172.30.184.98              : ok=6    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

This is not a fully-featured project of course, it is a proof-of-concept and a starting point. Fork the repo, add template expressions and vars as needed.

Nathan Hensel

on caving, mountaineering, networking, computing, electronics


2023-09-09