Consistency
Pins exact package versions so every environment gets the same stack.
A UDS Bundle combines Zarf packages with environment-specific configuration into a single declarative artifact, defined in a uds-bundle.yaml manifest and managed through the UDS CLI. It is the deployable unit — a versioned artifact that pairs what to deploy with how to configure it for a given environment.
Without bundles, teams would need to deploy Zarf packages individually, track compatible versions manually, and repeat environment-specific configuration for each cluster. Bundles solve this by treating the entire stack — platform and applications — as a single versioned artifact.
Consistency
Pins exact package versions so every environment gets the same stack.
Composability
Add or remove packages without forking the platform.
Air-gap readiness
Inherits Zarf’s ability to package everything for disconnected environments.
Environment tailoring
Overrides and variables adapt a single bundle to dev, staging, and production.
A bundle manifest lists Zarf packages to deploy, in order. A bundle for the core platform layers might look like this:
kind: UDSBundlemetadata: name: core-platform description: Cluster init and UDS Core platform version: "x.x.x"
packages: - name: init repository: ghcr.io/zarf-dev/packages/init ref: x.x.x
- name: core repository: ghcr.io/defenseunicorns/packages/uds/core ref: x.x.xEach entry references a Zarf package by OCI repository and version tag. Deploy order matters — packages are deployed top to bottom, so the platform is ready before applications land.
Bundles support two layers of configuration so that a single artifact can adapt to different environments:
| Mechanism | Defined in | Set by | Purpose |
|---|---|---|---|
| Overrides | uds-bundle.yaml | Bundle author | Defaults and Helm value mappings the author pre-configures |
| Variables | uds-config.yaml | Deployer | Secrets, endpoints, and values that differ per cluster |
The bundle author defines which Helm values and Zarf variables are configurable and where they map. The deployer provides the values via uds-config.yaml at deploy time. This separation means you build once and configure per cluster — the bundle defines the knobs, uds-config.yaml turns them.