Skip to content

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 during zarf package create.
  • onDeploy - Runs during zarf package deploy.
  • onRemove - Runs during zarf 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 for create, deploy, or remove.
  • after - sequential list of actions that will run after this component is successfully processed for create, deploy, or remove.
  • onSuccess - sequential list of actions that will run after ALL after 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 display Waiting for "File to be created" instead of Waiting 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 of name=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 is sh for macOS/Linux and powershell 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 using http or https, or success 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

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.
  • 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.
  • Add env entries for all previously declared Zarf variables.
    • This allows you to use variables in actions and when combined with setVariables allows you to chain variables from an action for use in later actions or templates.

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 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/examples
x-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`.
:::