A tool which builds container images using Ansible playbooks
Project description
ansible-bender
This is a tool which bends containers using Ansible playbooks and turns them into container images. It has a pluggable builder selection — it is up to you to pick the tool which will be used to construct your container image. Right now the only supported builder is buildah. More to come in the future. Ansible-bender (ab) relies on Ansible connection plugins for performing builds.
tl;dr Ansible is the frontend, buildah is the backend.
I described the concept in following blog posts:
You may be asking: why not ansible-container? Ansible bender is actually heavily inspired by ansible-container: the main distinction is that ansible-container covers the complete lifecycle of a containerized application while ab takes care of image builds only.
Status: ready to use
Features:
- You can build your container images with buildah as a backend.
- Ansible playbook is your build recipe.
- You are able to set various image metadata via CLI or as specific Ansible vars:
- working directory
- environment variables
- labels
- user
- default command
- exposed ports
- You can do volume mounts during build.
- Caching mechanism:
- Every task result is cached as a container image layer.
- You can turn this off with
--no-cache
. - You can disable caching from a certain point by adding a tag
no-cache
to a task.
- You can stop creating new image layers by adding tag
stop-layering
to a task. - If an image build fails, it's committed and named with a suffix
-failed
(so you can take a look inside and resolve the issue). - The tool tries to find python interpreter inside the base image.
- You can push images you built to remote locations such as:
- a registry, a tarball, docker daemon, ...
podman push
is used to perform the push.
Interface
Ansible-bender has these commands:
Command | Description |
---|---|
build |
build a new container image using selected playbook |
list-builds |
list all builds |
get-logs |
display build logs |
inspect |
provide detailed metadata about the selected build |
push |
Push images you built to remote locations. |
Installation
$ pip3 install ansible-bender
If you are brave enough, please install bender directly from git master:
$ pip3 install git+https://github.com/TomasTomecek/ansible-bender
If pip3
command is not available on your system, you can run pip like this:
$ python3 -m pip install ...
Requirements (host)
Pip takes care of python dependencies, but ab also requires a few binaries to be present on your host system:
I understand that the last two requirements are pretty tough: you can always run bender in a privileged container.
Requirements (base image)
- python interpreter — ansible-bender will try to find it (alternatively you
can specify it via
--python-interpreter
).- It can be python 2 or python 3 — on host, you have to have python 3 but inside the base image, it doesn't matter — Ansible is able to utilize python 2 even if it's invoked with python 3 on the control machine.
Requirements (Ansible playbook)
None.
Bender copies the playbook you provide so that it can be processed. hosts
variable is being overwritten in the copy and changed to the name of the
working container — where the build happens. So it doesn't matter what's the
content of the hosts variable.
Configuration
You can configure ansible-bender and set metadata on your final image, in order to do that, please check out docs/configuration.md.
Usage
You may noticed that I refer to ansible-bender
as ab. That was the initial
name and I used to it. I recommend adding an alias into your shell rc file:
alias ab="ansible-bender"
Building images
There is a simple playbook present in the root of this repository to showcase the functionality:
$ ansible-bender build ./simple-playbook.yaml
PLAY [Demonstration of ansible-bender functionality] ****************************************
TASK [Gathering Facts] **********************************************************************
ok: [a-very-nice-image-20190302-153257279579-cont]
TASK [Run a sample command] *****************************************************************
changed: [a-very-nice-image-20190302-153257279579-cont]
caching the task result in an image 'a-very-nice-image-20193302-153306'
TASK [Stat a file] **************************************************************************
ok: [a-very-nice-image-20190302-153257279579-cont]
caching the task result in an image 'a-very-nice-image-20193302-153310'
PLAY RECAP **********************************************************************************
a-very-nice-image-20190302-153257279579-cont : ok=3 changed=1 unreachable=0 failed=0
Getting image source signatures
Skipping blob 767f936afb51 (already present): 4.46 MiB / 4.46 MiB [=========] 0s
Skipping blob b211a7fc6e85 (already present): 819.00 KiB / 819.00 KiB [=====] 0s
Skipping blob 8d092d3e44bb (already present): 67.20 MiB / 67.20 MiB [=======] 0s
Skipping blob 767f936afb51 (already present): 4.46 MiB / 4.46 MiB [=========] 0s
Skipping blob b211a7fc6e85 (already present): 819.00 KiB / 819.00 KiB [=====] 0s
Skipping blob 8d092d3e44bb (already present): 67.20 MiB / 67.20 MiB [=======] 0s
Skipping blob 492c5c55da84 (already present): 4.50 KiB / 4.50 KiB [=========] 0s
Skipping blob 6f55b6e55d8a (already present): 6.15 MiB / 6.15 MiB [=========] 0s
Skipping blob 80ea48511c5d (already present): 1021.00 KiB / 1021.00 KiB [===] 0s
Copying config 6b6dc5878fb2: 0 B / 5.15 KiB [----------------------------------]
Copying config 6b6dc5878fb2: 5.15 KiB / 5.15 KiB [==========================] 0s
Writing manifest to image destination
Storing signatures
6b6dc5878fb2c2c10099adbb4458c2fc78cd894134df6e4dee0bf8656e93825a
Image 'a-very-nice-image' was built successfully \o/
This is how the playbook looks:
---
- name: Demonstration of ansible-bender functionality
hosts: all
vars:
ansible_bender:
base_image: python:3-alpine
working_container:
volumes:
- '{{ playbook_dir }}:/src'
target_image:
name: a-very-nice-image
working_dir: /src
labels:
built-by: '{{ ansible_user }}'
environment:
FILE_TO_PROCESS: README.md
tasks:
- name: Run a sample command
command: 'ls -lha /src'
- name: Stat a file
stat:
path: "{{ lookup('env','FILE_TO_PROCESS') }}"
As you can see, the whole build processed is configured by the variable
ansible_bender
.
If we rerun the build again, we can see that ab loads every task from cache:
$ ansible-bender build ./simple-playbook.yaml
PLAY [Demonstration of ansible-bender functionality] ****************************************
TASK [Gathering Facts] **********************************************************************
ok: [a-very-nice-image-20190302-153526013757-cont]
TASK [Run a sample command] *****************************************************************
loaded from cache: '7c69668c42987446cc78adbf6620fc2faf90ad10c3497662fe38940dd6de998f'
skipping: [a-very-nice-image-20190302-153526013757-cont]
TASK [Stat a file] **************************************************************************
loaded from cache: '4a4f54285928c03eea65745ee9feead88026c780a40126d94e79d5842bcdbe62'
skipping: [a-very-nice-image-20190302-153526013757-cont]
PLAY RECAP **********************************************************************************
a-very-nice-image-20190302-153526013757-cont : ok=1 changed=0 unreachable=0 failed=0
Getting image source signatures
Skipping blob 767f936afb51 (already present): 4.46 MiB / 4.46 MiB [=========] 0s
Skipping blob b211a7fc6e85 (already present): 819.00 KiB / 819.00 KiB [=====] 0s
Skipping blob 8d092d3e44bb (already present): 67.20 MiB / 67.20 MiB [=======] 0s
Skipping blob 492c5c55da84 (already present): 4.50 KiB / 4.50 KiB [=========] 0s
Skipping blob 767f936afb51 (already present): 4.46 MiB / 4.46 MiB [=========] 0s
Skipping blob 6f55b6e55d8a (already present): 6.15 MiB / 6.15 MiB [=========] 0s
Skipping blob b211a7fc6e85 (already present): 819.00 KiB / 819.00 KiB [=====] 0s
Skipping blob 80ea48511c5d (already present): 1021.00 KiB / 1021.00 KiB [===] 0s
Skipping blob 8d092d3e44bb (already present): 67.20 MiB / 67.20 MiB [=======] 0s
Skipping blob 5f70bf18a086 (already present): 1.00 KiB / 1.00 KiB [=========] 0s
Skipping blob 492c5c55da84 (already present): 4.50 KiB / 4.50 KiB [=========] 0s
Skipping blob 6f55b6e55d8a (already present): 6.15 MiB / 6.15 MiB [=========] 0s
Skipping blob 80ea48511c5d (already present): 1021.00 KiB / 1021.00 KiB [===] 0s
Skipping blob 5f70bf18a086 (already present): 1.00 KiB / 1.00 KiB [=========] 0s
Copying config 354752b97084: 0 B / 5.26 KiB [----------------------------------]
Copying config 354752b97084: 5.26 KiB / 5.26 KiB [==========================] 0s
Writing manifest to image destination
Storing signatures
354752b97084fcf349a28a2f66839d270e728559883dd1edb5ec22e8c9c6adb9
Image 'a-very-nice-image' was built successfully \o/
Listing builds
We can list builds we have done:
$ ansible-bender list-builds
BUILD ID IMAGE NAME STATUS DATE BUILD TIME
---------- ----------------- -------- -------------------------- --------------
1 a-very-nice-image done 2019-03-02 16:07:47.471912 0:00:12.347721
2 a-very-nice-image done 2019-03-02 16:07:58.858699 0:00:06.242378
Getting logs of a build
Wanna check build logs sometime later? No problem!
$ ansible-bender get-logs 2
PLAY [Demonstration of ansible-bender functionality] *********************************
TASK [Gathering Facts] ***************************************************************
ok: [a-very-nice-image-20190302-160751828671-cont]
TASK [Run a sample command] **********************************************************
loaded from cache: 'cd27cfb71a161f3333232b97cc6b2a89354ff52de71bce9058c52cdf536735f9'
skipping: [a-very-nice-image-20190302-160751828671-cont]
TASK [Stat a file] *******************************************************************
loaded from cache: '89ba4efc31358d688f035bf8159d900f1552314f0af6bf6c338b4897da593ccf'
skipping: [a-very-nice-image-20190302-160751828671-cont]
PLAY RECAP ***************************************************************************
a-very-nice-image-20190302-160751828671-cont : ok=1 changed=0 unreachable=0 failed=0
Locating built images with podman
Once they are built, you can use them with podman right away:
$ podman images a-very-nice-image
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/a-very-nice-image latest 5202048d9a0e 2 minutes ago 83.5 MB
Buildah configuration
If you are familiar with podman and buildah, you know that you can configure these tools. Ansible-bender doesn't change this configuration in any way so it's up to you how you set up buildah and podman. The same applies for running ansible-bender as root or not: buildah allows you to utilize rootless containers.
My suggestion is to use the overlay storage backend. Vfs backend is slow and inefficient.
Caching mechanism
Ansible bender has a caching mechanism. It is enabled by default. ab caches task results (=images). If a task content did not change and the base image is the same, the layer is loaded from cache instead of being processed again. This doesn't work correctly with tasks which process file: ab doesn't handle files yet.
You are able to control caching in two ways:
- disable it completely by running
ab build --no-cache
- or adding a tag to your task named
no-cache
— ab detects such tag and will not try to load from cache
Layering mechanism
When building your image by default, every task (except for setup) is being cached as an image layer. This may have bad consequences on storage and security: there may be things which you didn't want to have cached nor stored in a layer (certificates, package manager metadata, build artifacts).
ab allows you to easily disable layering mechanism. All you need to do is to
add a tag stop-layering
to a task which will disable layering (and caching)
for that task and all the following ones.
Ansible-bender in OKD
Recently I started experimenting with running ab inside OpenShift origin — imagine that you'd be able to build images in your cluster, using Ansible playbooks as definitions.
Openshift by default runs its pods in a restrictive environment. In the proof of concept I was forced to run ab in a privileged pod. In the end, the whole test suite is passing in that privileged pod.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file ansible-bender-0.5.0.tar.gz
.
File metadata
- Download URL: ansible-bender-0.5.0.tar.gz
- Upload date:
- Size: 53.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.12.2 pkginfo/1.4.2 requests/2.20.0 setuptools/40.4.3 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.7.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7f3267c5ca5fd18c41306bce40555e369254ad74cfffd09e5746e3a7484b8a13 |
|
MD5 | 21bd70912e5b3807eced78fb02412af8 |
|
BLAKE2b-256 | 7be92ef427eaf7f26fe331e1aa05885cd080756248a02b28f565c1a3255ed1e7 |
File details
Details for the file ansible_bender-0.5.0-py2.py3-none-any.whl
.
File metadata
- Download URL: ansible_bender-0.5.0-py2.py3-none-any.whl
- Upload date:
- Size: 35.7 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.12.2 pkginfo/1.4.2 requests/2.20.0 setuptools/40.4.3 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.7.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f7f499cbeac01a317f87ae611b9d6e5d9464c704fd8fe48e7589d27c37908662 |
|
MD5 | 69cfc1d9eb0790d9a978f73f76e6f689 |
|
BLAKE2b-256 | a84cdc50869f6cb8ebe0d1eea388d496c6c8fda1058820c2552dbe26215b5da7 |