Ansible - GCP Dynamic inventory bootstrap

Ansible GCP module bootstrap #

The official docs on Ansible GCP module are quite a bit confusing, so I’ve decided to publish some steps to quickly bootstrap a working environment.

Main concept is that Ansible can not only use static files as a source of inventory but also execute a script and use it’s output as an in-memory representation of it. This allows us to make dynamic inventories to load up hosts from your cloud provider, for example. And, conveniently, there’s such a script in the Ansible’s contrib directory named gce.py.

This assumes you already have:

Here are quick bootstrap instructions on how to get it working:

Install libcloud and libcrypto:

λ pip install apache-libcloud pycrypto

Create a working dir:

λ mkdir -p ansible/inventory && cd ansible

Clone ansible repo:

λ git clone https://github.com/ansible/ansible

Copy the gcp.py inventory script and the gcp.ini template from contrib folder:

λ cp ansible/contrib/inventory/gce.* inventory

Populate the .ini file (this is where gce.py will read its’ settings from):

λ cat ~/.ansible/gce.ini

[gce]
gce_service_account_email_address = my-account@my-project.iam.gserviceaccount.com
gce_service_account_pem_file_path = /full/path/to/my_key.json
gce_project_id = my-project

[inventory]
# Use external IP addresses to connect
inventory_ip_type = external

[cache]
cache_path = ~/.ansible/tmp
cache_max_age = 300

You can move it into your home directory and exporting the variable in your .zshrc for future ease-of-use:

λ cat ~/.zshrc | grep gce.ini
  # Export ansible gce.ini
  [[ -s "$HOME/.ansible/gce.ini" ]] && export GCE_INI_PATH="$HOME/.ansible/gce.ini"

Reload your shell and check if it’s working:

λ source ~/.zshrc
λ ./inventory/gce.py --list

If you’ve received a large set of output with your instance data - it’s now set up correctly.

Boom, now you can access your instances by zone:

λ ansible -i inventory australia-southeast1-c -m ping
web-worker-3 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
web-worker-1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
web-worker-2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
master | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

, or tag. For that just prepend the network tag name with tag_, i.e. for web-worker tag:

λ ansible -i inventory tag_web-worker -m ping
web-worker-3 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
web-worker-1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
web-worker-2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

For more options and further reading, check out the official module docs. Hope it’s helpful!

Materials used:

 
1
Kudos
 
1
Kudos

Now read this

What’s making me happy 07-05-2017

Went hiking to Uloola Falls this weekend - was the first truly lengthy hike since my arrival in Australia, feels good to be back in the game. Mastodon is another distributed social network which seems to be taking off a bit better than... Continue →