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!
Try this https://github.com/anantnaugai/ansible-role-includecsv
LikeLike