Components
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. |
healthChecks | array | List of resources to health check after deployment |
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. |
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 files: # 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 - source: test.txt target: test-templated.txt shasum: 3c0404e0c767ace905c361fadded6c4b91fdb88aa07d5c42d2a220a87564836d
- name: k3s only: localOS: linux cluster: architecture: amd64 description: > *** REQUIRES ROOT (not sudo) *** Install K3s, a certified Kubernetes distribution built for IoT & Edge computing. K3s provides the cluster need for Zarf running in Appliance Mode as well as can host a low-resource Gitops Service if not using an existing Kubernetes platform. files: # K3s removal script - source: zarf-clean-k3s.sh target: /opt/zarf/zarf-clean-k3s.sh executable: true # The K3s systemd service definition - source: k3s.service target: /etc/systemd/system/k3s.service symlinks: - /etc/systemd/system/multi-user.target.wants/k3s.service # Include the actual K3s binary - source: https://github.com/k3s-io/k3s/releases/download/v1.29.10+k3s1/k3s shasum: 5b82d6964ae1720a2cd5a5198a7732636ae6076321d497f5533502e2e488f53f target: /usr/sbin/k3s executable: true # K3s magic provides these tools when symlinking symlinks: - /usr/sbin/kubectl - /usr/sbin/ctr - /usr/sbin/crictl # Transfer the K3s images for containerd to pick them up - source: https://github.com/k3s-io/k3s/releases/download/v1.29.10+k3s1/k3s-airgap-images-amd64.tar.zst shasum: 09e644d380d27a845f5c8028066271cd712d0ac6fcfc283ba44ec532adb2ca6f target: /var/lib/rancher/k3s/agent/images/k3s.tar.zst actions: onDeploy: defaults: maxRetries: 5 before: - 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 maxRetries: 0 - cmd: ./zarf internal is-valid-hostname maxRetries: 0 description: Check if the current system has a, RFC1123 compliant hostname # If running RHEL variant, disable firewalld # https://rancher.com/docs/k3s/latest/en/advanced/#additional-preparation-for-red-hat-centos-enterprise-linux # NOTE: The empty echo prevents infinite retry loops on non-RHEL systems where the exit code would be an error - cmd: "[ -e /etc/redhat-release ] && systemctl disable firewalld --now || echo ''" description: If running a RHEL variant, disable 'firewalld' per k3s docs after: # Configure K3s systemd service - cmd: systemctl daemon-reload description: Reload the system services - cmd: systemctl enable k3s description: Enable 'k3s' to run at system boot - cmd: systemctl restart k3s description: Start the 'k3s' system service onRemove: before: - cmd: /opt/zarf/zarf-clean-k3s.sh description: Remove 'k3s' from the system - cmd: rm /opt/zarf/zarf-clean-k3s.sh description: Remove the cleanup script
# 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
- name: demo-helm-charts required: true charts: # 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 - name: podinfo-local version: 6.4.0 namespace: podinfo-from-local-chart # In this case `localPath` will load the podinfo chart that is located in the `chart` directory localPath: chart valuesFiles: - values.yaml # 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 variables: - name: REPLICA_COUNT description: "Override the number of pod replicas" path: replicaCount
- name: podinfo-oci version: 6.4.0 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 valuesFiles: - values.yaml
- name: podinfo-git version: 6.4.0 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` gitPath: charts/podinfo valuesFiles: - values.yaml
- name: podinfo-repo version: 6.4.0 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` repoName: podinfo # By default the release name will be the chart name, but you can override this with the `releaseName` key releaseName: cool-release-name valuesFiles: - values.yaml images: - 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
# 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/examplesx-mdx: | 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)
- name: httpd-local required: true manifests: - name: simple-httpd-deployment namespace: httpd files: # local manifests are specified relative to the `zarf.yaml` that uses them: - httpd-deployment.yaml # image discovery is supported in all manifests and charts using: # zarf prepare find-images images: - httpd:alpine3.18
- name: nginx-remote required: true manifests: - name: simple-nginx-deployment namespace: nginx files: # 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 # image discovery is supported in all manifests and charts using: # zarf prepare find-images images: - nginx:1.14.2
- name: podinfo-kustomize required: true manifests: - name: simple-podinfo-deployment namespace: podinfo kustomizations: # 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: - https://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. # image discovery is supported in all manifests and charts using: # zarf prepare find-images 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/examplesx-mdx: | 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
. The image list is not limited to containers, any OCI image following the Image Manifest specification can be pulled
- name: flux description: Installs the flux CRDs / controllers to use flux-based deployments in the cluster required: true manifests: - name: flux-install namespace: flux files: - https://github.com/fluxcd/flux2/releases/download/v2.4.0/install.yaml images: - ghcr.io/fluxcd/helm-controller:v1.1.0 - ghcr.io/fluxcd/image-automation-controller:v0.39.0 - ghcr.io/fluxcd/image-reflector-controller:v0.33.0 - ghcr.io/fluxcd/kustomize-controller:v1.4.0 - ghcr.io/fluxcd/notification-controller:v1.4.0 - ghcr.io/fluxcd/source-controller:v1.4.1
Field | Type | Description |
---|---|---|
repos | array | List of git repos to include in the package. |
The podinfo-flux
example showcases a simple GitOps workflow using Flux and Zarf.
- name: full-repo repos: # The following performs a full Git Repo Mirror with `go-git` (internal to Zarf) - https://github.com/zarf-dev/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
- name: specific-tag repos: # The following performs a tag Git Repo Mirror with `go-git` (internal to Zarf) - https://github.com/zarf-dev/zarf-public-test.git@v0.0.1 # The following performs a refspec tag Git Repo Mirror with `go-git` - https://github.com/zarf-dev/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
- name: specific-branch repos: # The following performs a branch Git Repo Mirror with `go-git` (internal to Zarf) - https://github.com/zarf-dev/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
- name: specific-hash repos: # The following performs a SHA Git Repo Mirror with `go-git` (internal to Zarf) - https://github.com/zarf-dev/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/examplesx-mdx: | 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 zarf-dev/zarf
repository (https://github.com/zarf-dev/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.
- name: specific-tag repos: # The following performs a tag Git Repo Mirror with `go-git` (internal to Zarf) - https://github.com/zarf-dev/zarf-public-test.git@v0.0.1 # The following performs a refspec tag Git Repo Mirror with `go-git` - https://github.com/zarf-dev/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 zarf-dev/zarf
repository (https://github.com/zarf-dev/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.
- name: specific-hash repos: # The following performs a SHA Git Repo Mirror with `go-git` (internal to Zarf) - https://github.com/zarf-dev/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/examplesx-mdx: | 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.
- name: full-repo repos: # The following performs a full Git Repo Mirror with `go-git` (internal to Zarf) - https://github.com/zarf-dev/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. |
During zarf package create
, data injections pull files from the host at the path specified by the source
key. During zarf package deploy
, these files are injected into the container specified by the target
key. The pod holding the targeted container must have the variable ###ZARF_DATA_INJECTION_MARKER###
within the pod spec otherwise the data injection will not occur. This variable gets templated at deploy time to become the name of the extra file Zarf injects into the pod to signify that the data injection is complete.
The kiwix
example showcases a simple data injection use case.
- name: kiwix-serve required: true manifests: - name: kiwix-serve namespace: kiwix files: - manifests/persistence.yaml - manifests/deployment.yaml - manifests/service.yaml images: - ghcr.io/kiwix/kiwix-serve:3.5.0-2 - alpine:3.18 # Add new data into the cluster, these will keep trying up until their timeout dataInjections: # Injection in the data directory using the data-loader init container - source: zim-data target: namespace: kiwix selector: app=kiwix-serve container: data-loader path: /data compress: true actions: onCreate: before: # Download a .zim file of a DevOps Stack Exchange snapshot into the data directory for use with Kiwix - cmd: curl https://zarf-remote.s3.us-east-2.amazonaws.com/testdata/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/examplesx-mdx: | 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.
:::caution
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 thezarf.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 anoci://
URL to a skeleton package that was published to an OCI registry. Skeleton packages are special package bundles that contain thezarf.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).
- name: local-games-path # The component logic keys ('required', 'group', and 'default') always override those of the imported package required: true # 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" import: # The local relative path to the folder containing this component's package definition path: ../dos-games # Example optional custom name to point to in the imported package (default is to use this component's name) name: baseline # '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. manifests: - name: multi-games files: - quake-service.yaml
- name: oci-games-url # 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 import: # The URL to the skeleton package containing this component's package definition url: oci://ghcr.io/zarf-dev/packages/dos-games:1.1.0 # Example optional custom name to point to in the imported package (default is to use this component's name) name: baseline # Un'name'd Zarf primitives will be appended to the end of the primitive's list for that component. actions: onDeploy: before: - 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/examplesx-mdx: | 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 |
---|---|---|
healthChecks | array | List of resources to health check after deployment |
Health checks wait until the specified resources are fully reconciled, meaning that their desired and current states match. Internally, kstatus is used to assess when reconciliation is complete. Health checks supports all Kubernetes resources that implement the status field, including custom resource definitions. If the status field is not implemented on a resource, it will automatically pass the health check.
healthChecks: - name: my-pod namespace: my-namespace apiVersion: v1 kind: Pod - name: my-stateful-set namespace: my-namespace apiVersion: apps/v1 kind: StatefulSet
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
Extensions were removed from Zarf in v0.41.0. To create packages similar to those previously built with extensions, check out https://github.com/defenseunicorns-partnerships/generate-big-bang-zarf-package