Skip to content

Creating a Custom 'init' Package

Introduction

In most cases the default Zarf ‘init’ Package will provide what you need to get started deploying packages into the airgap, however there are cases where you may want to tweak this package to tailor it for your target environment. This could include adding or removing components or including hardened versions of components specific to your use case.

In this tutorial, we will demonstrate how to build a custom Zarf ‘init’ Package with zarf package create.

When creating a Zarf ‘init’ package, you must have a network connection so that Zarf can fetch all of the dependencies and resources necessary to build the package. If your version of the ‘init’ package is using images from a private registry or is referencing repositories in a private repository, you will need to have your credentials configured on your machine for Zarf to be able to fetch the resources.

System Requirements

  • For the default init package you will require an Internet connection to pull down the resources Zarf needs.

Prerequisites

Before beginning this tutorial you will need the following:

Building the init-package

Creating the Zarf ‘init’ package is as simple as creating any other package. Start with a directory for your package definition and check your Zarf version:

Terminal window
$ mkdir custom-init
$ cd custom-init
$ zarf version
vX.X.X

Save the following as zarf.yaml, replacing each <version> with your Zarf release, including the leading v. The components are published under ghcr.io/zarf-dev/components/init and include the resources and default values needed to initialize a cluster.

apiVersion: zarf.dev/v1beta1
kind: ZarfInitConfig
metadata:
name: init
preventNamespaceOverride: true
components:
- name: k3s
optional: true
import:
remote:
- url: oci://ghcr.io/zarf-dev/components/init/k3s:<version>
- name: zarf-injector
import:
remote:
- url: oci://ghcr.io/zarf-dev/components/init/zarf-injector:<version>
- name: zarf-seed-registry
import:
remote:
- url: oci://ghcr.io/zarf-dev/components/init/zarf-seed-registry:<version>
- name: zarf-registry
import:
remote:
- url: oci://ghcr.io/zarf-dev/components/init/zarf-registry:<version>
- name: zarf-agent
import:
remote:
- url: oci://ghcr.io/zarf-dev/components/init/zarf-agent:<version>
- name: git-server
optional: true
import:
remote:
- url: oci://ghcr.io/zarf-dev/components/init/git-server:<version>

Run the command to create the package:

Terminal window
zarf package create .

After you confirm package creation, Zarf will create the Zarf ‘init’ package in the current directory. In this case, the package name should look something like zarf-init-ARCH-vX.X.X.tar.zst.

Customizing the ‘init’ Package

The above will simply build the init package as it is defined for your version of Zarf. To build something custom you will need to make some modifications.

The Zarf ‘init’ Package is a composed Zarf Package that imports published components. Customize the zarf.yaml file you created above to override their images or change which components are included.

Swapping Images

You can replace images from imported components by adding images entries with matching id fields. The name field supplies the replacement image reference. This allows you to swap these images for hardened or enterprise-vetted versions like those from Iron Bank.

Keep the existing import sections and add the following images entries under the corresponding components in zarf.yaml, replacing the example image references with your own:

components:
- name: zarf-seed-registry
# Keep the existing import section.
images:
- id: registry
name: custom.enterprise.corp/opensource/registry:3.1.1
- id: proxy
name: custom.enterprise.corp/alpine/socat:1.8.0.3
- name: zarf-registry
# Keep the existing import section.
images:
- id: registry
name: custom.enterprise.corp/opensource/registry:3.1.1
- id: proxy
name: custom.enterprise.corp/alpine/socat:1.8.0.3
- name: zarf-agent
# Keep the existing import section.
images:
- id: agent
name: custom.enterprise.corp/opensource/zarf:vX.X.X
source: registry
- name: git-server
# Keep the existing import section and optional: true.
images:
- id: git-server
name: custom.enterprise.corp/opensource/gitea:1.27.3-rootless

Use the same registry and proxy image overrides in both zarf-seed-registry and zarf-registry. The component templates use the image IDs to configure their charts with the replacement references.

The Gitea image still needs to implement the Gitea configuration of a rootless image, although its tag does not need to end in -rootless.

Removing Components

You may not need or want all of the components in your ‘init’ package and may choose to slim down your package by removing them. Because the Zarf Package is composed, remove the corresponding entry from components in zarf.yaml and rebuild the package.

For example, remove k3s if you already have a Kubernetes cluster, or git-server if you do not need an in-cluster Git server. If you use an external registry, you can remove zarf-injector, zarf-seed-registry, and zarf-registry; supply the external registry details with the --registry-* flags when running zarf init.