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:
- Ansible installed
- A working python installation
- Have a service account with Compute Engine API access
- Exported a JSON key in Credentials subsection of your console
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:
- Orchestrating GCE Instances with Ansible by folks at Vimeo
- Official Ansible Documentation