How To Execute Ansible Playbooks to Automate Server Setup

Configuration ManagementAnsibleAutomated Setups


Ansible is a modern configuration management tool that facilitates the task of setting up and maintaining remote servers. With a minimalist design intended to get users up and running quickly, it allows you to control one to hundreds of systems from a central location with either playbooks or ad hoc commands.

While ad hoc commands allow you to run one-off tasks on servers registered within your inventory file, playbooks are typically used to automate a sequence of tasks for setting up services and deploying applications to remote servers. Playbooks are written in YAML, and can contain one or more plays.

This short guide demonstrates how to execute Ansible playbooks to automate server setup, using an example playbook that sets up an Nginx server with a single static HTML page.


In order to follow this guide, you’ll need:

  • One Ansible control node. This guide assumes your control node is an Ubuntu 20.04 machine with Ansible installed and configured to connect to your Ansible hosts using SSH keys. Make sure the control node has a regular user with sudo permissions and a firewall enabled, as explained in our Initial Server Setup guide. To set up Ansible, please follow our guide on How to Install and Configure Ansible on Ubuntu 20.04.
  • One or more Ansible hosts. An Ansible host is any machine that your Ansible control node is configured to automate. This guide assumes your Ansible hosts are remote Ubuntu 20.04 servers. Make sure each Ansible host has:
    • The Ansible control node’s SSH public key added to the authorized_keys of a system user. This user can be either root or a regular user with sudo privileges. To set this up, you can follow Step 2 of How to Set Up SSH Keys on Ubuntu 20.04.
  • An inventory file set up on the Ansible control node. Make sure you have a working inventory file containing all your Ansible hosts. To set this up, please refer to the guide on How To Set Up Ansible Inventories.

Once you have met these prerequisites, run a connection test as outlined in our guide on How To Manage Multiple Servers with Ansible Ad Hoc Commands to make sure you’re able to connect and execute Ansible instructions on your remote nodes. In case you don’t have a playbook already available to you, you can create a testing playbook as described in the next section.

Creating a Test Playbook

To try out the examples described in this guide, you’ll need an Ansible playbook. We’ll set up a testing playbook that installs Nginx and sets up an index.html page on the remote server. This file will be copied from the Ansible control node to the remote nodes in your inventory file.

Create a new file called playbook.yml in the same directory as your inventory file. If you followed our guide on how to create inventory files, this should be a folder called ansible inside your home directory:

  • cd ~/ansible
  • nano playbook.yml

The following playbook has a single play and runs on all hosts from your inventory file, by default. This is defined by the hosts: all directive at the beginning of the file. The become directive is then used to indicate that the following tasks must be executed by a super user (root by default).

It defines two tasks: one to install required system packages, and the other one to copy an index.html file to the remote host, and save it in Nginx’s default document root location, /var/www/html. Each task has tags, which can be used to control the playbook’s execution.

Copy the following content to your playbook.yml file:

- hosts: all
  become: true
    - name: Install Packages
      apt: name={{ item }} update_cache=yes state=latest
      loop: [ 'nginx', 'vim' ]
      tags: [ 'setup' ]

    - name: Copy index page
        src: index.html
        dest: /var/www/html/index.html
        owner: www-data
        group: www-data
        mode: '0644'
      tags: [ 'update', 'sync' ]

Save and close the file when you’re done. Then, create a new index.html file in the same directory, and place the following content in it:

        <title>Testing Ansible Playbooks</title>
        <h1>Testing Ansible Playbooks</h1>
        <p>This server was set up using an Nginx playbook.</p>

Don’t forget to save and close the file.

Executing a Playbook

To execute the testing playbook on all servers listed within your inventory file, which we’ll refer to as inventory throughout this guide, you may use the following command:

  • ansible-playbook -i inventory playbook.yml

This will use the current system user as remote SSH user, and the current system user’s SSH key to authenticate to the nodes. In case those aren’t the correct credentials to access the server, you’ll need to include a few other parameters in the command, such as -u to define the remote user or --private-key to define the correct SSH keypair you want to use to connect. If your remote user requires a password for running commands with sudo, you’ll need to provide the -K option so that Ansible prompts you for the sudo password.

More information about connection options is available in our Ansible Cheatsheet guide.

Listing Playbook Tasks

In case you’d like to list all tasks contained in a playbook, without executing any of them, you may use the --list-tasks argument:

  • ansible-playbook -i inventory playbook.yml --list-tasks
playbook: nginx.yml play #1 (all): all TAGS: [] tasks: Install Packages TAGS: [setup] Copy index page TAGS: [sync, update]

Listing Playbook Tags

Tasks often have tags that allow you to have extended control over a playbook’s execution. To list current available tags in a playbook, you can use the --list-tags argument as follows:

  • ansible-playbook -i inventory playbook.yml --list-tags
playbook: nginx.yml play #1 (all): all TAGS: [] TASK TAGS: [setup, sync, update]

Executing Tasks by Tag

To only execute tasks that are marked with specific tags, you can use the --tags argument, along with the tags that you want to trigger:

  • ansible-playbook -i inventory playbook.yml --tags=setup

Skipping Tasks by Tag

To skip tasks that are marked with certain tags, you may use the --exclude-tags argument, along with the names of tags that you want to exclude from execution:

  • ansible-playbook -i inventory playbook.yml --exclude-tags=setup

Starting Execution at Specific Task

Another way to control the execution flow of a playbook is by starting the play at a certain task. This is useful when a playbook execution finishes prematurely, in which case you might want to run a retry.

  • ansible-playbook -i inventory playbook.yml --start-at-task=Copy index page

Limiting Targets for Execution

Many playbooks set up their target as all by default, and sometimes you want to limit the group or single server that should be the target for that setup. You can use -l (limit) to set up the target group or server in that play:

  • ansible-playbook -l dev -i inventory playbook.yml

Controlling Output Verbosity

If you run into errors while executing Ansible playbooks, you can increase output verbosity in order to get more information about the problem you’re experiencing. You can do that by including the -v option to the command:

  • ansible-playbook -i inventory playbook.yml -v

If you need more detail, you can use -vv or -vvv instead. If you’re unable to connect to the remote nodes, use -vvvv to obtain connection debugging information:

  • ansible-playbook -i inventory playbook.yml -vvvv


In this guide, you’ve learned how to execute Ansible playbooks to automate server setup. We’ve also seen how to obtain information about playbooks, how to manipulate a playbook’s execution flow using tags, and how to adjust output verbosity in order to obtain detailed debugging information in a play.

Creative Commons License