cub variant create
cub variant create
Create a variant by cloning a space and its units
Synopsis
Create a variant of an upstream space by cloning the space and all of its units into a new downstream space.
This is a convenience command that combines two bulk operations:
1. Clone the upstream space (like "cub space create" in bulk mode), setting the new space's
"Variant" label to
The first argument is the variant name, which becomes the value of the "Variant" label on the new space. The second argument is the slug (or UUID) of the upstream space to clone from. The upstream space is expected to have labels such as Layer, Owner, Stage, Environment, Region, and Variant, and may have a "TargetID" annotation referencing the default target for the space, but none of these are required.
The new space's labels are inherited from the upstream space, with "Variant" overridden to
--owner sets the Owner label of that Component, not of the new space; an Owner label the upstream
space has is still inherited like its other labels. A Component's owner is its own Owner label, or
else the Owner label all of its spaces share. When the Component already has a different owner,
--owner is refused before anything is created, and the error gives the
"cub component update --patch
The new space's slug defaults to
The new space selects the Triggers the upstream space selects: its WhereTrigger and TriggerFilterID are copied, and when it has neither, which means its own Triggers, the new space's WhereTrigger selects the Triggers in the upstream space. Permissions are copied too. Triggers are not copied: they run where they are, so every variant runs the same ones.
Metadata flags are split by what they target, space vs. unit, as on "cub variant upload":
--space-label / --space-annotation / set on the new space, merged onto the values copied
--space-delete-gate from the upstream space.
--unit-label / --unit-annotation / set on every cloned unit, merged onto each clone's
--unit-delete-gate / --unit-destroy-gate copied values. Destroy gates are unit-only (spaces have
no destroy gates). Use --unit-delete-gate critical to
protect a prod variant's units.
--permission add to, or with a leading "-" remove from, the
permissions copied from the upstream space.
--release-target the new space's release Target, which its units take;
--target sets it too, so use one or the other.
--change-desc / --changeset describe the clones' first revision and put the clones
in a changeset (
To automatically customize the cloned units, create PostClone triggers in the upstream space, or select them with its WhereTrigger or TriggerFilterID. The downstream space gets the same selection, so they run during the clone. Trigger arguments can reference space metadata in Go templates, such as "template:{{.SpaceLabels.Region}}" or "template:{{.SpaceAnnotations.host}}" — set the latter with --space-annotation. Any other changes can be made after the clone completes.
Links between units of the cloned space are copied into the new space and retargeted at the clones. Links pointing out of it are not, unless --include-outgoing-links-where selects them: a copied outgoing link keeps the original unit as its to-unit, so the variant reads from the same producer the upstream reads from.
A variant is normally downstream of its upstream space: changes flow from the upstream units into the clones, through the UpgradeUnit links this command creates ("cub variant promote"). --syncback additionally creates a MergeUnits link the other way, from each upstream unit back to its clone, which makes the variant usable as a draft: clone the space, change the clones, review them, then merge the changes back into the upstream units with
cub unit update --patch --space
The syncback links live in the upstream space and are named for the clone they take changes from
("syncback-
cub space delete --recursive --detach
When --target points at a cub-cluster Argo target (an OCI target carrying the
confighub.com/argo-apps-space annotation that "cub cluster up" stamps), this command also creates the
Argo CD Application that makes the new deployment live: a Kubernetes/YAML unit named after the new
space, added to the cluster's apps space and pulling the new space's OCI Release. The apps space's
Release is republished so the cluster's root app-of-apps picks it up on its next sync. This is a
no-op for ordinary targets; use --no-argo-app to skip it. Publish the deployment's own release
("cub release publish
Examples:
# Clone a space into a "test" variant. With Component=website inherited and Variant overridden to
# "test", the default slug is "website-test".
cub variant create test website-prod
# Clone into a regional staging variant, overriding the Environment and Region labels.
cub variant create staging website-prod --environment Staging --region us-east2
# Clone into a canary variant of production, overriding the Stage label.
cub variant create canary website-prod --stage Canary --environment Prod
# Point the cloned units at a target and stamp the new space's TargetID annotation.
# For an OCI target, this also sets the new space's release target, so the variant
# can be published with "cub release publish" without further setup.
cub variant create test website-prod --target website-test/cluster
# Deploy to a "cub cluster up" cluster: clones the base, retargets it, and creates
# the Argo CD Application so the cluster picks up the deployment (skip with --no-argo-app).
cub variant create dev cubbychat-base --target dev/target --namespace cubbychat
# Clone a space as a draft to change and review, with links to merge the changes back.
cub variant create draft website-prod --syncback
# Carry the units' links to producers in other spaces into the variant, so its units read
# from the same ones.
cub variant create prod website-base --include-outgoing-links-where "UpdateType = 'TransformPaths'"
# Set a space annotation a PostClone trigger reads, and protect the prod clones with a delete gate.
cub variant create prod website-base \
--space-annotation host=website.prod.example.com \
--unit-delete-gate critical --unit-destroy-gate critical
cub variant create <variant-name> <upstream-variant> [flags]
Options
--allow-exists Allow creation of resources that already exist
--change-desc string change description recorded on each cloned unit
--changeset string changeset to put the cloned units in, as <slug> or <space>/<slug>
--environment string set the "Environment" label on the new space (example: "Prod")
-h, --help help for create
--include-outgoing-links-where string where expression selecting which of the upstream units' links to units in other spaces to copy onto the clones; each copy keeps the original unit as its to-unit, so the variant reads from the same producers. Links within the cloned space are always copied and retargeted at the clones
--layer string set the "Layer" label on the new space (example: "App")
--namespace string run set-namespace with this value on the cloned Kubernetes/YAML units, replacing the placeholder namespace from the upstream (e.g. a base uploaded with --namespace confighubplaceholder), and record it as the new space's Namespace label, which cub variant promote applies to units it adds later
--no-argo-app skip auto-creating the Argo CD Application when --target is a cub-cluster Argo target
-o, --output string Output format. One of: json, yaml, name, wide, mutations, jq=<expr>, yq=<expr>, custom-columns=<spec>
--owner string set the "Owner" label on the Component the new space is in, not on the space; refused when the Component already has a different owner (example: "Engineering")
--permission strings permission on the new space in format Action:UserIDOrUsername, Action:group:GroupSlugOrID or Action:serviceaccount:ServiceAccountSlugOrID to add to those copied from the upstream space, or the same prefixed with - to remove one of them (e.g., Manage:user@example.com, View:group:platform, View:serviceaccount:deploy-bot, -View:user@example.com, can be repeated)
--quiet No default output.
--region string set the "Region" label on the new space (example: "us-east2")
--release-target string Target to use as the new space's release Target, addressed as <target-space>/<target-slug> (a bare <target-slug> resolves in --space; a Target ID is also accepted). The cloned units that are released through a Target take it as theirs. --target sets the same Target on the space and the units and also records it in the space's TargetID annotation, so the two flags cannot be combined
--space-annotation strings annotation key=value to set on the new space (repeatable); merged onto the annotations copied from the upstream space. PostClone trigger args can read these via {{.SpaceAnnotations.<key>}}. "TargetID" is reserved (use --target)
--space-delete-gate strings delete gate key[=true] to set on the new space (repeatable); merged onto the delete gates copied from the upstream space
--space-label strings label key=value to set on the new space (repeatable); merged onto the labels copied from the upstream space. It may not name a label another flag sets, such as Region
--space-pattern string a pattern string for the new space's slug, prefix 'template:' to use a Go template with .SourceEntitySlug for the upstream slug, .Component for the cloned space's Component, and .Labels for the cloned space's labels; defaults to 'template:{{.Component.Slug}}-{{.Labels.Variant}}' when the cloned space has a Component
--stage string set the "Stage" label on the new space (example: "Canary")
--syncback also link each cloned unit back to its upstream unit, with a MergeUnits link in the upstream space, so changes made in the variant can be merged back into the upstream units (see the draft workflow in the long help)
--target string target for the cloned units, in <target-slug> or <space-slug>/<target-slug> form; also sets the TargetID annotation on the new space, and for an OCI target the new space's ReleaseTargetID (required by 'cub release publish')
--timeout string completion timeout as a duration with units, such as 10s or 2m (default "10m0s")
--unit-annotation strings annotation key=value to set on every cloned unit (repeatable); merged onto each unit's copied annotations
--unit-delete-gate strings delete gate key[=true] to set on every cloned unit (repeatable); e.g. --unit-delete-gate critical to protect a prod variant
--unit-destroy-gate strings destroy gate key[=true] to set on every cloned unit (repeatable); destroy gates are unit-only (spaces have no destroy gates)
--unit-label strings label key=value to set on every cloned unit (repeatable); merged onto each unit's copied labels
--variant-labels strings additional variant labels for the new space in the format key1=value1,key2=value2 (the Variant label is always set from <variant-name>)
--verbose Detailed output, additive with default output
--wait wait for completion (default true)
Options inherited from parent commands
--context string The context to use for this command
--debug Debug output
SEE ALSO
- cub variant - Variant commands