Ansible + Ansible Tower + Docker


June 16, 2016


Levvel + Ansible

Levvel’s DevOps Team recently attended training at Ansible’s Headquarters in Durham, NC. Ansible is one of the top contenders in the IT Automation space and with its recent acquisition by RedHat, the Ansible team has made significant inroads into the Enterprise.


In 2012 the tech world was introduced to Ansible, a free and open-source software that is predominately used for IT Automation, Configuration Management, Software Deployments, and even ad-hoc command execution on remote systems.

Ansible works by connecting to remote hosts via SSH and executes commands on those systems. The initial appeal of Ansible is its agentless structure, unlike other configuration management tools that require some sort of agent or service/daemon to be running on remote hosts in order to use it.

Today we’ll learn a little about Ansible as a powerful configuration management and automation tool that can effortlessly manage thousands of remote hosts. We’ll also will shed some light on Ansible Tower a visual dashboard that centralizes your infrastructure and has lots of Enterprise-ready features. We’ll top it off with a look into Docker integration with Ansible and how Ansible can be used to manage a Dockerized infrastructure.

Why Ansible?

  • Ansible is Agentless

    Ansible doesn’t require an agent on the remote hosts to be able to execute commands and manage tasks. Unlike Chef and Puppet, Ansible only require an existing transport mechanism between the executor and the remote hosts, for Linux machines that means SSH connection using either OpenSSH or paramiko, for Windows environment that means Windows Remote Management via PowerShell remoting.

  • Ansible is Modular

    Ansible uses modules to manage tasks on the remote hosts, task such as installing a new package on a Debian based remote systems using the apt module, or to enabling a cronjob on a remote system using the cron module:

    apt: name=nginx state=latest

    There are hundreds of modules that manage everything from installing a simple package to managing complex integrations with cloud environments like AWS. Each module serves one purpose and you can easily develop your own module using any programming language to do a specific job on the remote host.

  • Ansible is the most concise CM tool

    Ansible has an extremely low learning curve, a very simple syntax, and its configuration is a simple description of your infrastructure. All of this is expressed in YAML with no need to learn a wonky DSL. Your development team won’t need to learn a new programming language and can start using Ansible right away.

Hello World Ansible Playbook

The playbook is the design plan that you will enforce on the remote host and is the configuration file that contains the tasks to be executed using Ansible’s modules.

Playbooks can declare configurations, but they can also orchestrate steps of any manually ordered process. It’s designed to be easily human-readable and viewed as an ordered lists of tasks that you can execute on remote hosts.

The following is an example of playbook that runs on all remote hosts designated as a webservers, installs Nginx and starts the service:


- hosts: webservers
  become: yes
    - name: Install Nginx
      apt: name=nginx update_cache=yes state=latest

    - name: Start Nginx Service
      service: name=nginx state=started

This is considered a play, which runs on hosts designated as webservers defined in an inventory file. This play executes two tasks using two different modules: (apt) and (service).

To run this simple playbook, you can use the

$ ansible-playbook

command and define the webservers hosts in the inventory file like this:


And run the ansible playbook using the following command:

$ ansible-playbook -i inventory_file playbook.yml
PLAY [webservers] **************************************************************

TASK [setup] *******************************************************************
ok: [x.x.x.x]

TASK [Install Nginx] ***********************************************************
changed: [x.x.x.x]

TASK [Start Nginx Service] *****************************************************
changed: [x.x.x.x]

PLAY RECAP *********************************************************************
x.x.x.x              : ok=3    changed=2    unreachable=0    failed=0

The recap of this playbook show us that that two tasks are in state changed which indicates that two changes are made on the remote hosts (installing Nginx and starting the service), if we try to execute the playbook again we see Configuration Management idempotency in action:

$ ansible-playbook -i inventory_file playbook.yml 

PLAY [webservers] **************************************************************

TASK [setup] *******************************************************************
ok: [x.x.x.x]

TASK [Install Nginx] ***********************************************************
ok: [x.x.x.x]

TASK [Start Nginx Service] *****************************************************
ok: [x.x.x.x]

PLAY RECAP *********************************************************************
x.x.x.x              : ok=4    changed=0    unreachable=0    failed=0

The “ok” indicates that the change you want to enforce on the remote host already exists and there is no need to repeat the process.

Check out Ansible’s great documentation to learn more. Ansible Tower

With Ansible Tower, you can centralize and control your Ansible infrastructure with a visual dashboard, role-based access control, job scheduling, and graphical inventory management. Tower’s REST API and CLI make it easy to embed Tower into existing tools and processes.

Tower supports other great features too, like push button deployment where users can run a playbook with just one click remote execution command features for ad-hoc commands and real-time output of audit and compliance reports. Try it for free

Ansible Tower offers a free license to manage up to 10 nodes.

root@localhost:~$ apt-get install software-properties-common
root@localhost:~$ apt-add-repository ppa:ansible/ansible
root@localhost:~$ apt-get update
root@localhost:~$ apt-get install ansible

The server should be at least 2 GB RAM with 20 GB dedicated space on the disk for the installation and managing jobs.

There are different scenarios for Ansible Tower installation but in this example we’ll use a simple setup.

# wget
# tar xvzf ansible-tower-setup-latest.tar.gz
# cd ansible-tower-setup-2.4.5

The installation archive is itself an Ansible playbook you can run using the $ ./configure script. Use the -l option with the configure script to indicate that you will be installing Ansible on the same local machine:

~/ansible-tower-setup-2.4.5# ./configure -l
Welcome to the Ansible Tower Install Wizard

This wizard will guide you through the setup process.

