We build an universal deployment tool for Kubernetes that supports rendering and deployment of lightweight Jinja templated k8s manifests as well as complex Helm charts. We’ve added support for easy secret management based on Gopass, running tests in CI/CD pipelines, extending upstream Helm Charts with custom Jinja-templates manifests as well as patching upstream Helm Charts before deploying.
¶ Installation
You can use pip
to install adeploy
from the Github mirror:
pip install git+https://github.com/awesome-it/adeploy.git
adeploy --version
Please check the help section of adeploy
if you need more information:
adeploy --help
adeploy -p <provider> (render|test|deploy) --help
To use adeploy
for your deployments, you need to keep the following directory structure in your deployment repository:
├── README.md
├── build/
├── chart/
├── defaults.yml
├── namespaces/<namespace>/<release>.yml
└── templates/
defaults.yml
defines global variables and versions for all releases of your dpeloyment.namespaces
contains a subdirectory for each namespaces and a<release>.yml
configuration for each release or instance.templates
orchart
contains your Jinja templates k8s manifests or your Helm chart (if you want to use an offline version).
¶ Variables
One of the most important features is the global deployment configuration file (i.e. defaults.yml
) and a per-deployment or per-namespace configuration file in (i.e. namespaces/<namespace>/<release>.yml
) that can be used to set parameters for all deployments and for each deployment release respectively.
One common use-case is the versions
map. Let’s have a look at the following WordPress deployments. Let’s suppose you have a deployment for your live page (i.e. https://awesome-it.de
) and another deployment for your testing page (i.e. https://beta.local.awesome-it.de
). So you have a global configuration file:
defaults.yml
:
versions:
wordpress: 5.5.0-fpm
nginx: 1.16.1
And your have additional configuration files for each deployment release (i.e. prod
and test
):
namespaces/wp-awe/prod.yml
:
versions: {}
database:
host: mariadb-galera.db-mariadb.svc
name: wp-ait-prod
namespaces/wp-awe/test.yml
:
versions:
wordpress: 5.5.2-fpm
database:
host: mariadb-galera.db-mariadb.svc
name: wp-ait-test
You can now use these variables in your Jinja templated manifest files or in your Helm values.yml
files as follows:
...
containers:
- name: main
image: wordpress:{{ version('wordpress') }}
env:
- name: DB_HOST
value: {{ deployment.get('database.host') }}
- name: DB_NAME
value: {{ deployment.get('database.name') }}
In doing so, you can configure for example different databases for you instances. This is really useful, if you want to deploy an application severals times i.e. for several customers or use-cases.
Further when doing updates, you can increase versions.wordpress
in test.yml
to update and check the test instance before you update WordPress in the production instance.
Note that configuration files will be merged, so a
versions: {}
inprod.yml
will not overwrite aversions:wordpress
indefaults.yml
.
¶ Jinja Deployments
Jina templates in the templates folder can be compiled for each namespace and deployment-release as follows:
$ adeploy -p jinja render <dir> [<dir> ...]
You can do a server-dry-run and apply the manifests as follows:
$ adeploy -p jinja test <dir> [<dir> ...]
$ adeploy -p jinja deploy <dir> [<dir> ...]
adeploy
is usingkubectl
and the current kubectl context including the destination kubernetes cluster and authentication.
¶ The following variables are available for the Jinja templates:
name
: The deployment name derived from the repo folder name or specified by –namerelease
: Release name derived from filenamespaces/mynamespace/<release>.yml
namespace
: The namespace for the deployment derived from foldernamespaces/<namespace>/...
deployment
: Variables from defaults.yml overwritten by namespaces/mynamespace/prod.yml
¶ Example
¶ Helm Deployments
The Helm chart in the chart
folder (default value of --chart-dir
) can be rendered with variables for each namespace and deployment-release merged with the variables from defaults.yml
as follows:
adeploy -p helm render . [--chart-dir ./chart]
The chart name is given by the containing folder name or you can spsecify a name using the
--name
parameter.
If no chart folder is given, an upstream chart can be automatically downloaded using --repo-url URL
in the render step:
adeploy [--name customer_chart_name] -p helm render . --repo-url https://chart.url
You can now do a server-dry-run and install the Helm chart as follows:
adeploy -p helm test .
adeploy -p helm deploy .
¶ Chart Version
The chart version can be set in the defaults.yml
(or defaults/<release>.yml
) for the appropriate deployments:
_chart:
version: 0.0.0
¶ Hooks
Since adeploy-0.4.X
, the render step executes scripts from the /mydeployment/hooks
folder as:
cd /mydeployment/hooks
./script.sh /mydeployment/build/helm/charts/<chartname>/
You can use this i.e. to patch Helm Charts without touching upstream repos for quick and dirty fixes before you install them.
¶ Example
¶ Conclusion
This tools introduced a simple and easy way to create k8s manifests using Jinja templates. Further it provides an abstraction for other deployment tools like Helm. We plan to support other deployment tools like Kustomize as well. This abstraction allows to implement really useful features that we hardly require in our daily use in all of these deployment tools. Examples are patching upstream Helm charts without touching or forking the upstream. Secret management, especially in CI/CD pipelines without the need to store secrets in a repo or using complicated secret operators in k8s is another example that we could solve using adeploy
. If this also seems useful to you, have a look at https://github.com/awesome-it/adeploy and try it by yourself. We appreciate your feedback and of course we welcome your contributions to this project.