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.
