Skip to navigation

Releases and environments

A source release is an immutable snapshot of your configuration directory in object storage. An environment is a named pointer, such as staging or production, to one release. Hosts running rivet run follow an environment. Promoting a release changes what they apply on their next run.

Hosts get a catalog from a release in one of two ways:

ModeHow it worksHost credentials
SourceThe host reads the release and compiles it locally.Read access to the release storage and any cloud assets.
Compile serviceThe host sends its facts over HTTPS; the service compiles and returns the catalog.An identity the service accepts, plus storage read access unless the service uses signed asset delivery.

If acquisition fails, the run stops. Rivet never switches modes or silently uses an older catalog.

Publish and promote

# Upload a snapshot. This prints the release digest and changes no environment.
rivet release publish ./site --store gs://example-rivet-config/site
RELEASE='sha256:<64 lowercase hex characters>' # the digest printed above
# Create the staging environment (generation 0 means it must not exist yet).
rivet environment promote staging --release "$RELEASE" \
--store gs://example-rivet-config/site --expected-generation 0
# After checking staging, promote the same release to production.
rivet environment promote production --release "$RELEASE" \
--store gs://example-rivet-config/site
rivet environment show production --store gs://example-rivet-config/site \
--cache-dir /tmp/rivet-publisher-cache

Stores are gs://bucket/prefix, s3://bucket/prefix, or file:///absolute/directory for local testing. Cloud stores use the standard credential chains. Give publishers write access and give hosts and the compile service separate read-only identities.

Keep agent and server configuration files out of the published directory: every top-level *.hcl file there is compiled as configuration.

Publishing copies regular files, skips .git, and refuses symlinks and special files. Objects are written only if absent, and the release index goes last, so a half-finished upload never looks like a release. Publishing identical content again gives the same digest.

Promoting first checks that every file in the release is present with the right size and SHA-256, then updates the environment pointer conditionally. If another promotion happened since you read the pointer, yours fails rather than overwriting it. --expected-generation N adds an explicit check: 0 requires a new environment, and a positive value requires that exact current generation. Each run reads the pointer once, so a promotion during a run doesn’t affect it.

Rolling back is promoting an older release. That changes what future runs apply; it doesn’t undo changes already made to hosts.

Environment names are 1 to 128 ASCII letters, digits, underscores, or hyphens.

Check a release before promoting

# Compile against representative facts without downloading asset contents.
rivet release validate --store gs://example-rivet-config/site \
--environment staging --cache-dir /tmp/rivet-publisher-cache --facts facts.json
# Fetch and verify every asset, and write a standalone bundle.
rivet release compile --store gs://example-rivet-config/site \
--environment staging --cache-dir /tmp/rivet-publisher-cache \
--facts facts.json --out staging.bundle

Without --facts, release validate uses the built-in Ubuntu baseline. Neither command touches a managed host.

What a release can contain

Releases include the top-level *.hcl files and the resource assets they reference. They don’t support:

  • Modules, local or remote.
  • Other files read by file() or templatefile().
  • --vars-file or data hierarchies, so every variable needs a default.

Inline templates and functions that don’t read other files work as usual. Use direct compilation when you need the unsupported features.

LimitValue
Files per release10,000
Total release size256 MiB
Combined top-level HCL16 MiB
Facts snapshot1 MiB

Storage layout

For a store ending in /site:

environments/production.json
environments/staging.json
releases/<index-sha256>/release.json
releases/<index-sha256>/main.hcl
releases/<index-sha256>/files/demo.conf

release.json lists every file with its SHA-256 and size, and its own digest identifies the release. An environment file holds a release digest and a promotion generation. Hosts read files through the index rather than listing the bucket.

Digests prove the files match the index, but not who wrote the index. Anyone who can write to the store can publish and promote. Releases aren’t signed, so treat storage write access as the trust boundary.

How hosts prepare a catalog

Before the runner starts, the host fetches every asset the catalog needs, verifies each size and SHA-256, and caches them under its private cache directory. A missing or mismatched asset stops the run before any change. The runner itself never downloads anything; apt repositories are the only network dependency during apply.

AssetWhere the host gets it
A file from the configuration directory, including .deb archivesThe release object
An S3 or GCS file source with a checksumThat object, at the version recorded during compilation
Inline or template-rendered contentIncluded in the catalog

The cache reuses unchanged files across releases. Releases and cached files are kept forever; there’s no garbage collection yet.

See agent runs to set up hosts, and testing for how releases are tested.