AI Chat

How to Set Up Ansible for Automated Bare-Metal Server Provisioning

Ansible Bare Metal Server Provisioning
Ask AI to extract steps & commands from this tutorial:

Manually configuring servers one at a time works fine when you have one or two boxes. It stops working the moment you're managing five, ten, or fifty. Ansible is an open-source automation tool that solves this by letting you describe a server's desired configuration — packages, users, firewall rules, services — in a simple text file, then apply that configuration to any number of servers consistently, repeatably, and without logging into each one by hand.

This tutorial covers setting up Ansible for automated bare-metal server provisioning: installing the control tooling, defining your server inventory, writing your first playbooks, and structuring things so the setup scales cleanly as your dedicated server fleet grows.

Why Use Ansible for Bare-Metal Provisioning?

Unlike some automation tools, Ansible does not require installing an agent on every server it manages. It connects over standard SSH and runs tasks defined in playbooks — human-readable YAML files. This makes it a natural fit for bare-metal environments where you want infrastructure-as-code without adding extra software footprint to production servers.

The main benefits for dedicated server fleets:

  • Consistency – every server ends up in the exact same state, removing "it works on this one but not that one" problems.

  • Speed – provisioning a new server becomes a matter of running one command instead of an hour of manual setup.

  • Documentation as code – your playbook is the documentation of how a server is configured.

  • Repeatability – re-running a playbook is safe; Ansible only changes what needs changing.

From experience automating provisioning across mixed server fleets, the biggest practical win isn't raw speed — it's eliminating configuration drift. When every dedicated server, database node, and application host is built from the same version-controlled automation script, you stop debugging "why is this one server different" problems entirely.

This approach scales particularly well across multiple dedicated server deployments, where you may be provisioning identical web, database, or application server roles across several physical machines. eServers UK's bare metal servers ship with full root access on Intel, AMD, or Ampere hardware, which matters here — Ansible needs unrestricted root-level SSH access to apply system-level changes like firewall rules and package installs. It also pairs naturally with a fleet spread across regions — for example, servers in London and Manchester can be provisioned from a single playbook run rather than configured separately by hand.

Ansible vs. Manual Provisioning: Why It's Worth the Setup Time

Writing your first playbook takes longer than just SSHing in and running a few commands. The payoff shows up the second, third, and fiftieth time you provision a server:

Manual Provisioning Ansible Automation
Consistency across servers Depends on memory/notes Guaranteed by the playbook
Time to provision a new server 30–60+ minutes A few minutes per run
Documentation Often outdated or missing The playbook is the documentation
Re-running safely Risk of duplicate/conflicting changes Idempotent — safe to re-run anytime
Onboarding new team members Tribal knowledge Readable YAML anyone can review

For a single test server, manual setup is fine. For a fleet of dedicated servers running production workloads, this gap compounds quickly.

Prerequisites

  • A control node — your local machine or a separate management server where Ansible will be installed.

  • One or more target servers (the bare-metal servers you want to provision), reachable over SSH.

  • SSH key-based access already set up between the control node and target servers.

  • Basic familiarity with YAML syntax.

Step 1: Install Ansible on the Control Node

Ansible only needs to be installed on the control node, not on the servers it manages.

On Ubuntu or Debian:

bash

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

On AlmaLinux or Rocky Linux:

bash

sudo dnf install epel-release -y
sudo dnf install ansible -y
                            

Confirm the installation:


ansible --version
                            

Step 2: Set Up SSH Key Access to Your Target Servers

Ansible connects to remote servers over SSH, so passwordless key-based authentication needs to be in place first.

Generate a key pair on the control node if you don't already have one:

bash

ssh-keygen -t ed25519 -C "ansible-control"
                            

Copy the public key to each target server:


ssh-copy-id root@your_server_ip
                            

Repeat this for every server you plan to manage with Ansible.

Step 3: Create Your Inventory File

The inventory is where you list the servers Ansible will manage, grouped by role. Create a project directory and an inventory file:

bash

mkdir ~/ansible-provisioning && cd ~/ansible-provisioning
nano inventory.ini
                            

Add your servers, grouped logically:

ini

[webservers]
web1 ansible_host=203.0.113.10
web2 ansible_host=203.0.113.11

[dbservers]
db1 ansible_host=203.0.113.20

[all:vars]
ansible_user=root
ansible_ssh_private_key_file=~/.ssh/id_ed25519
                            

Test connectivity to all servers in the inventory:


ansible all -i inventory.ini -m ping
                            

A successful response returns "pong" from each server.

Step 4: Write a Basic Provisioning Playbook

A playbook defines the tasks Ansible should run. Create a file for baseline server hardening and setup:

bash

nano baseline.yml
                            
yaml