You are installing Ansible Tower on this machine, using an internal database.

For security reasons, since this is a new install, you must specify the
following application passwords.

Enter the desired Ansible Tower admin user password: xxxxxxx
Enter the desired Munin password: xxxxxxx

You selected the following options:

The primary Tower machine is: localhost
Tower will operate on an INTERNAL database.

Are these settings correct (y/n)? y
Settings saved to /root/ansible-tower-setup-2.4.5/tower_setup_conf.yml.

You have completed the setup wizard. You may execute the installation of
Ansible Tower by issuing the following command:

sudo ./

The script will run a playbook to install Tower and it’s backing services. You’ll now be able to access the Tower web app using the server’s IP address:


Once logged in and registered with a free license, you can start experimenting with Tower.


There are a few key things to keep in mind with Ansible Tower:

Credentials and Permissions

Credentials are utilized by Tower for authentication when launching jobs against machines, synchronizing with inventory sources, and importing project content from a version control system.

Tower credentials are imported and stored encrypted in Tower, and are not retrievable in plain text on the command line by any user. Once a password or key has been entered into the Tower interface, it is encrypted and inserted into the Tower database, and cannot be retrieved from Tower. You can grant users and teams the ability to use these credentials, without actually exposing the credential to the user. If you have a user move to a different team or leave the organization, you don’t have to re-key all of your systems just because that credential was available in Tower.


Permissions are general user rights for job templates and inventories, allowing them to run certain playbooks on designated hosts.

There are three types of Tower Users:

Normal User: read and write access is limited to the inventory and projects for which that user has been granted the appropriate rights.

Organization Administrator: the administrator of an organization has all of the rights of a normal user, as well as admin, read, and write permission over the entire organization and all of its inventories and projects, but does not have those levels of access on content belonging to other organizations. This level of user can create and manage users.

Superuser: a Tower Superuser has admin, read, and write permissions over the entire Tower installation. A Superuser is typically a systems administrator responsible for managing Tower and will delegate responsibilities for day-to-day work to various Organization Administrators.

Credentials allow access for different destinations, like SSH access to machines, AWS access and/or SCM credentials to access GitHub or Bitbucket.


Projects, Jobs, and Job Templates

A Project is a logical collection of Ansible playbooks, represented in Tower.

You can manage playbooks and playbook directories by either placing them manually under the Project Base Path on your Tower server, or by placing your playbooks into a source code management (SCM) system supported by Tower, including Git, Subversion, and Mercurial.

A job template is a definition and set of parameters for running an Ansible job. Job templates are useful to execute the same job many times. While the REST API allows executing jobs directly, Tower requires first creating a job template.

A job is an instance of Tower launching an Ansible playbook against an inventory of hosts.

The Jobs link displays a list of jobs and their status–shown as completed successfully or failed, or as an active (running) job.

Tower Integrations

To integrate Tower with BitBucket, you can open the credentials tab, choose the source control credential type and add private key / username and password combinations that will be used to pull updates from your Git repository:


The addition of AWS credentials allows easy provisions and configurations in the cloud.


To get an idea of how Tower works with AWS, let’s create 10 centos 6.5 EC2s on AWS:


Then add inventory to sync the hosts from AWS to Ansible Tower.


After that we’ll sync our EC2 instances.


You can see that the 10 instances are synced correctly. Now it’s time to add a project and run a playbook:


Next we’ll set up a job template that contain a playbook to install WordPress on the EC2 instances.


Finally, run the job template and check the output in real time:



Ansible With Docker

The Docker module in Ansible can manage Docker containers and it can build images from a dockerfile or run images on remote hosts.

- name: Create a wordpress docker container  
     name: wordpress  
     image: wordpress:{{ wordpress_version }}  
     detach: True  
     - 80:80  
     env: RANCHER_NETWORK=true,  
          WORDPRESS_DB_HOST={{ mysql_host }}:3306,  
          WORDPRESS_DB_PASSWORD={{ mysql_root_password }},  
          WORDPRESS_AUTH_KEY={{ wordpress_auth_key }},  
          WORDPRESS_SECURE_AUTH_KEY={{ wordpress_secure_auth_key }},  
          WORDPRESS_LOGGED_IN_KEY={{ wordpress_logged_in_key }},  
          WORDPRESS_NONCE_KEY={{ wordpress_nonce_key }},  
          WORDPRESS_AUTH_SALT={{ wordpress_auth_salt }},  
          WORDPRESS_SECURE_AUTH_SALT={{ wordpress_secure_auth_salt }},  
          WORDPRESS_NONCE_SALT={{ wordpress_nonce_salt }},  
          WORDPRESS_LOGGED_IN_SALT={{ wordpress_loggedin_salt }}

** There are a few prerequisites that needs to be installed on the remote hosts, before running the Docker module. For extra credit use an Ansible playbook to install the following.

• python >= 2.6
• docker-py >= 0.3.0
• The docker server >= 0.10.0

Ansible is an amazing tool with clear benefits across your entire IT organization and Ansible Tower is the clear choice for managing your Ansible-powered infrastructure.

If your organization is ready to increase velocity with the best automation tool on the market, contact us at Levvel DevOps to get started. Additionally, I’ll be representing Levvel at DockerCon 2016 and would be happy to meet you in person. Drop me an email here.

Authored By

James Denman

James Denman

Meet our Experts

James Denman

James Denman

Let's chat.

You're doing big things, and big things come with big challenges. We're here to help.

Read the Blog

By clicking the button below you agree to our Terms of Service and Privacy Policy.

levvel mark white

Let's improve the world together.

© Levvel & Endava 2023