Juju-deployer is a tool to deploy complex stacks of charms quickly via a yaml or json configuration file.
The deployer configuration file can be in either yaml or json formats. The contents of the top level are a dictionary/hash mapping of stack names to configuration.
The stack can take several options for specifying, series:
wordpress-stage:
series: precise
Snippet:
wordpress-stage:
series: precise
services:
blog:
charm: wordpress
branch: lp:charms/precise/wordpress
constraints: mem=2
options:
tuning: optimized
engine: apache
icon: include-base64://file.ico
The service’s charm name will be infered from the vcs branch name if possible, else it will assume the service name, is the name of the charm, or can be specified manually via the charm key.
The service constraints are specified as a single string value corresponding to what would be specified on the command line. Valid generic constraints for juju-core are mem, cpu-cores, cpu-power.
Service configuration is specified a dictionary of key/value mapping. There is support for including data from external files with either the include-file://path-to-file or include-base64://path-to-file. Relative paths are resolved relative to the config file.
Relations can be specified in a few different formats.
legacy format uses a set of nested dicts with weights specified to specify relation creation ordering, this form is only for compatibility has been deprecated for over two years (2012):
relations:
keystone:
weight: 100,
consumes:
- mysql
In modern syntax, relations is an ordered list of endpoint pairs
endpoint pairs:
relations:
- [blog, db]
- [blog, memcached]
nested endpoint pairs:
relations:
- [blog, [db, memcached]]
The two forms above are equivalent and both will create a relation from blog to db and memcached.
There are a number of reasons why you may wish to have separate configuration files for a given juju environment you’re deploying to. An example is if you have a development, staging and production environment with small differences (hostnames, constraints, tuning options, etc.) but don’t want entirely separate juju deployer config files for each. Another example is if you want to be able to have secrets such as SSL certs in a different config file so you can share the bulk of the config (anything non-secret) with a wider audience without including the secrets.
In this case your options are to separate config files that you pass on the command line to juju-deployer:
juju-deployer -c wordpress.cfg -c wordpress-secrets.cfg -s 90 wordpress
Or config inheritance:
wordpress-stage:
series: precise
services:
blog:
charm: wordpress
branch: lp:charms/precise/wordpress
constraints: mem=2
options:
tuning: optimized
engine: apache
icon: include-base64://file.ico
wordpress-prod:
inherits: [wordpress-stage, monitoring]
services:
blog:
constraints: mem=16
options:
tuning: optimized
Deployer supports flexible per unit placement policies. A unit placement policy allows for specifying which machine a unit is placed on, including allowing multiple units to be deployed to the same machine.
This is expressed in deployer config via the ‘to’ list parameter on a service. Each unit that needs placement must have its placement specified individually else the default behavior is used, per the service’s constraints.
There are two forms of placement values that are supported.
- Specifying another service, in which case the unit will be placed alongside the matching unit of that service with matching done by unit count. ie the first unit of x will be placed with the first unit of y. The second unit of x with the second unit of y.
- Machine placement to machine ‘0’. This is the only machine placement supported as its ambigious for most usage scenarios.
Additionally, containerization of the service unit is supported for all of these values with the prefix ‘container_type:’, ie. lxc:mysql. Not specifying a containerization type results in both service units together in the same root fs (aka hulk-smash). Containerization can specified on a unit by unit basis.
The deployed-with service must have enough units to hold # # Nested to: specifications are not supported (ie in the below wordpress can’t # be deployed to mysql because mysql already specifies a ‘to’ placement)
Example:
envExport:
services:
mysql:
# The only machine id supported is machine 0
to: 0
wordpress:
units: 3
redis-server:
units: 3
to: [lxc:wordpress, wordpress]
ceph:
units: 4
to: [wordpress, wordpress, wordpress, wordpress]
serenade:
to: lxc:wordpress=2
In this case the first unit of redis-server is deployed in a container on wordpress/0 The second unit of redis-server is deployed hulk smash onto wordpress/1 The third unit of redis-server gets a full machine allocated to itself.
For ceph, we deploy hulk smash of the first 3 units, the final unit doesn’t have a corresponding unit of wordpress and is deployed (along with a console warning) to a separate machine per its default constraints.
The serenade service is overriding the default deploy-with unit by explicitly specifying a unit index for the deployment. These are not unit id based but rather based on extant unit count of the remote service starting with 0.