Manage sets of units together
Most operations in ConfigHub act on a set of units rather than on one. This guide is about naming that set well.
Start from the component model
Configuration in ConfigHub is organized as components and their variants. A component is a logical piece of software; each variant is one complete copy of its configuration, adapted to a particular deployment. A variant is a Space, and the units in that Space are the totality of the configuration for it.
That gives every set of units a shape, and there are two useful ones:
- A vertical subset: some or all of the units of one variant. "The frontend, backend, database, and cache in
acme-dev." This is a slice of one Space. - A horizontal subset: the same unit across many variants. "Every deployment of the
acmecomponent, in every region." This cuts across Spaces.
Both are expressed the same way — a where expression — but they select on different things. A vertical set usually selects on Unit fields and Unit labels. A horizontal set selects on the Space's labels, because that is where the component model lives: Component names the component, Variant names the variant within it, and Environment, Region, Layer, and Owner capture the other dimensions.
# Vertical: four units of one variant
cub unit list --space acme-dev --where "Slug IN ('frontend', 'backend', 'database', 'cache')"
# Horizontal: every production deployment of the acme component
cub unit list --space "*" --where "Space.Labels.Component = 'acme' AND Space.Labels.Environment = 'Prod'"
# Horizontal, one unit: the backend, in every variant of the component
cub unit list --space "*" --where "Slug = 'backend' AND Space.Labels.Component = 'acme'"
A single Space can be selected with the --space flag instead of a where clause; --space "*" searches across every Space you can see.
Adding labels to make a set nameable
If the set you want has no natural label yet, give it one. Bulk patch writes a label across a selection in one command:
cub unit update --patch --label Application=acme --space acme-dev --where "Slug IN ('frontend', 'backend', 'database', 'cache')"
That lets later filters be expressed on the label rather than on a list of slugs, which does not go stale as the set grows:
cub unit list --space acme-dev --where "Labels.Application = 'acme'"
For a horizontal set, label the Space. cub variant create sets Variant, Stage, Environment, and Region for you; anything else is a patch:
cub space update --patch --label Layer=platform acme-prod-use1
See managing environments for the label conventions, and organize and focus with filters and views for organizing the filters themselves.
Save the set as a Filter
If this is a set you will frequently operate on, create a saved Filter to represent it. Using a saved Filter reduces the chances of making mistakes, and means the definition lives in one place when it changes.
Choose a Space to put the Filter in. We recommend a "home space" for commonly reused entities such as Filters, Views, and ChangeSets. The CLI can store this space as the default space in the context.
cub space create acme-home
cub filter create --space acme-home acme-app Unit --where-field "Labels.Application = 'acme'"
A Filter over a horizontal set selects on the Space's labels the same way a --where does:
cub filter create --space acme-home acme-prod Unit \
--where-field "Space.Labels.Component = 'acme' AND Space.Labels.Environment = 'Prod'"
Every command that supports --where also supports --filter. Specify the saved Filter, including its space if it is not the default space and not the space specified on the command line.
cub unit approve --space acme-dev --filter acme-home/acme-app
Operating on the set
Bulk operations act on a filtered group of entities of the same type. Bulk patch, delete, and even create are supported for most entity types; bulk patch is also how unit data operations such as restore and upgrade are applied across a set.
Functions are invoked in bulk by default, except when operating on a specific revision of a specific unit.
Unit actions such as Tag and Approve support bulk operations too, and are frequently used as part of a multi-unit change workflow.
When the set is a whole variant
A set that is exactly one variant does not need a filter. The cub variant commands take the Space and work out the units themselves, which is both less to write and less to get wrong:
cub variant promote acme-prod-use1 # upgrade every unit whose upstream has advanced
cub variant approve acme-prod-use1 # approve every releasable unit
cub release publish acme-prod-use1 # publish the whole variant
See creating and managing variants, and tracking and promoting changes for moving one named change across many variants at once.