September 02, 2026 · by Alex M.
If you manage multiple servers or want to eliminate repetitive tasks from your workflow, Ansible is the tool you need. It is an open-source, agentless automation platform (no agent installation required on managed servers) and incredibly easy to learn. In this guide, you'll learn how to install and configure Ansible on a NVMe VPS or SSD VPS, with practical examples throughout.
Ansible is an IT automation platform developed by Red Hat that lets you:
Unlike Puppet or Chef, Ansible requires no agent on nodes. Communication happens over SSH, making it ideal for any Linux VPS or dedicated server.
apt, copy, service)Before you begin, make sure you have:
sudo privilegesIf you don't have a server yet, you can quickly spin up a CLIQHOST NVMe VPS with Ubuntu pre-installed.
sudo apt update
sudo apt install -y software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install -y ansible
ansible --version
Expected output:
ansible [core 2.16.x]
python version = 3.10.x
jinja version = 3.x.x
sudo dnf install -y epel-release
sudo dnf install -y ansible
The inventory is the heart of any Ansible configuration. It defines which servers will be managed and how they are grouped.
/etc/ansible/hosts)[webservers]
192.168.1.10
192.168.1.11
[dbservers]
192.168.1.20
[all:vars]
ansible_user=ubuntu
ansible_ssh_private_key_file=~/.ssh/id_rsa
Create an inventory.yml file:
all:
children:
webservers:
hosts:
web01:
ansible_host: 192.168.1.10
web02:
ansible_host: 192.168.1.11
dbservers:
hosts:
db01:
ansible_host: 192.168.1.20
vars:
ansible_user: ubuntu
ansible_ssh_private_key_file: ~/.ssh/id_rsa
ansible all -m ping -i inventory.yml
Success response:
web01 | SUCCESS => {
"changed": false,
"ping": "pong"
}
ansible.cfgCreate an ansible.cfg file in your project directory:
[defaults]
inventory = ./inventory.yml
remote_user = ubuntu
private_key_file = ~/.ssh/id_rsa
host_key_checking = False
retry_files_enabled = False
[privilege_escalation]
become = True
become_method = sudo
become_user = root
Note:
host_key_checking = Falseis useful in test environments. In production, on a managed dedicated server, keep this enabled for security.
Ad-hoc commands are useful for quick actions without writing a playbook:
# Check uptime on all servers
ansible all -m command -a "uptime"
# Install a package on all web servers
ansible webservers -m apt -a "name=nginx state=present" --become
# Copy a file to nodes
ansible webservers -m copy -a "src=/local/file.conf dest=/etc/nginx/file.conf"
# Restart a service
ansible webservers -m service -a "name=nginx state=restarted" --become
# Check disk space
ansible all -m shell -a "df -h"
A playbook is a YAML file that describes the desired state of your systems. Here is a complete example for installing and configuring Nginx:
---
- name: Install and configure Nginx
hosts: webservers
become: true
vars:
nginx_port: 80
site_name: "example.com"
tasks:
- name: Update APT cache
apt:
update_cache: yes
cache_valid_time: 3600
- name: Install Nginx
apt:
name: nginx
state: present
- name: Copy site configuration
template:
src: templates/nginx_site.conf.j2
dest: "/etc/nginx/sites-available/{{ site_name }}"
owner: root
group: root
mode: '0644'
notify: Restart Nginx
- name: Enable site
file:
src: "/etc/nginx/sites-available/{{ site_name }}"
dest: "/etc/nginx/sites-enabled/{{ site_name }}"
state: link
notify: Restart Nginx
- name: Start and enable Nginx
service:
name: nginx
state: started
enabled: yes
handlers:
- name: Restart Nginx
service:
name: nginx
state: restarted
templates/nginx_site.conf.j2)server {
listen {{ nginx_port }};
server_name {{ site_name }};
root /var/www/{{ site_name }};
index index.html index.php;
access_log /var/log/nginx/{{ site_name }}_access.log;
error_log /var/log/nginx/{{ site_name }}_error.log;
location / {
try_files $uri $uri/ =404;
}
}
# Dry-run (check without making changes)
ansible-playbook playbook_nginx.yml --check
# Actual run
ansible-playbook playbook_nginx.yml
# With verbose output
ansible-playbook playbook_nginx.yml -v
For larger projects, roles enable code reuse and organisation. Role structure:
roles/
nginx/
tasks/
main.yml
handlers/
main.yml
templates/
nginx_site.conf.j2
defaults/
main.yml
vars/
main.yml
files/
meta/
main.yml
ansible-galaxy init roles/nginx
ansible-galaxy init roles/mariadb
ansible-galaxy init roles/php
---
- name: Configure LEMP stack
hosts: webservers
become: true
roles:
- nginx
- mariadb
- php
group_vars/
webservers.yml
dbservers.yml
host_vars/
web01.yml
group_vars/webservers.yml:
nginx_worker_processes: 4
nginx_worker_connections: 1024
php_version: "8.2"
# Create an encrypted file
ansible-vault create group_vars/all/vault.yml
# Edit an encrypted file
ansible-vault edit group_vars/all/vault.yml
# Run playbook with vault
ansible-playbook site.yml --ask-vault-pass
# or with password file
ansible-playbook site.yml --vault-password-file ~/.vault_pass
vault.yml (decrypted content):
db_root_password: "SuperPassword123!"
db_app_password: "AppPassword456!"
api_key: "sk-xxxxxxxxxxxx"
---
- name: Initial VPS security hardening
hosts: all
become: true
tasks:
- name: Upgrade the system
apt:
upgrade: dist
update_cache: yes
- name: Install security packages
apt:
name:
- ufw
- fail2ban
- unattended-upgrades
state: present
- name: UFW - allow SSH
ufw:
rule: allow
port: "22"
proto: tcp
- name: UFW - allow HTTP/HTTPS
ufw:
rule: allow
port: "{{ item }}"
proto: tcp
loop:
- "80"
- "443"
- name: Enable UFW
ufw:
state: enabled
policy: deny
- name: Start and enable fail2ban
service:
name: fail2ban
state: started
enabled: yes
- name: Disable root SSH login
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PermitRootLogin'
line: 'PermitRootLogin no'
notify: Restart SSH
handlers:
- name: Restart SSH
service:
name: ssh
state: restarted
--check before running on production serversname fieldsFor complex production infrastructures, a managed dedicated server or a server management service can save you considerable time and effort.
ansible-project/
├── ansible.cfg
├── inventory/
│ ├── production/
│ │ ├── hosts.yml
│ │ └── group_vars/
│ └── staging/
│ ├── hosts.yml
│ └── group_vars/
├── roles/
│ ├── common/
│ ├── nginx/
│ ├── mariadb/
│ └── php/
├── playbooks/
│ ├── site.yml
│ ├── deploy.yml
│ └── security.yml
└── README.md
Ansible transforms server administration from a manual, repetitive activity into an automated, reproducible, and documented process. With a handful of well-written playbooks, you can configure dozens of servers identically in minutes, eliminate human error, and always have a clear picture of your infrastructure's state.
To put everything you've learned into practice, you need a solid infrastructure beneath you. Explore CLIQHOST NVMe VPS plans — fast, reliable, and ready to run Ansible in seconds — or get in touch with our team for a tailored server management plan. You'll also find more Linux and DevOps guides on the CLIQHOST blog.
Real reviews from customers who trust CLIQHOST for performance, reliability and expert technical support.
"We moved our online shop from a foreign host and the difference is night and day — pages load instantly and support replies in minutes, in Romanian."
"Migrated 12 client sites to CLIQHOST. Free migration, zero downtime, and the cPanel setup is exactly what my team needed. Highly recommend."
"Our NVMe VPS handles traffic spikes without a sweat. Full root, local datacenter, and billing in MDL — everything we wanted from a provider."