Oct 31, 2018

14 min read

Ansible security playbook for your VPS (part 1)

Written by

Vippy The VPS

In our last Ansible tutorial, we covered the basics of using Ansible for configuration management, which can help you get new servers set up faster and more reliably.

But the Ansible security playbook that we created there was pretty basic, so I thought we would show create a new playbook that supports more security out of the box without sacrificing normal access to the server.

The goals for this Ansible security playbook are:

  • Set up a non-root user with sudo access
  • Upgrade all installed packages
  • Install a few basic packages to make initial management easier, like nano. These can be easily customized according to your needs
  • Copy your SSH key to the VPS to enable password-less logins
  • Harden SSH with some basic security measures, such as disabling root and password-based logins
  • Install iptables if needed, and set up some basic restrictions to improve security
  • Install fail2ban to help prevent brute force attacks

(The final two steps will be outlined in part 2 of this Ansible security tutorial).

The goal here isn't to have you copy the code here and recreate your own playbook-- it's to teach you how to do it for yourself.

We'll walk you through the various components step-by-step so that you can use this playbook as a foundation for your own customizations.

And this playbook isn't comprehensive when it comes to security for your VPS—once you provision the server using this playbook, you may want to research some additional steps, such as using Lynis to audit your security.


  1. A newly-provisioned or rebuilt server running any of our OS options—CentOS, Debian, or Ubuntu.
  2. Ansible installed on your local machine— see these instructions for more details
  3. An Ansible hosts file set up with the IP(s) of your server(s)—see Step 2 of our previous tutorial


Step 1. Setting up the playbook structure

Ansible playbooks can be structured in a number of different ways, but the developers do have their recommendations.

This Ansible script is still relatively simple compared to what's possible with the system, so our structure is going to be far simpler as well.

Here's the general structure we're following:



If you want, you can go ahead and create the directories now, just to give you a better sense as to how the playbook separates its logic into different areas.

Step 2. Creating provision.yml

The provision.yml file is the core of our playbook—it's where we define which servers we're going to be working with, a few global variables, and tell Ansible where to look for its tasks.

- name: Provision a new server with hardened SSH and basic iptables.

  # Specify the hosts you want to target
  hosts: HOSTNAME

  # Specify the user you want to connect to the server.
  # With a new installation, you will connect with root. If you want to
  # re-run this playbook at a later date, you should change remote_user to
  # the user you specified under vars/username below and uncomment the
  # become: true line. You should then run the playbook using the
  # --ask-become-pass flag, like so:
  # ansible-playbook -k provision.yml --ask-become-pass.
  remote_user: root
  # become: true

    username: USER
    # Before first using the playbook, run the below command to create a hashed
    # password that Ansible will assign to your new user.
    # python
Continue reading this article
by subscribing to our newsletter.
Subscribe now

A note about tutorials: We encourage our users to try out tutorials, but they aren't fully supported by our team—we can't always provide support when things go wrong. Be sure to check which OS and version it was tested with before you proceed.

If you want a fully managed experience, with dedicated support for any application you might want to run, contact us for more information.