Actions
Component Actions offer several exec entrypoints that allow a component to perform additional logic at key stages of its lifecycle. These actions are executed within a shell with the same context as the Zarf binary. For a detailed overview of the execution sequence of component actions, please refer to the Zarf package create lifecycle documentation and package deploy lifecycle documentation. Additionally, you can experiment with the component actions example located in the Component Actions example.
The component.actions
field includes the following optional keys, also known as action sets
:
onCreate
- Runs duringzarf package create
.onDeploy
- Runs duringzarf package deploy
.onRemove
- Runs duringzarf package remove
.
These action sets
contain optional action lists
. The onSuccess
and onFailure
action lists are conditional and rely on the success or failure of previous actions within the same component, as well as the component”s lifecycle stages.
before
- sequential list of actions that will run before this component is processed forcreate
,deploy
, orremove
.after
- sequential list of actions that will run after this component is successfully processed forcreate
,deploy
, orremove
.onSuccess
- sequential list of actions that will run after ALLafter
actions have successfully completed.onFailure
- sequential list of actions that will run after ANY error during the above actions or component operations.
In addition to action lists
, action sets
can also specify a defaults
section that will be applied to all actions in the set. The defaults
section contains all of the same elements as an action configuration, with the exception of the action specific keys like cmd
, description
or wait
, which are not allowed in the defaults
section.
An action list
contains an ordered set of action configurations
that specify what a particular action will do. In Zarf there are two action types (cmd
and wait
), the configuration of which is described below.
Between all action configurations, there are a few common keys that are common to all of them which are described below:
description
- a description of the action that will replace the default text displayed to the user when the action is running. For example:description: "File to be created"
would displayWaiting for "File to be created"
instead ofWaiting for "touch test-create-before.txt"
.maxTotalSeconds
- the maximum total time to allow the command to run (default:0
- no limit for command actions,300
- 5 minutes for wait actions).
A cmd
action executes arbitrary commands or scripts within a shell wrapper. You can use the cmd
key to define the command(s) to run. This can also be a multi-line script. You cannot use cmd
and wait
in the same action.
Within each of the action
lists (before
, after
, onSuccess
, and onFailure
), the following action configurations are available:
cmd
- (required if not a wait action) the command to run.dir
- the directory to run the command in, defaults to the current working directory.mute
- whether to mute the realtime output of the command, output is always shown at the end on failure (default:false
).maxRetries
- the maximum number of times to retry the command if it fails (default:0
- no retries).env
- an array of environment variables to set for the command in the form ofname=value
.setVariables
- set the standard output of the command to a list of variables that can be used in other actions or components (onDeploy only).shell
- set a preferred shell for the command to run in for a particular operating system (default issh
for macOS/Linux andpowershell
for Windows).
The wait
action temporarily halts the component stage it”s initiated in, either until the specified condition is satisfied or until the maxTotalSeconds time limit is exceeded (which, by default, is set to 5 minutes). To define wait
parameters, execute the wait
key; it”s essential to note that you cannot use cmd
and wait
in the same action. Essentially, a wait
action is yaml sugar for a call to ./zarf tools wait-for
.
Within each of the action
lists (before
, after
, onSuccess
, and onFailure
), the following action configurations are available:
wait
- (required if not a cmd action) the wait parameters.cluster
- perform a wait operation on a Kubernetes resource (kubectl wait).kind
- the kind of resource to wait for (required).name
- the name of the resource to wait for (required), can be a name or label selector.namespace
- the namespace of the resource to wait for.condition
- the condition to wait for (default:exists
).
network
- perform a wait operation on a network resource (curl).protocol
- the protocol to use (i.e.http
,https
,tcp
).address
- the address/port to wait for (required).code
- the HTTP status code to wait for if usinghttp
orhttps
, orsuccess
to check for any 2xx response code (default:success
).
Below are some examples of putting together simple actions at various points in the Zarf lifecycle:
Below is a simple example of an onCreate
action set that declares defaults
as well as before
and after
action lists:
- name: on-create actions: # runs during "zarf package create" onCreate: # defaults are applied to all actions in this action set - below are the default defaults defaults: dir: "" env: [] maxRetries: 0 maxTotalSeconds: 300 mute: false shell: darwin: sh linux: sh windows: powershell # runs before the component is created before: # on Windows with `pwsh` or `powershell`, `touch` is replaced with New-Item - cmd: touch test-create-before.txt # description shows a more user friendly message when waiting for the command description: Create a test file # dir is the directory to run the command in dir: "" # env sets environment variables for this action only env: - thing=stuff # maxRetries is the number of times to retry the action if it fails maxRetries: 0 # maxTotalSeconds is the maximum amount of times the action can run before it is killed, over all retries maxTotalSeconds: 30 # mute determine if actions output should be printed to the console mute: false # shell sets the preferred shell across operating systems, in this case "pwsh" instead of "powershell" on Windows shell: windows: pwsh # runs after the component is created after: # actions in a list run in order - cmd: touch test-create-after.txt - cmd: sleep 0.5 - cmd: echo "I can print!" - cmd: sleep 0.5 # cmd actions can also specify a multiline string to run like a script - cmd: | echo "multiline!" sleep 0.5 echo "updates!" sleep 1 echo "in!" sleep 0.5 echo "realtime!" sleep 0.5
Below is an example of an onDeploy
action set that demonstrates how you can use onFailure
actions to perform cleanup tasks or user messaging when an action of component lifecycle step fails:
- name: on-deploy-with-timeout description: This component will fail after 1 second actions: # runs during "zarf package deploy" onDeploy: # defaults allow you to specify default values for the actions in that actionSet defaults: # maxTotalSeconds is the maximum amount of time the action can run before it is killed, over all retries maxTotalSeconds: 1 before: # this action will fail after 1 second - cmd: sleep 10 onFailure: - cmd: echo "😭😭😭 this action failed because it took too long to run 😭😭😭"
Below are examples of waiting for resources to exist or be available within an action using wait
actions:
- name: on-create-with-network-wait-action description: This component will wait for 15 seconds for a network resource to be available actions: onCreate: after: - description: Github.com to be available maxTotalSeconds: 15 wait: # wait for a network address to return a 200 OK response network: protocol: https address: github.com code: 200
- name: on-deploy-with-wait-action description: This component will wait for 5 seconds for the test-configmap to be exist manifests: - name: test-configmap files: - test-configmap.yaml actions: onDeploy: after: - description: The simple-configmap to exist maxTotalSeconds: 5 wait: # wait for the configmap to be available in the cluster cluster: kind: configmap name: simple-configmap namespace: zarf
As you may have noticed mentioned in the before
action list of the above Simple onCreate
example, Zarf provides some helpful transformations that help enhance cross-platform compatibility and allow you to better orchestrate Zarf and its components.
Below are the transformations that Zarf will make on an action before it is ran:
- Replace
./zarf
with the path to the currently running Zarf executable.- This allows you to run Zarf in Zarf and is designed to help you use
zarf tools
commands in the air gap.
- This allows you to run Zarf in Zarf and is designed to help you use
- Replace common Unix commands and shell syntax with
powershell
/pwsh
alternatives on Windows.- This allows commands like
touch
to work on Windows and while not perfect enhances cross-platform capabilities.
- This allows commands like
- Add
env
entries for all previously declared Zarfvariables
.- This allows you to use variables in actions and when combined with
setVariables
allows you to chainvariables
from an action for use in later actions or templates.
- This allows you to use variables in actions and when combined with
Within onDeploy
action lists, you can use the setVariables
action configuration to set a list of variables that can be used in other actions or components during zarf package deploy
. The variable value will be assigned in two environment variables: ZARF_VAR_{NAME}
and TF_VAR_{name}
. These values will be accessible in subsequent actions and can be used for templating in files
or manifests
in other components as ###ZARF_VAR_{NAME}###
. This feature allows package authors to define dynamic runtime variables for consumption by other components or actions.
- name: on-deploy-with-multiple-variables actions: # runs during "zarf package deploy" onDeploy: # runs before the component is deployed before: # setting this variable will allow it to be used in other actions with additional variables # set in other actions or components - cmd: echo "hiss" # setVariables defines a list of variables to set from the `cmd` standard out. setVariables: - name: SNAKE_SOUND # marks this variable as sensitive to prevent it from being output in the Zarf log sensitive: true # autoIndent tells Zarf to maintain spacing for any newlines when templating into a yaml file autoIndent: true # onSuccess will only run if steps in this component are successful onSuccess: # this action will print the CAT_SOUND variable that was set in a previous component - cmd: echo "the cat says ${ZARF_VAR_CAT_SOUND}" # this action will print the DOG_SOUND variable set at the top of the zarf.yaml file - cmd: echo "the dog says ${ZARF_VAR_DOG_SOUND}" # this action will print the SNAKE_SOUND variable set within this component # > NOTE: when including a variable in a command output this will be written to the log regardless of the sensitive setting # - use `mute` if you want to silence the command output for sensitive variables - cmd: echo "the snake says ${ZARF_VAR_SNAKE_SOUND}" # variables are also exposed as TF_VAR_name for terraform, note the lowercase variable name - cmd: echo "with a TF_VAR, the snake also says ${TF_VAR_snake_sound}"
Below is an example of an onRemove
action set that demonstrates how you can use ./zarf
to use Zarf commands like zarf tools kubectl
to perform actions on systems that might not have the pre-requisite software (like kubectl
) installed onto them:
- name: on-remove # A manifest that we expect to be removed by Zarf manifests: - name: test-configmap files: - test-configmap.yaml actions: # runs during "zarf package remove" onRemove: before: # because this runs before the manifest is removed this should return our manifest - cmd: ./zarf tools kubectl get configmap -n zarf remove-test-configmap || echo "Not Found" after: # because this runs after the manifest is removed this should no longer be found - cmd: ./zarf tools kubectl get configmap -n zarf remove-test-configmap || echo "Not Found"
Below are a few more use cases from other examples
and packages
for how actions can be used:
The below example shows the kiwix-serve
component from the data injections example which downloads a .zim
file with an onCreate.before
action for inclusion into the Zarf package.
- 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-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/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`.
:::
The below example includes the eksctl
binary and eks.yaml
file in one component, setting it up in an onDeploy.after
action and then uses the eksctl
binary in a second component to create an EKS cluster in an onDeploy.before
action.
- name: load-eksctl required: true files: - source: eks.yaml target: eks.yaml - source: https://github.com/weaveworks/eksctl/releases/download/v0.170.0/eksctl_Darwin_amd64.tar.gz target: binaries/eksctl_Darwin_x86_64 executable: true shasum: 88297c757fb1bc731f9ea29931c463a4575eb37f4cee27625774c88d5e8c95e2 extractPath: eksctl - source: https://github.com/weaveworks/eksctl/releases/download/v0.170.0/eksctl_Darwin_arm64.tar.gz target: binaries/eksctl_Darwin_arm64 executable: true shasum: ad97a3196dc8fcbba5c501cf386ab8637663bb6a3876e20bc991a1de07a0831e extractPath: eksctl - source: https://github.com/weaveworks/eksctl/releases/download/v0.170.0/eksctl_Linux_amd64.tar.gz target: binaries/eksctl_Linux_x86_64 executable: true shasum: 790b540f8931424d8c89c10dee4cb5567bff44a5e8ed018c7c3a0ac818cf2e05 extractPath: eksctl
- name: deploy-eks-cluster description: Create an EKS cluster! actions: onDeploy: before: - cmd: ./binaries/eksctl_$(uname -s)_$(uname -m) create cluster --dry-run -f eks.yaml - cmd: sleep 15 - cmd: ./binaries/eksctl_$(uname -s)_$(uname -m) create cluster -f eks.yaml - cmd: ./binaries/eksctl_$(uname -s)_$(uname -m) utils write-kubeconfig -c ${ZARF_VAR_EKS_CLUSTER_NAME}
The below example shows using a wait
command to wait for a GitOps deployment to happen after Zarf configures the initial GitRepository
manifest. By default Zarf will only track the resources it directly deploys, but adding a wait
action allows you to control the lifecycle more directly.
- name: podinfo-via-flux description: Example deployment via flux using the famous podinfo example required: true manifests: - name: podinfo-via-flux namespace: podinfo files: - podinfo-source.yaml - podinfo-kustomization.yaml repos: - https://github.com/stefanprodan/podinfo.git images: - ghcr.io/stefanprodan/podinfo:6.3.3 actions: onDeploy: after: # This will use a wait action to wait for the podinfo pod to be ready - description: Podinfo pods to be ready via wait action wait: cluster: kind: pod name: app=podinfo namespace: podinfo condition: ready
# 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 demonstrates how to use flux with Zarf to deploy the `stefanprodan/podinfo` app using GitOps.
It uses a vanilla configuration of flux with upstream containers.
To learn more about how Zarf handles `git` repositories, see the [Git Repositories section](/ref/components/#git-repositories) of the package components documentation.