tldr; Using the wait action to create simple end-to-end tests for Zarf components.

Overview

A little know and under-documented feature of Zarf components is the ability to wait on arbitrary Kubernetes resources to be ready during deploy actions. This is a very powerful feature as it allows for creating simple end-to-end tests that live in the same declarative land as the component it is testing.

under the hood this is a wrapper around the kubectl wait command, which can always be manually accessed via ./zarf tools kubectl wait ... inside of actions

Testing Helm Charts

Let's take a look at creating a Zarf package that deploys the base Helm chart w/ a simple NGINX server as well as podinfo via OCI.

$ mkdir zarf-tdd
$ cd zarf-tdd
$ helm create local
Creating local
$ mv local chart

Then we'll add a zarf.yaml file to the root of the package:

# zarf.yaml
kind: ZarfPackageConfig
metadata:
  name: zarf-tdd
  description: A simple TDD package
  version: 0.0.1

components:
  - name: simple-helm
    required: true
    charts:
      - name: local
        version: 0.1.0
        namespace: simple-helm
        localPath: chart
      - name: oci-demo
        version: 6.3.3
        namespace: podinfo
        url: oci://ghcr.io/stefanprodan/charts/podinfo
    images:
      - nginx:1.16.0
      - ghcr.io/stefanprodan/podinfo:6.3.3
    actions:
      onDeploy:
        after:
          - wait:
              cluster:
                kind: deployment
                name: local
                namespace: simple-helm
                condition: available
          - wait:
              cluster:
                kind: pod
                # `name` can be either a resource name or a label selector
                name: app.kubernetes.io/name=oci-demo-podinfo
                namespace: podinfo
                condition: ready

Testing HTTP Endpoints

Sometimes you may want to test a network endpoint to ensure it is ready before continuing with the deployment (looking at you Registry1).

# using the same zarf.yaml as above
...

  - name: image-from-registry1
    required: true
    images:
      - registry1.dso.mil/ironbank/big-bang/base:2.0.0
    actions:
      onCreate:
        before:
          - wait:
                network:
                    protocol: https
                    address: registry1.dso.mil

The world is your oyster, and the Zarf team cannot wait to see the innovative ways other Unicorns extend this feature. For more examples, I have mirrored the Zarf CLI docs below.

CLI Help

$ ./zarf tools wait-for --help

By default Zarf will wait for all Kubernetes resources to be ready before completion of a component during a deployment. 
This command can be used to wait for a Kubernetes resources to exist and be ready that may be created by a Gitops tool or a Kubernetes operator. 
You can also wait for aribtrary network endpoints using REST or TCP checks.

Usage:
  zarf tools wait-for {KIND|PROTOCOL} {NAME|SELECTOR|URI} {CONDITION|HTTP_CODE} [flags]

Aliases:
  wait-for, w, wait

Examples:
    Wait for Kubernetes resources:
        zarf tools wait-for pod my-pod-name ready -n default                    wait for pod my-pod-name in namespace default to be ready
        zarf tools wait-for p cool-pod-name ready -n cool                       wait for pod (using p alias) cool-pod-name in namespace cool to be ready
        zarf tools wait-for deployment podinfo available -n podinfo             wait for deployment podinfo in namespace podinfo to be available
        zarf tools wait-for pod app=podinfo ready -n podinfo                    wait for pod with label app=podinfo in namespace podinfo to be ready
        zarf tools wait-for svc zarf-docker-registry exists -n zarf             wait for service zarf-docker-registry in namespace zarf to exist
        zarf tools wait-for svc zarf-docker-registry -n zarf                    same as above, except exists is the default condition
        zarf tools wati-for crd addons.k3s.cattle.io                            wait for crd addons.k3s.cattle.io to exist

    Wait for network endpoints:
        zarf tools wait-for http localhost:8080 200                             wait for a 200 response from http://localhost:8080
        zarf tools wait-for tcp localhost:8080                                  wait for a connection to be established on localhost:8080
        zarf tools wait-for https 1.1.1.1 200                                   wait for a 200 response from https://1.1.1.1
        zarf tools wait-for http google.com                                     wait for any 2xx response from http://google.com
        zarf tools wait-for http google.com success                             wait for any 2xx response from http://google.com
  

Flags:
  -h, --help               help for wait-for
  -n, --namespace string   Specify the namespace of the resources to wait for.
      --timeout string     Specify the timeout duration for the wait command. (default "5m")