Here we’re going to explore repetitive project content and one method you can employ to automate its generation.
After creating a few Ansible-based Kubernetes projects the boilerplate begins to emerge on two fronts - a number of mandatory Ansible files and the Kubernetes object definitions. What’s most frustrating is that, for the most part, Kubernetes objects are often detailed (verbose) yet irritatingly repetitive and predictable.
To do Ansible well you start with a playbook (maybe a simple
site.yaml) before placing your execution logic in a
role where you normally author a number of
main.yaml files distributed over a selection of directories (
templates). Then there’s an
ansible.cfg and an
With the playbook framework laid out you turn your attention to the Kubernetes objects that will be responsible for managing your application. To run an application (a container image) using Kubernetes requires more than just the definition of a
Deployment (The container details, replicas, etc.). You’ll usually need a
Namespace and then, probably, a
RoleBinding and a
Service (if the application offers a service to others). You might round things off with a
Secret or two, some files in the form of a
ConfigMap and maybe some container persistence with a
Beyond that you realise you also need to create a
requirements.txt and, if you’re diligent, a
.travis.yml, and a
As the projects come and go the work becomes eerily familiar - a repetitive “pattern” of files and content.
In your next project you decide that it might be easier to start by copying almost all of the files from the last project before editing their content for the new one. But this is tedious and error-prone.
Is there better way?
There is. It’s a cookiecutter.
In baking it’s a tool to cut cookie dough into a particular shape. In software it’s a tool to pre-format a series of project files to comply with development structure and content - i.e. a “form”. An ideal tool if you’re going to create a number of similar projects (cookies).
The cookiecutter I’m referring to is the rather beautiful solution published on GitHub. Despite its origins as tool to create a Python package project from a Python package project template it is valuable to anyone because: -
How do you use it?
You create a project - just like the one’s you’re repeatedly creating - in template form. Just template your entire project - setting out structure, names and content and then provide a
cookiecutter.json parameter file that the cutter uses to prompt your user for their choice of values in order to create a project rendered using a “flavour” of their choosing.
The rendering is based on Jinja.
The wonderful thing is that it’s not just file content you’re rendering, the cookiecutter can also render file and directory names as well.
The cookiecutter exposes a “hooks” mechanism so that you can run additional code before or after the rendering process. I use a “post-rendering” hook to remove files the user doesn’t want (based on the user’s response to the cookiecutter prompts). So, if the user says “no” to wanting a “ConfigMap” then the post-hook (which has access to the users’s parameter values and the rendered project directory) removes the ConfigMap file from the user’s project. In summary, hooks are great for “taking things away”.
Once you have a project template that’s sufficiently rich to provide enough formatting for you, commit it to revision control and then point your next “cookiecutter” execution to the repository URL so that it can render projects directly from a GitHub (or Mercurial repos on Bitbucket).
Here’s our cookiecutter project layout, with hooks, the template and the cookiecutter.json: -
Now we can rapidly template a new Ansible Kubernetes project, populating it with a full set of functional files by running: -
If you’re crafting Kubernetes applications with Ansible then feel free to browse our cookiecutter. If anything it will hopefully inspire you to create and publish your own for your next project.
After all, if you’re like me then…
Surely you’d rather be writing code that writes code than write code?