Sandbox99 Chronicles

Building a Baseline: Ansible Playbook for Initial Server Prep

ansible baseline setup

Written by Jose Mendez

Hi, I’m Jose Mendez, the creator of sandbox99.cc. with a passion for technology and a hands-on approach to learning, I’ve spent more than fifteen years navigating the ever-evolving world of IT.

Published May 19, 2025 | Last updated on May 28, 2025 at 7:05AM

Reading Time: 4 minutes

Introduction

In our previous post, we demonstrated how to set up a basic Ansible demo environment with a control node and a target In the previous post, we built a basic Ansible demo environment with a control node and a target node. Now it’s time to write your first real playbook—a simple but essential step in automating your infrastructure.

In this post, we’ll walk you through a playbook that installs baseline server applications commonly needed on any fresh Linux server. These include useful command-line tools like vim, htop, and curl—packages that form the foundation for productivity, debugging, and remote access management.

This will help you standardize server environments quickly and consistently, especially when deploying new systems in bulk.

How the Setup Would Look Like?

📡 Network Diagram

📁 Directory Structure

📄 Feel free to add any number of host groups to your inventory/hosts.ini file; you’ll refer to these groups by their names when running playbooks.

# ==========================
# Ansible Inventory File
# ==========================

# Syntax Reference:
# [group_name]         <-- Group of hosts
# IP_or_Hostname       ansible_user=username   ansible_port=port_number

# ------------------------------------
# Infrastructure Linux Hosts
# ------------------------------------
[Debian_Linux]
203.0.113.10        ansible_user=admin1      ansible_port=2222

# ------------------------------------
# Cisco Network device
# ------------------------------------
# [L2 Switches]
# 10.1.5.150     ansible_user=cisco          ansible_port=22
# 10.1.5.100     ansible_user=cisco          ansible_port=22


# -----------------------------------
# Business Unit 1 Servers
# -----------------------------------
# [Business_Unit1]
# 172.16.23.210    ansible_user=svc12345   ansible_port=3333
# 172.16.23.220    ansible_user=svc12345   ansible_port=3333

⚙️ For your Ansible configuration, the ansible.cfg file should be placed in your current directory. This location holds the second highest precedence in Ansible’s configuration loading order. Ensure this file contains your desired settings, and specifically, do not comment out line 2. To prevent confusion, it’s recommended to use only one ansible.cfg file. Remember the full precedence order is:
1. ANSIBLE_CONFIG environment variable,
2. ansible.cfg in the current directory,
3. ~/.ansible.cfg in the home directory
4. /etc/ansible/ansible.cfg.
Note: that in enterprise environments with dedicated Ansible servers, configurations are often found in the ANSIBLE_CONFIG environment variable or /etc/ansible/ansible.cfg.

[defaults]
inventory = ./inventory/hosts.ini      # Path to your inventory file
# remote_user = ansible_user           # Default SSH user (can be overridden per host)
# host_key_checking = False            # Disable SSH host key checking
# timeout = 30                         # SSH connection timeout
# retry_files_enabled = False          # Disable creation of *.retry files
# interpreter_python = auto_silent     # Let Ansible auto-detect Python path silently

[privilege_escalation]
# become = True                        # Enable privilege escalation (like sudo)
# become_method = sudo
# become_user = root
# become_ask_pass = False

📝 This basic playbook for essential setup is located at playbook/01-baseline-setup.yml.

  • Feel free to customize the list of applications to install as needed. Note that line 3 specifies the target hosts by referencing a group name you defined in your hosts.ini inventory file.
  • Should you forget to remove something during a previous run, you can add it to the packages_to_uninstall list for the next execution.
  • Please pay close attention to the spacing in this YAML playbook file. Using an editor like VS Code with a YAML extension is highly recommended to help ensure correct formatting.
---
- name: Initial Server Setup with Install/Uninstall Options
  hosts: Debian_Linux # Your target host group
  become: true # Requires root privileges

  # Define variables for packages to install and uninstall
  # You can override these using --extra-vars on the command line,
  # inventory variables, or group/host_vars files.
  vars:
    packages_to_install:
      - docker.io
      - docker-compose
      - htop
      - curl
      - vim
      - nano
      - git
      - neofetch
      - inxi
      - netcat-openbsd
      # Add packages here that you always want to install by default

    packages_to_uninstall:
      # Add packages here that you want to uninstall when running with the uninstall task enabled
      # - vim
      # - nmap

  tasks:
    - name: Update apt cache
      ansible.builtin.apt:
        update_cache: yes
        cache_valid_time: 3600 # Cache valid for 1 hour
      when: package_update | default(false) # Only run if package_update is true

    - name: Upgrade all packages
      ansible.builtin.apt:
        upgrade: dist
      when: package_upgrade | default(false) # Only run if package_upgrade is true

    - name: Install specified packages
      ansible.builtin.apt:
        name: "{{ packages_to_install }}" # Use the variable for the list of packages
        state: present # Ensure packages are installed
      when: packages_to_install is defined and packages_to_install | length > 0 # Only run if the list is defined and not empty

    - name: Uninstall specified packages
      ansible.builtin.apt:
        name: "{{ packages_to_uninstall }}" # Use the variable for the list of packages
        state: absent # Ensure packages are removed
        purge: yes # Optionally remove configuration files as well
        autoremove: yes # Optionally remove dependencies no longer needed
      when: packages_to_uninstall is defined and packages_to_uninstall | length > 0 # Only run if the list is defined and not empty
      tags:
        - uninstall # Add a tag to easily run this task specifically

🚀 Running Your Playbook from your_ansible_project directory:

ansible-playbook playbook/01-baseline-setup.yml

# If you want to run only Uninstall task and the rest remain the same
ansible-playbook playbook/01-baseline-setup.yml --tags uninstall

If your configuration is correct, you should see Ansible execute each task and apply the changes to your target node(s). Try modifying the playbook and running it again to observe how the behavior changes. If you encounter failures, use them as opportunities to adjust settings in your ansible.cfg and deepen your understanding.

Final Thoughts

This first playbook might look simple, but it’s a powerful start. Automating baseline package installation ensures that every server you spin up is equipped with essential tools—no manual setup required.

As you grow more confident with Ansible, you can expand your playbooks to include user management, security hardening, service deployment, and more. But for now, this clean and focused playbook gets the job done and gives you a solid foundation.

Calendar

July 2025
S M T W T F S
 12345
6789101112
13141516171819
20212223242526
2728293031  

Related Post

Caddy: The Modern Web Server You Need to Know

Caddy: The Modern Web Server You Need to Know

The Shifting Landscape of Web Servers For years, a few titans have dominated the web server landscape. Names like Nginx, Apache2, and Microsoft IIS have been synonymous with hosting websites and applications, powering the vast majority of the internet. Their robust...

read more
Docker & Docker Compose Cheatsheet

Docker & Docker Compose Cheatsheet

Introduction to Docker In the world of software development, the phrase "it works on my machine" used to be a common, frustrating refrain. This is precisely the problem Docker set out to solve. Introduced in 2013, Docker has revolutionized how applications are built,...

read more