playing with Ansible container
2017-03-16 UPDATE - I’m not sure I see a good use case for Ansible container. It’s neat, but at this time it comes off as overly complicated and REALLY slow. Maybe it will advance and become interesting, but right now, a Dockerfile
seems better in many ways.
Using ansible-container, the post covers creating Docker images, specifically images for development with AWS and Azure. It will configure the images accordingly, using Ansible playbooks and roles.
background
Managing Docker can be somewhat unweildy. Dockerfiles are essentially a giant bash script. Ansible-container can help with that and provide a way of managing that lifecycle.
This post walks through the installation of ansible-container and the creation of a few images and containers. In this example, their are two images, awsdev
and azuredev
. awsdev
installs the necessary developer tools to work with AWS, and azuredev
installs the necessary tools to work with Azure. They’re good for interactive examples. These containers are most useful when working from OS X development platforms and there is value in isolating those tools and environments. Can be a nicer setup than running full-blow VMs.
All steps are run from the ansible-container directory within the git project playbook, which can found here.
installing ansible-container
The first step is installing ansible-container
, which has just hit 0.2.0. There are bugs, that comes with the territory of new software.
To install, simply run the environment.sh
script here. This will:
- If the Python virtual environment is not created, creates it.
- Install the necessary Ansible tools via pip.
- Installs ansible-container.
See the README.md for information.
a look at the ansible-container container.yml and main.yml
Ansible-container has an init
command which will create the directory structure. Running this will create an ansible folder with container.yml
, main.yml
, and requirements.txt
files. Pretty straightforward:
(env) % ansible-container init
Ansible Container initialized.
(env) % ls ansible/
ansible.cfg container.yml main.yml requirements.txt requirements.yml
-
ansible.cfg
is the Ansible configuration file. Standard Ansible fare. -
The
container.yml
file is where the Docker image and container settings are defined. This is a Jinja templated file (as of 0.2!), which means we can use the same Ansible logic and variables. The best way to describe this file is directly from the docs themselves:
The container.yml file is very similar to the Docker Compose version 1 schema. Much like Docker Compose, this file describes the orchestration of your app. Ansible Container uses this file to determine what images to build, what containers to run and connect, and what images to push to your repository. Additionally, when Ansible Container generates an Ansible role to ship and orchestrate your images in the cloud, this file describes the configuration that role ensures is met.
As described, this is where the Docker orcestration can come into play. This is also where dev environments vs deployment environments can be configured. More information on container.yml
can be found here. In the future, I would like to explore this more (see future improvements
below). For now, the Docker URL and Docker namespace are the only variables set within this file.
-
main.yml
is the Ansible playbook that configures the Docker containers. Each image within thecontainer.yml
file is added to the Ansible inventory. Adding it to thehost
list will have Ansible configure that Docker image much like it was a standard system being configured by Ansible. -
requirements.txt
is the Python requirements file for ansible-container. -
requirements.yml
is the Ansible yaml file that installs the necessary Ansible-galaxy roles. Something to dig into.
build an image with roles
Now that some of the basics First step, source the Python virtual env:
% cd /path/to/playbook/ansible-container
% ./environment.sh
% source ./env/bin/activate
Environment set. Running ansible-container version
should reveal:
(env) % ansible-container version
Ansible Container, version 0.2.0
Using the 0.2.0
pre-release version, as it has some new notable features (the ability to use custom Ansible roles path being one of them).
To build the images from the git project:
cd devcontainers
ansible-container --debug build --with-volumes /full/path/to/playbook/ansible-roles:/roles
This will run the main.yml
Ansible playbook against all Docker images/containers defined within container.yml
. Each container defined is treated as part of the Ansible inventory and is added to the Ansible inventory. It will take a while; Hopefully because it’s a 0.2.0 version, it’s slow and this isn’t the final speed. You can leave out the --debug
, at this point in ansible-container’s development cycle, it’s useful.
Note the ansible.cfg
file. Note the path of the roles
. This is actually the path WITHIN the ansible-container Docker image (ansible/ansible-container-builder
), which gets volume mounted into the container.
Taking a look at the docker images, this is what gets created:
(env)% docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ansible-container-awsdev 20161008144935 8a10947917dc 32 minutes ago 1.006 GB
ansible-container-awsdev latest 8a10947917dc 32 minutes ago 1.006 GB
ansible-container-azuredev 20161008144935 1236277b974c 32 minutes ago 973.6 MB
ansible-container-azuredev latest 1236277b974c 32 minutes ago 973.6 MB
ansible/ansible-container-builder 0.2 6a0481cdff24 10 days ago 710.6 MB
run the container
ansible-container can run the container as well. This is far more useful when the container.yml
is a bit more in depth and there’s actual intra-container orchestration needed. A future playbook will include something that can use this functionality.
push the images
When pushing, the variables docker_url
and docker_namespace
are needed. These are variables defined in container.yml
. Note if a different repository is used, edit the file as needed. Push also requires the --with-volumes
option, as Push uses the ansible-container inventory and loads the main.yml
playbook:
ansible-container --debug push --with-volumes /full/path/to/playbook/ansible-roles:/roles --with-variables docker_url=https://YOUR.DOCKERREGISTRY.COM,docker_namespace=YOURNAMESPACE
Again, debug is useful to see any isuses that pop up. It is 0.2 software after all. After pushing, it will create another tag. Note the image list now:
(env)% docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ansible-container-awsdev 20161008144935 8a10947917dc 32 minutes ago 1.006 GB
ansible-container-awsdev latest 8a10947917dc 32 minutes ago 1.006 GB
bcawthra/ansible-container-awsdev 20161008144935 8a10947917dc 32 minutes ago 1.006 GB
ansible-container-azuredev 20161008144935 1236277b974c 32 minutes ago 973.6 MB
ansible-container-azuredev latest 1236277b974c 32 minutes ago 973.6 MB
bcawthra/ansible-container-azuredev 20161008144935 1236277b974c 32 minutes ago 973.6 MB
ansible-container-awsdev 20161008144710 545a9a293e09 34 minutes ago 937.5 MB
ansible-container-azuredev 20161008144710 bfbd10c20d36 34 minutes ago 904.8 MB
ansible/ansible-container-builder 0.2 6a0481cdff24 10 days ago 710.6 MB
conclusion
Interesting tool. Good for creating custom images using a known Ansible process, especially if there is invested knowledge in Ansible. When teamed up with Kubernetes, it can provide an excellent platform for deploying a stack both locally for development and to a Docker platform. I’m going to dig into some of these features in the future.
future improvements
- Configure containers and images that build a stack of something, such as ELK, Prometheus/Alertmanager/Grafana, or some other multiple component tool.
- Configure
container.yml
to support both a local development environment and some Docker platform (most likely Kubernetes). - Configure
container.yml
with additional Ansible/Jinja variables.
links
- ansible-container on Github - https://github.com/ansible/ansible-container
- ansible-container docs - https://docs.ansible.com/ansible-container/
- ansible-container container.yml - https://docs.ansible.com/ansible-container/container_yml/index.html