Parsing CSV into an Ansible vars_file

Somebody asked me if it was possible to parse a CSV file into an Ansible vars_file. A little casual googling didn’t yield good results, so I wrote up a little hack.

The context was wanting to feed a big CSV file of data (presumably exported from an Excel spreadsheet) to Ansible’s network automation. So first we gin up a bit of CSV:

name,description,vlanid,state,mtu,inet
spam,spam,1,up,1500,192.168.1.1
eggs,eggs,2,up,1500,192.168.1.2
sausage,sausage,3,up,9000,192.168.1.3

Parsing this with Python is very easy. In fact, it even has a built-in module for CSV, which can produce a nice dict with labels based on the column titles.

#!/usr/bin/env python

import csv
import sys
import yaml

csv_data = []
with open(sys.argv[1]) as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        csv_data.append(row)

with open(sys.argv[1] + '.yml', 'w') as outfile:
    outfile.write(yaml.dump({'csv_data': csv_data}))

Now using this bit of Python, we can make an Ansible playbook that first parses the CSV into a YAML vars_file, and then imports that vars_file in the playbook.

---
- hosts: localhost
  connection: local
  become: false
  gather_facts: false
  tasks:
    - name: parse csv and make vars file
      command: "python csv_to_yaml.py example.csv"

- hosts: localhost
  connection: local
  become: false
  gather_facts: false
  vars_files:
    - example.csv.yml
  tasks:
    - debug: var=csv_data

Now lets run it and look at the debug output.

[jason@w550s redhat]$ ansible-playbook csv_vars_playbook.yml
 [WARNING]: Could not match supplied host pattern, ignoring: all

 [WARNING]: provided hosts list is empty, only localhost is available


PLAY [localhost] **********************************************************

TASK [parse csv and make vars file] ***************************************
changed: [localhost]

PLAY [localhost] **********************************************************

TASK [debug] **************************************************************
ok: [localhost] => {
    "csv_data": [
        {
            "description": "spam",
            "inet": "192.168.1.1",
            "mtu": "1500",
            "name": "spam",
            "state": "up",
            "vlanid": "1"
        },
        {
            "description": "eggs",
            "inet": "192.168.1.2",
            "mtu": "1500",
            "name": "eggs",
            "state": "up",
            "vlanid": "2"
        },
        {
            "description": "sausage",
            "inet": "192.168.1.3",
            "mtu": "9000",
            "name": "sausage",
            "state": "up",
            "vlanid": "3"
        }
    ]
}

PLAY RECAP ****************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0

There may be better ways for Ansible to parse CSV, but this was quick and easy. Hit me up if you’ve got a more elegant approach!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s