Skip to content

Ansible Docker Framework

The purpose of this project is to provide a Docker based framework to use the full power of the Ansible Framework on any host without having to install any dependencies (expect Docker of course). With this environment you will be able to run the Ansible Framework for any number of inventories in parallel - and safely.

Getting started

Preparation

Docker

Most important, Docker needs to be installed first. If Docker is not yet installed on your host, please refer to the Docker Documentation

Global variables for all inventories

You can define certain variables which will be made available to all inventory containers automatically.

Global variables go into /etc/ansible.yml and may contain information about GitLab and Mattermost but also many other things you will need globally, e.g.:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
gitlab_issue:
  url: 'https://gitlab.lakedrops.com'
  token: '[PRIVATETOKEN]'

inventories:
  - 'name1'
  - 'name2'

mattermost_hooks:
  name1: 'https://mattermost.lakedrops.com/hooks/[TOKEN1]'
  name2: 'https://mattermost.lakedrops.com/hooks/[TOKEN2]'

In this example, name1 and name2 are examples/placeholders for real inventory names that you're working with. You can find the list of available inventories in this GitLab group where you can grab the name(s) for each inventory.

The [TOKENs] for Mattermost are available from each of the inventories project pages.

The [PRIVATETOKEN] can be generated on your GitLab Profile.

Installation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
docker pull registry.lakedrops.com/docker/ansible:latest

# On Ubuntu and other Linux systems:
docker run -it --rm \
    --volume ~/.a:/root/.a \
    --volume /etc/ansible.yml:/etc/ansible.yml \
    --volume /etc/ansible/facts.d:/etc/ansible/facts.d \
    --volume /usr/local/bin:/usr/local/bin \
    registry.lakedrops.com/docker/ansible:latest

# On MacOS:
docker run -it --rm \
    --volume ~/.a:/root/.a \
    --volume /private/etc/ansible.yml:/etc/ansible.yml \
    --volume /private/etc/ansible/facts.d:/etc/ansible/facts.d \
    --volume ~/bin:/usr/local/bin \
    registry.lakedrops.com/docker/ansible:latest

This process is setting up your localhost as the Ansible master based on Docker and it creates 2 scripts (dans and dans-all) in your /usr/local/bin (or ~/bin on MacOS) directory. Those 2 scripts are used to operate Ansible tasks on all your different inventories you have access to.

Notes on MacOS: Probably the ~/bin directory is not included in your search path for executables. If so, please make sure to add it first.

Usage

Login to the LakeDrops Docker repository

The Ansible Docker images for the inventories are private and can only be downloaded and used by authenticated users.

1
docker login registry.lakedrops.com

This asks for your username and password for that registry which is the same as your credentials for LakeDrops GitLab - you only need to login once, your authentication is persistent on your localhost and normally you shouldn't have to re-login in the future, unless Docker asks you to do so again in case the authentication expired.

Download and later update your Docker images

For each inventory you will get an individual Docker image. Those images bring everything with them, you don't have to configure anything. To initially download and later update any of your inventory images, call

1
dans INVENTORYNAME update

This will download the Docker image for that inventory and start a Docker container for it which you can then start using for all your Ansible operations. If you operate with mutliple inventories, you can also update them all at once with the second script

1
dans-all update

This works for all commands also explained below, dans INVENTRORYNAME works for the fiven inventory only where dans-all works for all available inventories at once.

Running Ansible commands

To get a list of all prepared Ansible scripts, call

1
dans INVENTORYNAME

without any further arguments. This will give you a long list of scripts and to learn more about any of them just call

1
dans INVENTORYNAME SCRIPT --help

To run a playbook which isn't covered by a script (yet), you can use the script called playbook which even allows you to run a custom playbook that's only available for a specific inventory, e.g.

1
dans INVENTORYNAME playbook deploy --custom=yes

Note, that you can always add more arguments to the end of the command. Those will be passed through the Ansible and have therefore to be supported by the utilized Ansible executable.

Shell into Ansible inventory containers

Sometimes, e.g. for testing or debugging purposes, you may want to get into one of the containers which is easy with

1
dans INVENTORYNAME exec

Execute Ansible command directly

To execute commands directly (without roles or playbooks), Ansible comes with a shell script the call any Ansible module or plugin with some arguments for quick on-off tasks. You can also call them in this context by calling

1
dans INVENTORYNAME direct MODULE ARGUMENTS

Example to receive filtered facts from remote hosts:

1
dans name1 direct setup "filter=ansible_*_mb"

Other commands

For each inventory you downloaded a separate Docker image, and a named Docker container for each of them is running in the background. There are a few extra commands for those containers:

Start a container for an inventory

1
dans INVENTORYNAME start

Stop a container for an inventory

1
dans INVENTORYNAME stop

Stop and remove a container for an inventory

1
dans INVENTORYNAME remove

Debug an inventory

1
dans INVENTORYNAME debug

Force update for an inventory

1
dans INVENTORYNAME forceupdate

Troubleshooting

This suite has been tested on Ubuntu and MacOS but of course, things can still go wrong. In this section we are collecting recommendations on what you can do in case, things are not working.

Ansible is very slow

By default, Ansible sends log messages to your host on port 24224 where a FluentD service could be listening which stores those logs for later investigation. If no service is listening, this is usually ignored, but we've seen some hosts where this slows down Ansible startup time significantly. For those cases, you should explicitly turn off FluentD logging with these steps:

Edit or create the file ~/.a/environment and add a line FLUENTD_LOGGING=no. Then force updating your containers by calling dans INVENTORYNAME forceupdate.

Ansible reports errors UNREACHABLE

This can have a lot of reasons. Please check the following options:

  • Are your credentials (remote username and password) correct? You know, typos can happen. So please check the files ~/.a/environment for the username and ~/.a/variables.yml for the password. If one of them contained a mistake, please correct that and update your container with dans INVENTORYNAME update
  • Is your private key contained in ~/.ssh/id_rsa the correct one for the hosts in your inventory? If not, please correct that and update the container.

If none of that helps, please run dans INVENTORYNAME debug and copy the very verbose output into an issue here in this project, so that we can analyze the problem further.

SSH ControlMaster not working in your environment

In some environments, the SSH ControlMaster is not working properly so that we included the option to disable it. To do that, edit the file /etc/ansible.yml on your host and add the following definition:

1
custom_disable_controlmaster: true

Save the file, Update your Ansible Docker Framework and then update your container with dans INVENTORYNAME update which should from then on always ignore the ControlMaster.