How to Automate Server Configuration with Ansible Playbooks on Ubuntu

Learning how to automate server configuration with Ansible Playbooks on Ubuntu can save you hours of repetitive manual work. Instead of SSHing into each server and running the same commands over and over, Ansible lets you define your entire server setup in a single file. You run it once, and every server gets configured exactly the same way. This tutorial walks you through installing Ansible, writing your first playbook, and running it against an Ubuntu server. By the end, you’ll have a working playbook that installs packages, configures a service, and creates system users automatically.

Prerequisites for Automating Server Configuration with Ansible

Before you start, make sure you have the following in place.

Required setup:

  • A control machine running Ubuntu 20.04 or 22.04 (your local machine or a VPS)
  • At least one target Ubuntu server you want to configure
  • SSH access from your control machine to the target server
  • A non-root user with sudo privileges on both machines
  • Python 3 installed on the target server (Ubuntu includes this by default)

Assumed knowledge:

  • Basic Linux command line usage
  • Understanding of SSH key authentication
  • Familiarity with YAML file formatting helps, but isn’t required

Estimated time: 30–45 minutes

You’ll also want SSH key-based authentication set up between your control machine and your target server. Password authentication works, but key-based auth is cleaner and avoids extra prompts during playbook runs. If you haven’t set that up yet, run ssh-keygen on your control machine and copy the key with ssh-copy-id user@your-server-ip.

How to Automate Server Configuration with Ansible Playbooks on Ubuntu

See also: Setup Pivpn Server on Ubuntu and Connect on Windows

Follow these steps carefully. Each one builds on the last.

Step 1: Install Ansible on your control machine

Start by adding the official Ansible PPA and installing the package.

sudo apt update
sudo apt install software-properties-common -y
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible -y

Verify the installation worked:

ansible --version

You should see output showing the Ansible version and Python path. If you get a “command not found” error, the installation didn’t complete. Try running sudo apt install ansible -y again.

Step 2: Create your project directory

Keep your Ansible files organized from the start. Create a dedicated project folder.

mkdir ~/ansible-project
cd ~/ansible-project

Step 3: Create the inventory file

Ansible needs to know which servers to target. You define these in an inventory file.

nano inventory.ini

Add the following content. Replace your-server-ip with your actual server’s IP address.

[webservers]
your-server-ip ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa

Save and close the file with Ctrl+X, then Y, then Enter.

Test that Ansible can reach your server:

ansible -i inventory.ini webservers -m ping

You should see a green “pong” response. That confirms the connection works.

Step 4: Write your first Ansible playbook

Now for the main event. Create a playbook file:

nano site.yml

Add the following playbook. This installs Nginx, creates a deploy user, and ensures the service starts on boot.

---
- name: Configure web server
  hosts: webservers
  become: yes

  vars:
    deploy_user: deployuser

  tasks:
    - name: Update apt cache
      apt:
        update_cache: yes

    - name: Install Nginx
      apt:
        name: nginx
        state: present

    - name: Start and enable Nginx
      service:
        name: nginx
        state: started
        enabled: yes

    - name: Create deploy user
      user:
        name: "{{ deploy_user }}"
        shell: /bin/bash
        create_home: yes

    - name: Allow deploy user to use sudo
      lineinfile:
        path: /etc/sudoers
        line: "{{ deploy_user }} ALL=(ALL) NOPASSWD:ALL"
        validate: 'visudo -cf %s'

Save the file. This playbook covers the most common tasks you’ll need on a fresh server.

Step 5: Run the playbook

Execute the playbook against your inventory:

ansible-playbook -i inventory.ini site.yml

Ansible will connect to your server and run each task in order. You’ll see colored output for each task. Green means success. Yellow means the task ran but made a change. Red means something failed.

Step 6: Verify the results

SSH into your target server and confirm everything worked:

ssh ubuntu@your-server-ip
systemctl status nginx
id deployuser

Nginx should be active and running. The deployuser account should exist. You’ve now confirmed your playbook worked end to end.

Step 7: Use variables to make your playbook reusable

Hard-coded values make playbooks brittle. Move your variables into a separate file for cleaner management.

nano vars.yml
deploy_user: deployuser
nginx_port: 80

Then reference it in your playbook by adding this line under the hosts declaration:

  vars_files:
    - vars.yml

This approach scales well. You can maintain different variable files for staging and production environments without touching the playbook itself. The official Ansible documentation on variables covers more advanced patterns worth exploring.

Troubleshooting Common Ansible Playbook Errors

Even clean playbooks hit snags. Here are the most common issues you’ll run into.

Problem: “UNREACHABLE” error when running a playbook

This means Ansible can’t connect via SSH. Check that your SSH key path is correct in the inventory file. Also verify the target server is running and accepts connections on port 22.

Problem: “Missing sudo password” error

Your user needs passwordless sudo, or you need to pass the --ask-become-pass flag:

ansible-playbook -i inventory.ini site.yml --ask-become-pass

Problem: YAML indentation errors

YAML is sensitive to spacing. Use spaces, never tabs. Each level of indentation should be exactly two spaces. A YAML linter can catch these before you run the playbook.

Problem: A task runs every time even when nothing changed

This usually means the task isn’t idempotent. Check that you’re using Ansible modules (like apt, service, user) instead of raw shell commands. Modules track state. Raw commands don’t.

Tip: Run playbooks with the --check flag first to preview changes without applying them:

ansible-playbook -i inventory.ini site.yml --check

You can also find community-maintained roles on Ansible Galaxy that handle complex setups like MySQL, PHP, and WordPress stacks. These save significant time on common configurations.

Conclusion: Next Steps After Your First Ansible Playbook

You now know how to automate server configuration with Ansible Playbooks on Ubuntu from start to finish. You installed Ansible, built an inventory, wrote a playbook with real tasks, and ran it successfully against a live server. That’s a solid foundation.

From here, consider organizing your playbooks into roles. Roles let you split tasks, variables, and templates into structured folders. This makes large projects much easier to manage. You might also look at Ansible Vault for encrypting sensitive values like passwords and API keys.

The real power of this approach shows up when you manage five, ten, or fifty servers. Every machine gets the same configuration. Every change is tracked in version control. Manual configuration errors become a thing of the past.

Similar Posts