About constraints

See also:



A constraint is a user-defined minimum hardware specification for a machine that is spawned by Juju. There are in all ten types of constraints, with the most common ones being mem, cores, root-disk, and arch. The definitive constraint resource is found on the Juju | Constraints reference page.

Several noteworthy constraint characteristics:

  • A constraint can be specified whenever a new machine is spawned with the command bootstrap, deploy, or add-machine.
  • Some constraints are only supported by certain clouds.
  • When used with deploy, the constraint becomes the application’s default constraint.
  • Multiple constraints are logically ANDs (i.e., the machine must satisfy all constraints).
  • When used in conjunction with a placement directive (the --to option), the placement directive takes precedence.

Clouds and constraints

In the ideal case, you stipulate a constraint when deploying an application and the backing cloud provides a machine with those exact resources. In the majority of cases, however, default constraints may have already been set (at various levels) and the cloud may be unable to supply those exact resources.

When the backing cloud is unable to precisely satisfy a constraint, the resulting system’s resources will exceed the constraint-defined minimum. However, if the cloud cannot satisfy a constraint at all, then an error will be emitted and a machine will not be provisioned.

Constraints and LXD containers

Constraints can be applied to LXD containers either when they’re running directly upon a LXD cloud type or when hosted on a Juju machine (residing on any cloud type). However, with containers, constraints are interpreted as resource maximums as opposed to minimums.

In the absence of constraints, a container will, by default, have access to all of the underlying system’s resources.

LXD constraints also honour instance type names from either AWS, Azure, or GCE (e.g., AWS type t2.micro maps to 1 CPU and 1 GiB of memory). When used in combination with specific CPU/MEM constraints, the latter values will override the corresponding instance type values.

Constraints and Kubernetes

Constraints in Kubernetes models control the resource requests and limits on the pods spawned as a result of deploying an application.

Memory and CPU constraints on sidecar charms currently only represent requests used by Kubernetes for scheduling, and don’t set limits and requests separately on each container. This deficiency is tracked under bug LP1919976.

Constraint scopes, defaults, and precedence

Constraints can be applied to various levels or scopes. Defaults can be set on some of them, and in the case of overlapping configurations a precedence is adhered to. Changing a default does not affect the existing machines.

On a per-controller basis, the following constraint scopes exist:

Among the scopes, default constraints can be set for each with the exception of the controller and single machines.

The all-units scope has its default set dynamically. It is the possible constraint used in the initial deployment of an application.

The following precedence is observed (in order of priority):

  1. Machine
  2. Application (and its units)
  3. Model
  4. All models

For instance, if a default constraint (mem) applies to a single model and the same constraint has been stipulated when adding a machine (add-machine) within that model, then the machine’s constraint value will be applied.

The dynamic default for units can be overridden by either setting the application’s default or by adding a machine with a constraint and then applying the new unit to that machine.