Automating infrastructure configuration across multiple CentOS servers using Ansible — built hands-on on Apple M3 silicon using UTM virtualization.
┌─────────────────────────────────────────────────────┐
│ HOME LAB │
│ │
│ ┌─────────────────────────┐ │
│ │ AnsibleController │ │
│ │ 192.168.189.106 │ │
│ │ CentOS | SSH Keys │ │
│ └────────────┬────────────┘ │
│ │ │
│ SSH Key Authentication │
│ │ │
│ ┌─────────┴──────────┐ │
│ │ │ │
│ ┌───▼──────────┐ ┌──────▼────────┐ │
│ │ Target1 │ │ Target2 │ │
│ │ 192.168.189 │ │ 192.168.189 │ │
│ │ .205 │ │ .121 │ │
│ │ CentOS │ │ CentOS │ │
│ └──────────────┘ └───────────────┘ │
│ │
│ Virtualization: UTM on Apple M3 │
│ SSH Client: Termius │
└─────────────────────────────────────────────────────┘
| Task | Status |
|---|---|
| SSH key authentication between controller and nodes | ✅ Done |
| Ansible ping across all nodes | ✅ Done |
| Automated package updates across fleet | ✅ Done |
| Automated software installation on all nodes | ✅ Done |
ansible-lab/
├── inventory.txt # Host definitions and connection config
├── demo-playbook.yml # Main playbook — update and install
├── ansible.cfg # Ansible configuration
└── README.md # This file
This lab uses SSH key-based authentication — the production standard for Ansible deployments.
# Generate SSH key on controller
ssh-keygen -t rsa
# Copy public key to each target node
ssh-copy-id senopaul@192.168.189.205
ssh-copy-id senopaul@192.168.189.121No passwords stored. No password prompts. Secure and automated.
Target1 ansible_host=192.168.189.205 ansible_user=senopaul
Target2 ansible_host=192.168.189.121 ansible_user=senopaul---
- name: Update and install VLC on servers
hosts: all
become: yes
tasks:
- name: Update all packages on hosts
yum:
name: "*"
state: latest
ignore_errors: yes
- name: Install VLC player
yum:
name: vlc
state: present
ignore_errors: yesTest connectivity across all nodes:
ansible all -m ping -i inventory.txtExpected output:
Target1 | SUCCESS => {"ping": "pong"}
Target2 | SUCCESS => {"ping": "pong"}
Run the full playbook:
ansible-playbook demo-playbook.yml -i inventory.txtExpected output:
TASK [Update all packages on hosts]
changed: [Target1]
changed: [Target2]
TASK [Install VLC player]
changed: [Target1]
changed: [Target2]
Target1 : ok=3 changed=2 failed=0
Target2 : ok=3 changed=2 failed=0
| Tool | Purpose |
|---|---|
| Ansible | Configuration management and automation |
| CentOS | Operating system on all nodes |
| UTM | Virtualization on Apple M3 silicon |
| Termius | SSH client for terminal access |
| Git | Version control |
Built by Paul Ssenoga — Software Engineer transitioning into DevOps.
This lab was built hands-on after a 10-hour workday. Every error is documented. Every fix earned.
Part of a broader DevOps journey covering: