Skip to content

Managing Drift

One of the big challenges with having a separate storage for configuration outside of your live resources is keeping things in sync. It is common, for a variety of reasons, for changes to be made directly in the live resources without going through your configuration management system. Now the two systems have drifted apart.

If you may are familiar with GitOps, then you may expect the drift detection and reconciliation to be unidirectional, overwriting the live resources with the desired state in storage (git, OCI, ConfigHub, ...).

ConfigHub provides another alternative. ConfigHub enables you to pull changes to the live resources into ConfigHub and create a new revision. This is done with the refresh command:

cub unit refresh --space prod backend

Now you have both your original configuration (in the previous revision) and a new revision matching what is live now.

From here you can decide to simply do nothing, or you can restore the previous revision and apply it to bring the live resources back to the previous state.

One strategy you could use to maximize transparency and minimize surprises is to refresh after your initial apply and subsequently before making additional changes to apply. That way you always have a current reflection of the live state when making changes. If you want to be able to revert to the prior state, you can set a tag first, such as:

cub tag create --space home pre-refresh-20251022
cub unit tag --space "*" --revision HeadRevisionNum home/pre-refresh-20251022 # tags all units
cub unit refresh --space "*" # refreshes all units

You can also execute refresh in "dry run" mode, similar to unit updates and function invocations. In this case, the unit's configuration data is not updated, but the operation will report whether it detected drift and the LiveData and LiveState of the unit will be updated. The refreshed configuration data that would have been stored in the unit is stored in the UnitAction corresponding to the operation instead. You can get the data from the refresh operation as follows.

opID=$(cub unit refresh --wait --space prod backend --dry-run --jq ".QueuedOperationID")
cub unit-action get --space prod backend $opID
cub unit livedata --space prod backend
cub unit livestate --space prod backend

Units must first be applied at least once before they can be refreshed. To create units from the live state initially use import.