Ansible Container is a set of tools that builds upon concepts introduced earlier in this chapter in order to provide a comprehensive workflow for container development, testing, and deployment. Since the last release of this book, a stable release has become available.
At the time of writing, Ansible Container does not get installed with Ansible, and it must be installed separately. It can be installed from pypi as the package name ansible-container, or it can be installed from the source repository (https://github.com/ansible/ansible-container.git). At the time of writing this book, ansible-container has some quite exacting requirements for the Python environment; specifically, docker-py must be removed, and only version 2.7.0 of the docker Python module can be installed. Also note there is (at the time of writing) a known issue in the interaction between the latest version of ansible-container and the docker module, and the docker module must be patched manually for this to work. Hopefully in future this will be fixed—however, at the time of writing this is still required.
To successfully install it on our CentOS 7 demo machine, I had to issue the following commands:
sudo pip uninstall docker-py
sudo pip uninstall docker
sudo pip install docker==2.7.0
sudo sed -i "s/return os.path.join(os.sep, 'run', 'secrets')/return os.path.join(os.sep, 'docker', 'secrets')/g" /usr/lib/python2.7/site-packages/container/docker/engine.py
sudo pip install -U setuptools
sudo pip install "ansible-container[docker,openshift]"
With Ansible Container, we can define one or more services to containerize. These are defined in a YAML file that closely follows the Docker Compose version 2 schema (support for the version 2 schema was added in the 0.3.0 release of ansible-container). Each service that's defined becomes a container and is exposed as an Ansible host. These hosts are used by a playbook file to perform all of the necessary configurations to prep the container to run the service. Additional files can be used to define any Python library requirements for modules used by the playbook, the Ansible Galaxy role dependencies of the playbook, the Ansible Galaxy metadata for sharing the project, and an Ansible configuration file used with the playbook.
The main executable of Ansible Container is ansible-container, which includes a number of sub-commands:
- init: The init sub-command will create the required directory structure and template files for a new Ansible Container project within the current directory. Optionally, it can connect to Ansible Galaxy and use a project template to pre-populate some of the files; otherwise, they will mostly be created blank.
- build: The build sub-command is used to launch the containers for each service defined, and one container with Ansible inside of it, which is used to run the playbook against the service containers. Once the playbook is finished, images are created from the configured containers.
- run: The run sub-command will launch new containers for each service using the images created during the build phase.
- stop: The stop sub-command will stop containers launched by a run sub-command.
- push: The push sub-command will upload the built images to a target Docker image registry.
- shipit: The shipit sub-command will generate Ansible content to deploy containers from built images into container orchestration platforms, such as Kubernetes or Red Hat OpenShift:
To demonstrate Ansible Container, we'll reproduce our previous Docker service container to display cowsay via a web server and run it locally.