The actual capabilities that Zarf Packages provide are defined within named components.
These components define what dependencies they have along with a declarative definition of how they should be deployed.
Each package can have as many components as the package creator wants but a package isn’t anything without at least one component.
There are certain fields that will be common across all component definitions. These fields are:
Field Type Description name
* string The name of the component cosignKeyPath
string [Deprecated] Specify a path to a public key to validate signed online resources. This will be removed in Zarf v1.0.0. default
boolean Determines the default Y/N state for installing this component on package deploy description
string Message to include during package deploy describing the purpose of this component group
string [Deprecated] Create a user selector field based on all components in the same group. This will be removed in Zarf v1.0.0. Consider using 'only.flavor' instead. import
object Import a component from another Zarf package only
object Filter when this component is included in package creation or deployment required
boolean Do not prompt user to install this component
* Required field
Field Type Description actions
object Custom commands to run at various stages of a package lifecycle
Component actions are explored in the component actions documentation .
Field Type Description files
array Files or folders to place on disk during package deployment
Files can be:
Relative paths to either a file or directory (from the zarf.yaml
file)
A remote URL (http/https)
Verified using the shasum
field for data integrity (optional and only available for files)
- name : on-deploy-with-template-use-of-variable
# this file will be copied to the target location and the cat, dog, and snake sounds will be replaced with their values
# requires the on-deploy-with-dynamic-variable and on-deploy-with-multiple-variables components
target : test-templated.txt
shasum : 3c0404e0c767ace905c361fadded6c4b91fdb88aa07d5c42d2a220a87564836d
# Include the actual K3s binary
- source : https://github.com/k3s-io/k3s/releases/download/v1.28.4+k3s2/k3s
shasum : 9014535a4cd20c788282d60398a06279983562093455b53ab76701539ce67acf
# K3s magic provides these tools when symlinking
# Transfer the K3s images for containerd to pick them up
- source : https://github.com/k3s-io/k3s/releases/download/v1.28.4+k3s2/k3s-airgap-images-amd64.tar.zst
shasum : bc4d05bad56a583c80ff443d60e8277a136cc4357dc8527702d38b5cca28880d
target : /var/lib/rancher/k3s/agent/images/k3s.tar.zst
- cmd : if [ "$(uname -m)" != "x86_64" ]; then echo "this package architecture is amd64, but the target system has a different architecture. These architectures must be the same" && exit 1; fi
description : Check that the host architecture matches the package architecture
# ARM-64 version of the K3s stack
Field Type Description charts
array Helm charts to install during package deploy
Charts using the localPath
key can be:
Relative paths to either a file or directory (from the zarf.yaml
file)
Charts using the url
key can be:
A remote URL (http/https) to a Git repository
A remote URL (oci://) to an OCI registry
A remote URL (http/https) to a Helm repository
# Charts are organized in a list with unique chart names per component - note that a Zarf chart name does not need to match the chart name in a Chart.yaml
namespace : podinfo-from-local-chart
# In this case `localPath` will load the podinfo chart that is located in the `chart` directory
# Variables are used to override the default values in the chart
# This can be overridden by the user at deployment time with the `--set` flag
description : " Override the number of pod replicas "
namespace : podinfo-from-oci
# In this case `url` will load the helm chart located in the podinfo OCI repository
url : oci://ghcr.io/stefanprodan/charts/podinfo
namespace : podinfo-from-git
# In this case `url` will load the helm chart located in the podinfo git repository
url : https://github.com/stefanprodan/podinfo.git
# By default git will look in the root of the git repository but you can define a sub directory with `gitPath`
namespace : podinfo-from-repo
# In this case `url` will load the helm chart located in the podinfo helm repository
url : https://stefanprodan.github.io/podinfo
# By default the chart `name` will be what is used to search a repository but since Zarf chart names must be unique per-component you can override this with `repoName`
# By default the release name will be the chart name, but you can override this with the `releaseName` key
releaseName : cool-release-name
- ghcr.io/stefanprodan/podinfo:6.4.0
# This is the cosign signature for the podinfo image for image signature verification
- ghcr.io/stefanprodan/podinfo:sha256-57a654ace69ec02ba8973093b6a786faa15640575fbf0dbb603db55aca2ccec8.sig
namespace : podinfo-from-local-chart
namespace : podinfo-from-oci
namespace : podinfo-from-git
name : cool-release-name-podinfo
namespace : podinfo-from-repo
# YAML keys starting with `x-` are custom keys that are ignored by the Zarf CLI
# The `x-mdx` key is used to render the markdown content for https://docs.zarf.dev/ref/examples
This example shows the many ways you can deploy Helm Charts with Zarf. To learn more about how `charts` work in Zarf, see the [Helm Charts section](/ref/components/#helm-charts) of the package components documentation.
Field Type Description manifests
array Kubernetes manifests to be included in a generated Helm chart on package deploy
Manifests under the files
key can be:
Relative paths to a Kubernetes manifest file (from the zarf.yaml
file)
Verified using the url@shasum
syntax for data integrity (optional and only for remote URLs)
Manifests under the kustomizations
key can be:
Any valid Kustomize reference both local and remote (ie. anything you could do a kustomize build
on)
Note
Zarf dynamically generates a Helm Chart from the named manifest entries that you specify. This means that any given set of files under a manifest entry will be applied according to Helm Chart template and manifest install ordering and not necessarily in the order that files are declared. If ordering is important, consider moving each file into its own manifest entry in the manifests
array.
- name : simple-httpd-deployment
# local manifests are specified relative to the `zarf.yaml` that uses them:
# the following checks were computed by viewing the success state of the package deployment
# and creating `wait` actions that match
condition : " {.status.readyReplicas}=2 "
# image discovery is supported in all manifests and charts using:
# zarf prepare find-images
- name : simple-nginx-deployment
# remote manifests are specified with a URL and you can verify integrity of a manifest
# by adding a sha256sum to the end of the URL, separated by an @:
- https://k8s.io/examples/application/deployment.yaml@c57f73449b26eae02ca2a549c388807d49ef6d3f2dc040a9bbb1290128d97157
# this sha256 can be discovered using:
# zarf prepare sha256sum https://k8s.io/examples/application/deployment.yaml
# the following checks were computed by viewing the success state of the package deployment
# and creating `wait` actions that match
# image discovery is supported in all manifests and charts using:
# zarf prepare find-images
Note
Kustomizations are handled a bit differently than normal manifests in that Zarf will automatically run kustomize build
on them during zarf package create
, thus rendering the Kustomization into a single manifest file. This prevents needing to grab any remote Kustomization resources during zarf package deploy
but also means that any Zarf variables
will only apply to the rendered manifest not the kustomize build
process.
- name : podinfo-kustomize
- name : simple-podinfo-deployment
# kustomizations can be specified relative to the `zarf.yaml` or as remoteBuild resources with the
# following syntax: https://github.com/kubernetes-sigs/kustomize/blob/master/examples/remoteBuild.md:
- github.com/stefanprodan/podinfo//kustomize?ref=6.4.0
# while ?ref= is not a requirement, it is recommended to use a specific commit hash / git tag to
# ensure that the kustomization is not changed in a way that breaks your deployment.
# the following checks were computed by viewing the success state of the package deployment
# and creating `wait` actions that match
# image discovery is supported in all manifests and charts using:
# zarf prepare find-images
- ghcr.io/stefanprodan/podinfo:6.4.0
# YAML keys starting with `x-` are custom keys that are ignored by the Zarf CLI
# The `x-mdx` key is used to render the markdown content for https://docs.zarf.dev/ref/examples
This example shows you how to specify Kubernetes resources in a component's `manifests` list. These files can either be local or remote and under the hood Zarf will wrap them in an auto-generated helm chart to manage their install, rollback, and uninstall logic.
To learn more about how `manifests` work in Zarf, see the [Kubernetes Manifests section](/ref/components/#kubernetes-manifests) of the package components documentation.
Field Type Description images
array List of OCI images to include in the package
Images can either be discovered manually, or automatically by using zarf dev find-images
.
Note
zarf dev find-images
will find images for most standard manifests, kustomizations, and helm charts, however some images cannot be discovered this way as some upstream resources (like operators) may bury image definitions inside. For these images, zarf dev find-images
also offers support for the draft Helm Improvement Proposal 15 which allows chart creators to annotate any hidden images in their charts along with the values conditions that will cause those images to be used.
description : Installs the flux CRDs / controllers to use flux-based deployments in the cluster
- ghcr.io/fluxcd/kustomize-controller:v0.27.1
- ghcr.io/fluxcd/source-controller:v0.28.0
The podinfo-flux
example showcases a simple GitOps workflow using Flux and Zarf.
Field Type Description repos
array List of git repos to include in the package
# The following performs a full Git Repo Mirror with `go-git` (internal to Zarf)
- https://github.com/defenseunicorns/zarf-public-test.git
# The following performs a full Git Repo Mirror forcing a fallback to host `git`
- https://dev.azure.com/defenseunicorns/zarf-public-test/_git/zarf-public-test
# The following performs a tag Git Repo Mirror with `go-git` (internal to Zarf)
- https://github.com/defenseunicorns/zarf-public-test.git@v0.0.1
# The following performs a refspec tag Git Repo Mirror with `go-git`
- https://github.com/defenseunicorns/zarf-public-test.git@refs/tags/v0.0.1
# The following performs a tag Git Repo Mirror forcing a fallback to host `git`
- https://dev.azure.com/defenseunicorns/zarf-public-test/_git/zarf-public-test@v0.0.1
# The following performs a branch Git Repo Mirror with `go-git` (internal to Zarf)
- https://github.com/defenseunicorns/zarf-public-test.git@refs/heads/dragons
# The following performs a branch Git Repo Mirror forcing a fallback to host `git`
- https://dev.azure.com/defenseunicorns/zarf-public-test/_git/zarf-public-test@refs/heads/dragons
# The following performs a SHA Git Repo Mirror with `go-git` (internal to Zarf)
- https://github.com/defenseunicorns/zarf-public-test.git@01a23218923f24194133b5eb11268cf8d73ff1bb
# The following performs a SHA Git Repo Mirror forcing a fallback to host `git`
- https://dev.azure.com/defenseunicorns/zarf-public-test/_git/zarf-public-test@01a23218923f24194133b5eb11268cf8d73ff1bb
# YAML keys starting with `x-` are custom keys that are ignored by the Zarf CLI
# The `x-mdx` key is used to render the markdown content for https://docs.zarf.dev/ref/examples
To learn more about how Zarf handles `git` repositories, see the [Git Repositories section](/ref/components/#git-repositories) of the package components documentation.
Tag-based git
repository cloning is the recommended way of cloning a git
repository for air-gapped deployments because it wraps meaning around a specific point in git history that can easily be traced back to the online world. Tag-based clones are defined using the scheme://host/repo@tag
format as seen in the example of the defenseunicorns/zarf
repository (https://github.com/defenseunicorns/zarf.git@v0.15.0
).
A tag-based clone only mirrors the tag defined in the Zarf definition. The tag will be applied on the git
mirror to a zarf-specific branch name based on the tag name (e.g. the tag v0.1.0
will be pushed to the zarf-ref-v0.1.0
branch). This ensures that this tag will be pushed and received properly by the airgap git
server.
Note
If you would like to use a protocol scheme other than http/https, you can do so with something like the following: ssh://git@github.com/defenseunicorns/zarf.git@v0.15.0
. Using this you can also clone from a local repo to help you manage larger git repositories: file:///home/zarf/workspace/zarf@v0.15.0
.
Caution
Because Zarf creates long-lived mirrors of repositories in the air gap, it does not support shallow clones (i.e. git clone --depth x
). These may be present in build environments (i.e. GitLab runners ) and should be avoided. To learn more about shallow and partial clones see the GitHub blog on the topic .
# The following performs a tag Git Repo Mirror with `go-git` (internal to Zarf)
- https://github.com/defenseunicorns/zarf-public-test.git@v0.0.1
# The following performs a refspec tag Git Repo Mirror with `go-git`
- https://github.com/defenseunicorns/zarf-public-test.git@refs/tags/v0.0.1
# The following performs a tag Git Repo Mirror forcing a fallback to host `git`
- https://dev.azure.com/defenseunicorns/zarf-public-test/_git/zarf-public-test@v0.0.1
In addition to tags, Zarf also supports cloning and pushing a specific SHA hash from a git
repository, but this is not recommended as it is less readable/understandable than tag cloning. Commit SHAs are defined using the same scheme://host/repo@shasum
format as seen in the example of the defenseunicorns/zarf
repository (https://github.com/defenseunicorns/zarf.git@c74e2e9626da0400e0a41e78319b3054c53a5d4e
).
A SHA-based clone only mirrors the SHA hash defined in the Zarf definition. The SHA will be applied on the git
mirror to a zarf-specific branch name based on the SHA hash (e.g. the SHA c74e2e9626da0400e0a41e78319b3054c53a5d4e
will be pushed to the zarf-ref-c74e2e9626da0400e0a41e78319b3054c53a5d4e
branch). This ensures that this tag will be pushed and received properly by the airgap git
server.
# The following performs a SHA Git Repo Mirror with `go-git` (internal to Zarf)
- https://github.com/defenseunicorns/zarf-public-test.git@01a23218923f24194133b5eb11268cf8d73ff1bb
# The following performs a SHA Git Repo Mirror forcing a fallback to host `git`
- https://dev.azure.com/defenseunicorns/zarf-public-test/_git/zarf-public-test@01a23218923f24194133b5eb11268cf8d73ff1bb
# YAML keys starting with `x-` are custom keys that are ignored by the Zarf CLI
# The `x-mdx` key is used to render the markdown content for https://docs.zarf.dev/ref/examples
To learn more about how Zarf handles `git` repositories, see the [Git Repositories section](/ref/components/#git-repositories) of the package components documentation.
If you need even more control, Zarf also supports providing full git
refspecs , as seen in https://repo1.dso.mil/big-bang/bigbang.git@refs/heads/release-1.54.x
. This allows you to pull specific tags or branches by using this standard. The branch name used by zarf on deploy will depend on the kind of ref specified, branches will use the upstream branch name, whereas other refs (namely tags) will use the zarf-ref-*
branch name.
Full clones are used in this example with the stefanprodan/podinfo
repository and follow the scheme://host/repo
format (https://github.com/stefanprodan/podinfo.git
). Full clones will contain all branches and tags in the mirrored repository rather than any one specific tag.
# The following performs a full Git Repo Mirror with `go-git` (internal to Zarf)
- https://github.com/defenseunicorns/zarf-public-test.git
# The following performs a full Git Repo Mirror forcing a fallback to host `git`
- https://dev.azure.com/defenseunicorns/zarf-public-test/_git/zarf-public-test
Field Type Description dataInjections
array Datasets to inject into a container in the target cluster
- manifests/persistence.yaml
- manifests/deployment.yaml
- ghcr.io/kiwix/kiwix-serve:3.5.0-2
# Add new data into the cluster, these will keep trying up until their timeout
# Injection in the data directory using the data-loader init container
selector : app=kiwix-serve
# Download a .zim file of a DevOps Stack Exchange snapshot into the data directory for use with Kiwix
- cmd : curl https://zarf-examples.s3.amazonaws.com/devops.stackexchange.com_en_all_2023-05.zim -o zim-data/devops.stackexchange.com_en_all_2023-05.zim
# Below are some more examples of *.zim files of available content:
# https://library.kiwix.org/?lang=eng
# NOTE: If `zarf package create`ing regularly you should mirror content to a web host you control to be a friendly neighbor
# YAML keys starting with `x-` are custom keys that are ignored by the Zarf CLI
# The `x-mdx` key is used to render the markdown content for https://docs.zarf.dev/ref/examples
This example shows Zarf's ability to inject data into a container running in a pod, in this case to initialize a [Kiwix server](https://www.kiwix.org/en/) to allow offline viewing of documentation and wiki pages.
Data injections allow for data that is not included in the container image to be injected at deploy time and are declared using the `dataInjections` key within a component. Once the specified container is started, Zarf will copy the files and folders from the specified source into the specified container and path.
Data injections depend on the `tar` (and for `compress`, `gzip`) executables and their implementation across operating systems. Between macOS and Linux there is general agreement on how these utilities should function, however on Windows you may see issues enabling compression.
To resolve this you can either disable compression or use the GNU core-utils version of `tar` and `gzip`.
Field Type Description import
object Import a component from another Zarf package
The import
key in Zarf supports two modes to pull in a component:
The path
key allows you to specify a path to a directory that contains the zarf.yaml
that you wish to import on your local filesystem. This allows you to have a common component that you can reuse across multiple packages within a project (i.e. within one team/codebase).
The url
key allows you to specify an oci://
URL to a skeleton package that was published to an OCI registry. Skeleton packages are special package bundles that contain the zarf.yaml
package definition and any local files referenced by that definition at publish time. This allows you to version a set of reusable components and import them into multiple packages across projects (i.e. across teams/codebases).
# The component logic keys ('required', 'group', and 'default') always override those of the imported package
# group: "" # the initial value overrides the child component
# default: false # the initial value overrides the child component
description : " Example of a local composed package with a unique description for this component "
# The local relative path to the folder containing this component's package definition
# Example optional custom name to point to in the imported package (default is to use this component's name)
# 'name'd Zarf primitives will merge the arrays together on import:
# - 'manifests' of the same name will merge namespace, files and kustomizations
# - 'charts' of the same name will merge namespace, releaseName and valuesFiles
# Zarf primitives without matching 'name's will be appended to the end of the primitive's list for that component.
# The component logic keys ('required', 'group', and 'default') always override those of the imported package
# required: false # the initial value overrides the child component
# group: "" # the initial value overrides the child component
# default: false # the initial value overrides the child component
# The URL to the skeleton package containing this component's package definition
url : oci://🦄/dos-games:1.0.0
# Example optional custom name to point to in the imported package (default is to use this component's name)
# Un'name'd Zarf primitives will be appended to the end of the primitive's list for that component.
- cmd : ./zarf tools kubectl get -n dos-games deployment -o jsonpath={.items[0].metadata.creationTimestamp}
# YAML keys starting with `x-` are custom keys that are ignored by the Zarf CLI
# The `x-mdx` key is used to render the markdown content for https://docs.zarf.dev/ref/examples
As you can see in the example, the `import` key can be combined with other keys to merge components together. This can be done as many components deep as you wish and in the end will generate one main `zarf.yaml` file with all of the defined resources included.
This is useful if you want to slightly tweak a given component while maintaining a common core.
When merging components together Zarf will adopt the following strategies depending on the kind of primitive (files
, required
, manifests
) that it is merging:
Kind Key(s) Description Component Behavior name
, group
, default
, required
These keys control how Zarf interacts with a given component and will always take the value of the overriding component Component Description description
This key will only take the value of the overriding component if it is not empty Cosign Key Path cosignKeyPath
[Deprecated] This key will only take the value of the overriding component if it is not empty Un’name’d Primitive Arrays actions
, dataInjections
, files
, images
, repos
These keys will append the overriding component’s version of the array to the end of the base component’s array ’name’d Primitive Arrays charts
, manifests
For any given element in the overriding component, if the element matches based on name
then its values will be merged with the base element of the same name
. If not then the element will be appended to the end of the array
Field Type Description extensions
object Extend component functionality with additional features
./zarf tools kubectl patch helmrelease -n bigbang bigbang --type=merge -p '{"spec":{"suspend":true}}'
./zarf tools kubectl delete helmrelease -n bigbang istio --ignore-not-found
./zarf tools kubectl delete helmrelease -n bigbang istio-operator --ignore-not-found
./zarf tools kubectl delete helmrelease -n bigbang monitoring --ignore-not-found
./zarf tools kubectl delete providers grafana -n monitoring --ignore-not-found
./zarf tools kubectl delete alerts grafana -n monitoring --ignore-not-found
./zarf tools kubectl delete helmrelease -n bigbang promtail --ignore-not-found
./zarf tools kubectl delete helmrelease -n bigbang loki --ignore-not-found
./zarf tools kubectl delete kiali -n kiali kiali --ignore-not-found
./zarf tools kubectl delete helmrelease -n bigbang tempo --ignore-not-found
./zarf tools kubectl delete helmrelease -n bigbang neuvector --ignore-not-found
./zarf tools kubectl delete validatingwebhookconfigurations.admissionregistration.k8s.io neuvector-validating-crd-webhook --ignore-not-found
./zarf tools kubectl delete helmrelease -n bigbang kyverno-reporter --ignore-not-found
./zarf tools kubectl delete helmrelease -n bigbang kyverno-policies --ignore-not-found
./zarf tools kubectl delete helmrelease -n bigbang kyverno --ignore-not-found
./zarf tools kubectl delete validatingwebhookconfigurations.admissionregistration.k8s.io kyverno-policy-validating-webhook-cfg kyverno-resource-validating-webhook-cfg --ignore-not-found
./zarf tools kubectl delete helmrelease -n bigbang kiali --ignore-not-found
./zarf tools kubectl delete helmrelease -n bigbang metrics-server --ignore-not-found
./zarf tools kubectl delete apiservices.apiregistration.k8s.io -l helm.toolkit.fluxcd.io/namespace=bigbang,helm.toolkit.fluxcd.io/name=metrics-server --ignore-not-found
./zarf tools kubectl delete gitrepositories -n bigbang -l app.kubernetes.io/part-of=bigbang
description : " Cleaning up Big Bang resources "
# renovate: datasource=gitlab-releases depName=big-bang/bigbang versioning=semver registryUrl=https://repo1.dso.mil/
# Use Kyverno instead of Gatekeeper
# Needed when running in k3s. Otherwise Neuvector fails to start with an error saying it can't detect its runtime
# Values are merged in order, so this would override the above and disable everything if uncommented
# - config/disable-all.yaml
When deploying a Zarf package, components are deployed in the order they are defined in the zarf.yaml
.
The zarf.yaml
configuration for each component also defines whether the component is ‘required’ or not. ‘Required’ components are always deployed without any additional user interaction while optional components are printed out in an interactive prompt asking the user if they wish to the deploy the component.
If you already know which components you want to deploy, you can do so without getting prompted by passing the components as a comma-separated list to the --components
flag during the deploy command.
# deploy all required components, prompting for optional components and variables
$ zarf package deploy ./path/to/package.tar.zst
# deploy all required components, ignoring optional components and variable prompts
$ zarf package deploy ./path/to/package.tar.zst --confirm
# deploy optional-component-1 and optional-component-2 components whether they are required or not
$ zarf package deploy ./path/to/package.tar.zst --components=optional-component-1,optional-component-2
Tip
You can deploy components in a package using globbing as well. The following would deploy all components regardless of optional status:
# deploy optional-component-1 and optional-component-2 components whether they are required or not
$ zarf package deploy ./path/to/package.tar.zst --components= *
If you have any default
components in a package definition you can also exclude those from the CLI with a leading dash (-
) (similar to how you can exclude search terms in a search engine).
# deploy optional-component-1 but exclude default-component-1
$ zarf package deploy ./path/to/package.tar.zst --components=optional-component-1,-default-component-1