Tiller v0.3.0 has just been released, which brings a couple of changes. The first is that the ordering of plugins specified in
common.yaml is now significant. Tiller will run these plugins in the order that they are specified; this is important as before the order was effectively random, so your templates may change with this release if you rely on merging values from different sources (hence the major version bump indicating a breaking change).
The reason for this (apart from making Tiller’s behaviour more deterministic) is that there is now a
DefaultsDataSource, which allows you to specify global and per-template values in a
defaults.yaml (or in separate YAML files under
/etc/tiller/defaults.d/) and then over-ride these with other data sources later.
You’ll hopefully find this useful if you have a lot of environments you want to deploy your Docker containers into (Development, Integration, Staging, NFT, Production, etc.) but only a few values change between each one.
Note 2 : Tiller v0.7.0 and later support a new configuration system, where you can place most configuration blocks in one file, instead of splitting it out over different environment files. However, this article still refers to the old “one file per environment” approach as it’s still supported and won’t be removed.
The following is a simple example of how you might use the new
DefaultsDataSource to generate a fictional application configuration file. Here’s what your common.yaml might look like :
1 2 3 4 5 6 7 8 9 exec: /usr/local/bin/myapp data_sources: - defaults - file - environment_json template_sources: - file
As mentioned above, the order you load data and template sources is significant. Tiller will use each one in the order it is listed, from top to bottom so you now have control over which module has priority. If you wanted to change it so the
file module over-rides values from the
environment_json module (see see http://www.markround.com/blog/2014/10/17/building-dynamic-docker-images-with-json-and-tiller-0-dot-1-4/), you’d swap the order above :
data_sources: - defaults - environment_json - file
Now, here’s our example template configuration file (
/etc/tiller/templates/app.conf.erb) that we want to ship with our Docker container :
1 2 3 4 5 6 7 8 9 [http] http.port=<%= port %> http.hostname=<%= environment %>.<%= domain_name %> [smtp] mail.domain_name=<%= domain_name %> [db] db.host=<%= database %>
In this, you can see that there’s a few dynamic values defined, but we probably don’t want to have to specify them in all our environment files if they’re the same for most of our environments. For example, the domain_name is used in a couple of places, and we’ll also assume that for all our environments the HTTP port will remain the same apart from the staging environment. You can see that if we had a lot of templates to generate, being able to specify the
domain_name and other shared variables in a single place will now be much neater.
Let’s now fill in the defaults for our templates. This is done by creating the new
defaults.yaml file in your Tiller configuration directory, which is usually
1 2 3 4 5 6 # /etc/tiller/defaults.yaml global: domain_name: 'example.com' app.conf.erb: port: '8080'
Now, for all our environments, we only need to provide the values that will change, or that we want to over-ride. Let’s take our “production” environment first - the only thing we want to specify in this example is the database name:
1 2 3 4 5 # /etc/tiller/environments/production.yaml app.conf.erb: target: /tmp/app.conf config: database: 'prd-db-1.example.com'
Now run Tiller to generate the file :
$ tiller -n tiller v0.3.0 (https://github.com/markround/tiller) <[email protected]> Template generation completed $ cat /tmp/app.conf [http] http.port=8080 http.hostname=production.example.com [smtp] mail.domain_name=example.com [db] db.host=prd-db-1.example.com
Let’s now create a new “staging” environment, and demonstrate over-riding the port as well as setting the database; notice how we’re only setting the values that have changed for this environment :
1 2 3 4 5 6 # /etc/tiller/environments/staging.yaml app.conf.erb: target: /tmp/app.conf config: port: '8081' database: 'stg-db-1.dev.example.com'
And now run Tiller to create our config file for this environment:
$ tiller -e staging -n tiller v0.3.0 (https://github.com/markround/tiller) <[email protected]> Warning, merging duplicate data values. port => '8080' being replaced by : '8081' from FileDataSource Template generation completed $ cat /tmp/app.conf [http] http.port=8081 http.hostname=staging.example.com [smtp] mail.domain_name=example.com [db] db.host=stg-db-1.dev.example.com
You’ll notice that Tiller warned you about the value from the
DefaultsDataSource being replaced with one from the
FileDataSource; you can see here how the ordering of plugins loaded in
common.yaml is important.
And there you have it. A short example (and I’ve omitted the creation of the other example environments and templates), but you can see how this new behaviour will make life much easier when you use Tiller as the
ENTRYPOINT in your container. Hopefully this will mean more efficient Tiller configs and will help you create more flexible Docker images. Any feedback or queries, just leave them in the comments section below, or report a bug/request a new feature on the Github issue tracker.