Skip to main content

The Natural Evolution of Ansible: A Human Journey

· 3 min read
Max Kaido
Architect

When people start with Ansible, they often encounter tutorials showing a perfect directory structure with roles, playbooks, and inventories all laid out. But that's not how real adoption happens. Let me share a more natural journey of how teams typically grow into Ansible.

Phase 1: The First Script (Day 1)

It usually starts with a simple need: "I need to set up my development environment on a new laptop." You create your first YAML file:

# setup.yml
- hosts: localhost
tasks:
- name: Install dev tools
apt:
name:
- git
- vim
- tmux
state: present
become: true

You run it with ansible-playbook setup.yml and it works! This is your gateway drug to Ansible.

Phase 2: Reusability Needs (Week 1)

After setting up a second machine, you realize you need different packages for different scenarios. You start using variables:

# setup.yml
- hosts: localhost
vars:
dev_packages:
- git
- vim
- tmux
gui_packages:
- i3
- alacritty
tasks:
- name: Install dev tools
apt:
name: '{{ dev_packages }}'
state: present
become: true
when: install_dev | default(true)

- name: Install GUI tools
apt:
name: '{{ gui_packages }}'
state: present
become: true
when: install_gui | default(false)

Phase 3: Configuration Files (Week 2)

You need to manage config files. Your playbook grows:

- hosts: localhost
tasks:
- name: Create config directories
file:
path: '~/.config/{{ item }}'
state: directory
loop:
- i3
- alacritty

- name: Copy config files
copy:
src: 'files/{{ item }}'
dest: '~/.config/{{ item }}'
loop:
- i3/config
- alacritty/alacritty.yml

Now you need a files/ directory. Structure starts emerging naturally.

Phase 4: Multiple Machines (Month 1)

You need to manage multiple machines. Inventory becomes necessary:

# inventory.ini
[laptops]
work_laptop ansible_host=192.168.1.10
home_laptop ansible_host=192.168.1.20

[servers]
webserver ansible_host=203.0.113.10

Phase 5: Task Organization (Month 2)

Your playbook becomes huge. You start splitting tasks into files:

# tasks/packages.yml
- name: Install packages
apt:
name: '{{ dev_packages }}'
state: present
become: true

# main.yml
- hosts: laptops
tasks:
- include_tasks: tasks/packages.yml
- include_tasks: tasks/configs.yml

Phase 6: The Role Revelation (Month 3)

You're copying task files between projects. Time for roles:

ansible-galaxy init laptop_setup

Your first role emerges from necessity, not because a tutorial told you to use roles.

Phase 7: Group Variables (Month 4)

Different machines need different settings. Group variables become your friend:

# group_vars/laptops.yml
dev_packages:
- git
- vim
- tmux

# group_vars/servers.yml
server_packages:
- nginx
- postgresql

Phase 8: Multiple Roles (Month 6)

You realize some setups are common across projects:

# roles/
- common/ # Basic setup
- nodejs/ # Node.js installation
- python/ # Python environment
- laptop/ # Laptop-specific setup

Each role born from a real need, not pre-planning.

Phase 9: Handlers and Dependencies (Month 8)

Services need to restart after config changes. Dependencies between roles become clear:

# roles/nginx/handlers/main.yml
- name: restart nginx
service:
name: nginx
state: restarted

# roles/webapp/meta/main.yml
dependencies:
- role: nginx
- role: nodejs

The Key Lessons

  1. Start Simple: One playbook, a few tasks. Don't over-architect.
  2. Let Structure Emerge: Create directories and splits when they become necessary.
  3. Roles Come from Repetition: When you copy-paste tasks between playbooks, that's your cue to create a role.
  4. Variables Grow Gradually: Start with hardcoded values, extract variables when you need flexibility.
  5. Inventory Follows Need: Start with localhost, add inventory when managing multiple machines.

Remember: The "perfect" Ansible structure isn't perfect if it doesn't match your current needs. Let your Ansible setup grow organically with your requirements. The best structure is the one that solves your problems today while being flexible enough to grow tomorrow.

What's Next?

As your Ansible usage evolves, you'll naturally discover needs for:

  • CI/CD integration
  • Vault for secrets
  • Dynamic inventory
  • Custom modules

But that's another story, for another day. Let your needs guide you, not the other way around.

Tags: #ansible #devops #infrastructure #automation