Hi there! I'm Maneshwar. Right now, I’m building LiveAPI, a first-of-its-kind tool for helping you automatically index API endpoints across all your repositories. LiveAPI helps you discover, understand, and use APIs in large tech infrastructures with ease.
If you've ever SSHed into a bunch of servers to install the same stuff over and over, you know the pain.
Ansible solves that beautifully — it's like writing shell scripts that scale.
In this post, I’ll show you how to use Ansible to automate installing the Google Cloud CLI across multiple remote Ubuntu servers.
What’s Ansible?
Ansible is an open-source automation engine used for configuration management, application deployment, and orchestration.
Unlike Chef or Puppet, Ansible is agentless — meaning your remote machines don’t need to install anything.
It just uses good old SSH + Python to get the job done.
You define what you want, not how to do it.
That means less bash gymnastics and more readable, version-controlled infrastructure code.
How Ansible Works
Here’s the high-level idea:
- You write playbooks (YAML files) describing tasks like “install this package,” “copy this file,” “restart this service.”
- You define hosts (target machines) in an inventory file.
- Ansible connects over SSH, interprets your playbook, and runs the tasks in order.
It’s declarative. Idempotent. Easy to debug.
Quick Primer: Ansible Syntax
An Ansible playbook looks like this:
- name: Say hello
hosts: all
tasks:
- name: Print greeting
debug:
msg: "Hello from {{ inventory_hostname }}"
You can break it down like this:
Term | What It Means |
---|---|
hosts |
Which group or machine to run this on (from inventory) |
tasks |
List of steps to run |
debug: |
A module (built-in Ansible logic) |
msg: |
Argument passed to the module |
Install Ansible
Here’s a quick setup script for Ubuntu:
#!/bin/bash
sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible
Your Inventory: hosts.ini
This file tells Ansible where to go and how to log in.
[all]
server1 ansible_host=34.0.0.0 ansible_user=root ansible_ssh_private_key_file=~/.ssh/key.txt
server2 ansible_host=34.0.0.0 ansible_user=root ansible_ssh_private_key_file=~/.ssh/key.txt
Replace with your actual server IPs and SSH key paths.
Variable File: vars.yml
Keep your secrets and project configs tidy here:
gcp_service_account_json: [email protected]
gcp_project_id: my-project-id-004
Drop your GCP service account JSON file into the same directory as the playbook.
The Playbook: gcloud-install.yml
Here’s where the magic happens:
---
- name: Install Google Cloud CLI on Ubuntu
hosts: all
become: false
pre_tasks:
- name: Fail if not root
fail:
msg: "This playbook must be run as root (sudo)."
when: ansible_user_id != 'root'
- name: Check if vars file exists
stat:
path: "{{ playbook_dir }}/vars.yml"
register: vars_file_check
- fail:
msg: "vars.yml not found."
when: not vars_file_check.stat.exists
vars_files:
- vars.yml
tasks:
- name: Update apt cache
apt:
update_cache: yes
- name: Install dependencies
apt:
name:
- apt-transport-https
- ca-certificates
- gnupg
- curl
state: present
- name: Add GCloud GPG key
shell: |
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg
args:
creates: /usr/share/keyrings/cloud.google.gpg
- name: Add GCloud repo
copy:
dest: /etc/apt/sources.list.d/google-cloud-sdk.list
content: |
deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main
- name: Update apt cache again
apt:
update_cache: yes
- name: Install GCloud CLI
apt:
name: google-cloud-cli
state: present
- name: Copy service account key to target
copy:
src: "{{ gcp_service_account_json }}"
dest: /tmp/gcp-service-account.json
mode: "0600"
when: inventory_hostname != "localhost"
- name: Set key path for localhost
set_fact:
gcp_key_path: "{{ playbook_dir }}/{{ gcp_service_account_json }}"
when: inventory_hostname == "localhost"
- name: Set key path for remote
set_fact:
gcp_key_path: /tmp/gcp-service-account.json
when: inventory_hostname != "localhost"
- name: Authenticate GCloud
command: gcloud auth activate-service-account --key-file={{ gcp_key_path }}
environment:
CLOUDSDK_CORE_DISABLE_PROMPTS: "1"
- name: Set GCloud project
command: gcloud config set project {{ gcp_project_id }}
environment:
CLOUDSDK_CORE_DISABLE_PROMPTS: "1"
- name: List GCE Instances
command: gcloud compute instances list --project={{ gcp_project_id }}
register: gcloud_instances
environment:
CLOUDSDK_CORE_DISABLE_PROMPTS: "1"
ignore_errors: true
- name: Show instance list
debug:
var: gcloud_instances.stdout_lines
♂️ Run It!
ansible-playbook -i hosts.ini gcloud-install.yml
Make sure you run this as sudo
or from a root session if you're not using become: true
.
Final Thoughts
This example scratches the surface of what Ansible can do. Once you get comfy, you'll be:
- Spinning up full environments
- Managing Docker containers
- Deploying apps at scale
- Sleeping better 😴
LiveAPI helps you get all your backend APIs documented in a few minutes
With LiveAPI, you can quickly generate interactive API documentation that allows users to search and execute APIs directly from the browser.
If you’re tired of manually creating docs for your APIs, this tool might just make your life easier.
Top comments (8)
Ansible suddenly feels way less intimidating...
Yeah even I found it difficult in the beginning, now its getting better for me.
Love the step-by-step Ansible breakdown, makes remote setup feel way less intimidating. Have you tried automating anything besides CLI tools yet?
Thanks. No
Good explanation
Thanks
nice
Thanks
Some comments may only be visible to logged-in visitors. Sign in to view all comments.