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 18-06-2017

Visiting NorCal and Seattle area over the past 2 weeks, it’s been nice to visit some of my old friends. Those moments, although brief do warm my heart. Took some time walking around Stanford. The Dish trail turned out to be a great walk.... Continue →