Configuring servers by hand works for one VPS, but becomes error-prone at three or more. Ansible describes the desired state in YAML playbooks and applies it over SSH, with no agent on the servers. This guide shows how to automate VPS configuration with Ansible.
Before you start
- A control machine (your laptop, WSL or a management VPS) with Python.
- One or more Linux VPSs reachable by SSH with key login and a sudo user. See first steps on a new VPS.
Install Ansible
python3 -m pip install --user ansibleOr use your package manager (sudo apt install ansible), which may be older.
Create an inventory
inventory.ini:
[web]
web01 ansible_host=203.0.113.10
web02 ansible_host=203.0.113.11
[web:vars]
ansible_user=deployTest connectivity:
ansible -i inventory.ini web -m pingRun ad-hoc commands
ansible -i inventory.ini web -b -m apt -a "update_cache=yes upgrade=dist"-b means become root with sudo.
Write a playbook
site.yml:
- hosts: web
become: true
tasks:
- name: Install packages
ansible.builtin.apt:
name: [nginx, ufw, fail2ban]
state: present
update_cache: true
- name: Disable SSH password login
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PasswordAuthentication'
line: 'PasswordAuthentication no'
notify: Restart ssh
- name: Allow SSH and HTTP(S)
community.general.ufw:
rule: allow
name: "{{ item }}"
loop: [OpenSSH, 'Nginx Full']
- name: Enable firewall
community.general.ufw:
state: enabled
- name: Ensure Nginx is running
ansible.builtin.service:
name: nginx
state: started
enabled: true
handlers:
- name: Restart ssh
ansible.builtin.service:
name: ssh
state: restartedThe community.general collection ships with the full ansible package; install it with ansible-galaxy collection install community.general if missing.
Run it
ansible-playbook -i inventory.ini site.yml --check --diff--check shows what would change. Then run without it. Running again reports ok instead of changed: playbooks are idempotent.
Grow from here
- Organise tasks into roles (common, web, database).
- Store secrets with
ansible-vault. - Use templates (
ansible.builtin.template) for Nginx vhosts. - Combine with cloud-init for first boot.
Troubleshooting
- UNREACHABLE: wrong IP, user or key; test plain
ssh deploy@IP. - Missing sudo password: add
-Kto prompt, or configure passwordless sudo for the deploy user. - couldn't resolve module: install the needed collection.
Frequently asked questions
Do servers need Ansible installed?
No, only Python and SSH, which almost all Linux distributions have.
Ansible or Terraform?
Terraform creates infrastructure (VMs, DNS); Ansible configures what runs inside. They work well together.
Can Ansible manage Windows servers?
Yes, over WinRM or SSH with Windows-specific modules.
