Skip to content

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 acme component, 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.