Overview

If you’re working in infrastructure operations or DevOps leadership and manage Linux-based systems, you’ve likely encountered the challenge of configuration drift, manual patching, or inconsistent environments. These problems scale poorly β€” and automation is the only sustainable answer.

This article outlines a real-world setup for automating Linux server administration from macOS using Ansible, focused on a Google Cloud VM running Ubuntu. The approach is agentless, secure, and entirely SSH-based β€” no third-party daemons or opaque orchestration layers required.

Whether you’re exploring configuration automation for the first time, or evaluating Ansible for adoption, this guide is designed to show how clean and production-ready such a setup can be β€” without unnecessary overhead.


Why Ansible?

Ansible offers a compelling model for infrastructure management:

  • βœ… Agentless β€” no software to install on the target machine
  • βœ… Readable β€” playbooks are in YAML; understandable, even by non-developers
  • βœ… Secure β€” leverages SSH and OS-level privileges (no vendor lock-in)
  • βœ… Idempotent β€” re-running tasks yields consistent, safe results

Combined with cloud-native infrastructure like GCP and a Unix-based workstation like macOS, Ansible becomes a powerful interface between you and your servers.


Architecture Summary

Component Technology Used
Control Node macOS (x.x), Python 3.x, Ansible
Target Node Ubuntu 22.04 LTS VM on GCP
Transport SSH + RSA 4096 key
Privilege Mode sudo via google-sudoers group (no password)

No Ansible agent is required on the remote system. All operations are invoked through SSH and executed using Python, which is available by default on Ubuntu servers.


Setup on macOS (Control Node)

1. Install Ansible inside a Python virtual environment

python3 -m venv ~/ansible-venv
source ~/ansible-venv/bin/activate
pip install ansible

Using a virtual environment helps avoid package conflicts and keeps your automation environment isolated.


2. Generate an SSH Key for Authentication

ssh-keygen -t rsa -b 4096 -f ~/.ssh/gcp-key

This generates a private/public keypair.

  • The private key stays on your Mac
  • The public key (.pub) is added to the ~/.ssh/authorized_keys of the Ubuntu VM user (often ab, ubuntu, or a configured admin user)

If using GCP’s OS Login or metadata-based key injection, add your public key via the GCP console or CLI.


3. Configure Inventory and Ansible Settings

inventory.ini

[gcp]
gcp-vm-hostname-or-ip

[gcp:vars]
ansible_user=your-remote-username
ansible_ssh_private_key_file=~/.ssh/gcp-key

ansible.cfg

[defaults]
inventory = inventory.ini
host_key_checking = False

This setup tells Ansible how to connect and where the inventory (host list) lives.


Playbook: Installing Google Chrome Remotely

Here’s a practical automation example β€” deploying Google Chrome on the remote Ubuntu server.

install-chrome.yaml

- name: Install Google Chrome on Ubuntu
  hosts: gcp
  become: true
  tasks:
    - name: Download Chrome installer
      get_url:
        url: https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
        dest: /tmp/google-chrome.deb

    - name: Install Chrome package
      apt:
        deb: /tmp/google-chrome.deb

    - name: Remove installer after install
      file:
        path: /tmp/google-chrome.deb
        state: absent

To execute:

ansible-playbook install-chrome.yaml

Ansible will:

  • Connect via SSH
  • Download the .deb installer
  • Install the software using apt
  • Clean up the temporary file

What Happens Under the Hood?

When you run the playbook, Ansible:

  1. Connects to the remote host over SSH using your provided key
  2. Copies the required Python module (apt, get_url, etc.) to a temporary directory
  3. Passes a JSON-formatted argument payload via stdin
  4. Executes the module using the remote Python interpreter
  5. Receives structured output and status (changed, failed, skipped, etc.)

You do not need to write shell scripts or wrap commands in quotes β€” Ansible abstracts the platform-level logic, leaving you with clean, declarative YAML.


Sudo and Privilege Escalation

In this setup, the remote user is not root, but it can elevate to root using sudo. On GCP Ubuntu VMs, this is often pre-configured via the google-sudoers group:

# Inside /etc/sudoers.d/google_sudoers
%google-sudoers ALL=(ALL:ALL) NOPASSWD:ALL

This allows any user in the group to perform root-level actions without being prompted for a password β€” crucial for automation workflows like this.

Ansible simply invokes sudo using become: true in your playbook.


Verification: Is Chrome Really Installed?

To validate installation remotely, you can run:

ansible gcp -a "google-chrome --version" -b

Or check existence of the binary:

- name: Ensure Chrome is installed
  hosts: gcp
  become: true
  tasks:
    - name: Check Chrome version
      command: google-chrome --version
      register: chrome_version
      ignore_errors: true

    - debug:
        var: chrome_version.stdout

Why This Approach Works

This model:

  • 🧩 Works from macOS with no special tooling beyond Python
  • πŸ”’ Uses SSH-based access control β€” no agent risk or open management ports
  • βš™οΈ Allows full configuration, patching, and software management from a single playbook
  • πŸ“œ Is version-controlled and auditable β€” your infrastructure lives in code

Final Words

If you’re an experienced systems engineer or IT leader exploring infrastructure-as-code, Ansible offers a practical, low-barrier entry point into automated, declarative system management.

With as little as one inventory file and one playbook, you can go from ad-hoc remote access to repeatable, secure, production-grade configuration management β€” from your Mac.

Whether your team is small and growing, or scaling globally, this approach is modular, scalable, and entirely transparent.