---
- name: Baseline provisioning for new dedicated servers
  hosts: all
  become: true

  tasks:
    - name: Update all packages
      apt:
        update_cache: yes
        upgrade: dist
      when: ansible_facts['os_family'] == "Debian"

    - name: Create a non-root sudo user
      user:
        name: deployuser
        groups: sudo
        shell: /bin/bash
        create_home: yes

    - name: Set up SSH key for the new user
      authorized_key:
        user: deployuser
        state: present
        key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"

    - name: Install UFW firewall
      apt:
        name: ufw
        state: present
      when: ansible_facts['os_family'] == "Debian"

    - name: Allow SSH through the firewall
      ufw:
        rule: allow
        name: OpenSSH

    - name: Enable the firewall
      ufw:
        state: enabled
        policy: deny
                            

This playbook updates packages, creates a dedicated non-root user, sets up SSH key access for that user, and enables a firewall — the same baseline hardening steps you'd otherwise do manually on every new server.

Step 5: Run the Playbook

Apply the playbook to every server in your inventory:

bash

ansible-playbook -i inventory.ini baseline.yml
                            

Ansible connects to each target, checks the current state against what the playbook describes, and only makes the changes needed to bring it into compliance. Running the same playbook again later will report "ok" for tasks that are already satisfied, rather than repeating them.

Step 6: Provision Role-Specific Software

Once baseline hardening is handled, you can create additional playbooks for specific server roles. For example, a web server playbook:

bash

nano webserver.yml
                            
yaml

---
- name: Provision web servers
  hosts: webservers
  become: true

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

    - name: Ensure Nginx is running and enabled
      service:
        name: nginx
        state: started
        enabled: true

    - name: Open HTTP and HTTPS ports
      ufw:
        rule: allow
        port: "{{ item }}"
      loop:
        - "80"
        - "443"
                            

Run it against just the webservers group defined in your inventory:


ansible-playbook -i inventory.ini webserver.yml
                            

Step 7: Organise Playbooks with Roles (For Larger Deployments)

As your infrastructure grows, a single large playbook becomes harder to maintain. Ansible roles let you break configuration into reusable, organised components:

bash

ansible-galaxy init roles/webserver
                            

This generates a standard directory structure (tasks/, handlers/, templates/, vars/, defaults/) that keeps large provisioning setups organised and easier to reuse across projects.

Step 8: Keep Secrets Out of Plain Text

Provisioning playbooks often need sensitive values like database passwords or API keys. Ansible includes Ansible Vault for encrypting these values so they are never stored in plain text:

bash

ansible-vault create secrets.yml
                            

You'll be prompted for a password to encrypt the file. Reference vault-encrypted variables in your playbooks as normal, and provide the vault password at runtime:


ansible-playbook -i inventory.ini baseline.yml --ask-vault-pass
                            

Putting It Together

With this setup, provisioning a brand-new dedicated server becomes:

  1. Add the server's IP to your inventory file

  2. Confirm SSH connectivity with ansible all -m ping

  3. Run your baseline playbook

  4. Run any role-specific playbooks (web, database, application)

What used to take an hour of manual SSH sessions now takes a few minutes, with a written, version-controlled record of exactly how each server was configured and provisioned.

Conclusion

Ansible turns bare-metal server provisioning from a manual, error-prone process into a repeatable, version-controlled workflow. Whether you're managing three servers or thirty, defining your configuration as code means every server ends up consistent, every change is documented, and scaling your infrastructure no longer means scaling your manual workload.

If you're building out a fleet of dedicated servers and want hardware that's ready for automated provisioning from day one, get in touch with the eServers UK team. Our engineers can help you plan server specs and network setup across locations to fit your automation workflow.

Frequently Asked Questions

Does Ansible require installing software on the servers it manages? +

No. Ansible is agentless — it connects over standard SSH and only needs Python present on the target server, which is already included by default on virtually every mainstream Linux distribution.

Is Ansible suitable for a small setup, or only large server fleets? +

It scales in both directions. Even with two or three dedicated servers, having your configuration as a version-controlled playbook rather than tribal knowledge makes rebuilding or replacing a server far less risky.

What's the difference between a playbook and a role? +

A playbook is a single YAML file describing tasks to run. A role is a structured, reusable collection of tasks, templates, and variables — useful once your playbooks grow large enough that organising them by server function (web, database, cache) becomes worthwhile.

Can Ansible manage servers running different operating systems in the same playbook? +

Yes, using conditionals like when: ansible_facts['os_family'] == 'Debian', as shown in this guide. This lets a single playbook adapt its commands correctly across Ubuntu, Debian, AlmaLinux, and Rocky Linux targets.

Discover eServers Dedicated Server Locations

eServers provides reliable dedicated servers across multiple global regions. Whether you need low latency, regional compliance, or proximity to your audience, our wide geographic coverage ensures the perfect hosting environment for your project.

Our Bandwidth providers

We are Partners with 15 +

At eServers , we proudly partner with 15+ leading global tech providers to deliver secure, high-performance hosting solutions. These trusted alliances with top hardware, software, and network innovators ensure our clients benefit from modern technology and enterprise-grade reliability.

Hosting Solutions