Learn how to automate Google Cloud with Ansible and Qwiklabs

Qwiklabs has some pretty cool Google Cloud Platform (GCP) training that I’ve been playing with this weekend.

I thought it might be fun to try and automate the lessons with Ansible’s GCE modules.

The playbooks, and steps to recreate their execution environment, are on my GitHub.

I wasn’t able to automate 100% of the workshops. The Ansible GCE module is still in beta, and I’m new at GCP in general, and may have missed some things. For example, I couldn’t find any way at all to programmatically interact with Google Cloud Launcher with the SDK or API. But like I said, maybe I just missed it.

If you’re like me, and you know AWS better than GCP, here’s a nice Rosetta stone¬†comparing services.

There are a number of open Ansible issues related to GCE, many of which look like great places to jump in and be an Ansible contributor.

Still, lots of fun!

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!