Skip to content

Commit 517bbd1

Browse files
committed
feat(tutorial): initial solution
Signed-off-by: Brandt Keller <brandt.keller@defenseunicorns.com>
1 parent a8420cd commit 517bbd1

6 files changed

Lines changed: 301 additions & 2 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.tar.zst

01-create-zarf-package/README.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Part 1: Create a Zarf Package
2+
3+
Zarf packages all the contents of your application into a single OCI artifact that can be deployed into an airgapped environment. In this part, you'll create a Zarf package for [ArgoCD](https://argo-cd.readthedocs.io/) from scratch.
4+
5+
Create a working directory and navigate into it:
6+
7+
```bash
8+
mkdir zarf-package && cd zarf-package
9+
```
10+
11+
## Step 1: Create the Package Definition
12+
13+
The most important piece of a Zarf package is the `zarf.yaml` file. It follows the [Zarf package schema](https://github.com/zarf-dev/zarf/blob/main/zarf.schema.json) and defines both the package metadata and the components to deploy.
14+
15+
Create a `zarf.yaml` file with the following content:
16+
17+
```yaml
18+
kind: ZarfPackageConfig # ZarfPackageConfig is the package kind for most normal zarf packages
19+
metadata:
20+
name: argocd # specifies the name of our package; should be unique and stable across updates
21+
version: 9.4.4 # (optional) a version to track as you release updates or publish to a registry
22+
description: | # (optional) a human-readable description of the package
23+
"A Zarf Package that deploys the ArgoCD platform"
24+
```
25+
26+
## Step 2: Add the ArgoCD Component
27+
28+
In a Zarf package, **components** are the units that define an application stack. They can include Kubernetes manifests, configuration files, Helm charts, and more. Components are defined under the `components` key in `zarf.yaml`.
29+
30+
For more details, see [Understanding Zarf Components](https://docs.zarf.dev/ref/components/).
31+
32+
Add the following to the bottom of your `zarf.yaml`:
33+
34+
```yaml
35+
components:
36+
- name: argocd # specifies the name of our component; should be unique and stable across updates
37+
description: | # (optional) a human-readable description of the component
38+
"Deploys the ArgoCD packaged chart into the cluster"
39+
required: true # ensures this component is always deployed
40+
charts:
41+
- name: argo-cd
42+
version: 9.4.4
43+
namespace: argocd
44+
url: https://argoproj.github.io/argo-helm
45+
releaseName: argocd-baseline
46+
valuesFiles:
47+
- baseline-values.yaml
48+
```
49+
50+
The `url` field points directly to the upstream ArgoCD Helm repository — the same source you'd use with `helm repo add`. When you build the package, Zarf fetches the chart from that URL and bundles it into the tarball, so the airgapped environment gets an unmodified copy of the upstream chart. Local chart directories are also supported if you need to package a custom or vendored chart.
51+
52+
## Step 3: Create the Values File
53+
54+
The `valuesFiles` entry above references a `baseline-values.yaml` file. Create it in the same directory with the following content:
55+
56+
```yaml
57+
redis-ha:
58+
enabled: false
59+
60+
dex:
61+
enabled: false
62+
63+
notifications:
64+
enabled: false
65+
66+
redis:
67+
image:
68+
repository: docker.io/library/redis
69+
```
70+
71+
> [!NOTE]
72+
> These values are needed at package creation time because the `zarf dev find-images` command (used in the next step) templates the Helm chart to discover required images. Providing values now ensures that templating succeeds.
73+
74+
## Step 4: Find the Images
75+
76+
Zarf packages all required container images alongside your application so they're available in a disconnected environment. The `zarf dev find-images` command templates your Helm chart and identifies every image that will be needed.
77+
78+
Run this in your `zarf-package` directory:
79+
80+
```bash
81+
zarf dev find-images
82+
```
83+
84+
You should see output similar to:
85+
86+
```yaml
87+
components:
88+
- name: argocd
89+
images:
90+
- docker.io/library/redis:8.2.3-alpine
91+
- quay.io/argoproj/argocd:v3.3.2
92+
# Cosign artifacts for images - argocd
93+
- quay.io/argoproj/argocd:sha256-5882f28f7aaeaac397949c4511fdc1ad66c1260af44166ccf7e57aca3d7b9797.att
94+
```
95+
96+
Copy the full `images` list from your output into the `argocd` component in your `zarf.yaml`, replacing the two images you added in Step 2.
97+
98+
## Step 5: Set Up a Zarf Connect Service
99+
100+
Zarf Connect Services let you quickly connect to a deployed application by watching for specific Kubernetes service labels and annotations. After deployment, Zarf surfaces any discovered connect endpoints.
101+
102+
Add the following to your `baseline-values.yaml` file:
103+
104+
```yaml
105+
server:
106+
service:
107+
labels:
108+
zarf.dev/connect-name: argocd
109+
annotations:
110+
zarf.dev/connect-description: "The Argocd UI service"
111+
```
112+
113+
This adds a label/annotation to the argocd server service which zarf can discover once deployed to the cluster.
114+
115+
## Step 6: Build the Package
116+
117+
With your `zarf.yaml` and `baseline-values.yaml` in place, build the package:
118+
119+
```bash
120+
zarf package create .
121+
```
122+
123+
Zarf will pull down all referenced resources and bundle them into a package tarball. When it completes, list the directory to confirm:
124+
125+
```bash
126+
ls
127+
```
128+
129+
You should see a file named something like `zarf-package-argocd-amd64-9.4.4.tar.zst` (the architecture segment will match your system). Zarf also embeds a Software Bill of Materials (SBOM) into each package automatically.
130+
131+
---
132+
133+
## Reference Solution
134+
135+
If you get stuck, a complete working solution is available in the [`solution/`](./solution/) directory.
136+
137+
---
138+
139+
**Next:** [Part 2: Deploy a Zarf Package](../02-deploy-zarf-package/README.md)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
redis-ha:
2+
enabled: false
3+
4+
dex:
5+
enabled: false
6+
7+
notifications:
8+
enabled: false
9+
10+
redis:
11+
image:
12+
repository: docker.io/library/redis
13+
14+
server:
15+
service:
16+
labels:
17+
zarf.dev/connect-name: argocd
18+
annotations:
19+
zarf.dev/connect-description: "The Argocd UI service"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
kind: ZarfPackageConfig # ZarfPackageConfig is the package kind for most normal zarf packages
2+
metadata:
3+
name: argocd # specifies the name of our package; should be unique and stable across updates
4+
version: 9.4.4 # (optional) a version to track as you release updates or publish to a registry
5+
description: | # (optional) a human-readable description of the package
6+
"A Zarf Package that deploys the ArgoCD platform"
7+
8+
components:
9+
- name: argocd # specifies the name of our component; should be unique and stable across updates
10+
description: | # (optional) a human-readable description of the component
11+
"Deploys the ArgoCD packaged chart into the cluster"
12+
required: true # ensures this component is always deployed
13+
charts:
14+
- name: argo-cd
15+
version: 9.4.4
16+
namespace: argocd
17+
url: https://argoproj.github.io/argo-helm
18+
releaseName: argocd-baseline
19+
valuesFiles:
20+
- baseline-values.yaml
21+
images:
22+
- docker.io/library/redis:8.2.3-alpine
23+
- quay.io/argoproj/argocd:v3.3.2
24+
# Cosign artifacts for images - argocd
25+
- quay.io/argoproj/argocd:sha256-5882f28f7aaeaac397949c4511fdc1ad66c1260af44166ccf7e57aca3d7b9797.att

02-deploy-zarf-package/README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Part 2: Deploy a Zarf Package
2+
3+
In Part 1, you built a Zarf package for ArgoCD. In this part, you'll deploy that package to your local Kubernetes cluster and access the ArgoCD dashboard.
4+
5+
Make sure you're in the same `zarf-package` directory you used in Part 1.
6+
7+
## Step 1: Inspect the Environment
8+
9+
Confirm the package tarball from Part 1 is present:
10+
11+
```bash
12+
ls
13+
```
14+
15+
You should see a file like `zarf-package-argocd-amd64-9.4.4.tar.zst`. The architecture may be different depending on your local machine.
16+
17+
Also verify your cluster is reachable:
18+
19+
```bash
20+
zarf tools kubectl cluster-info
21+
```
22+
23+
## Step 2: Deploy the Package
24+
25+
Run the deploy command:
26+
27+
```bash
28+
zarf package deploy zarf-package-argocd-amd64-9.4.4.tar.zst
29+
```
30+
31+
Zarf will prompt you to select the package (if multiple are present) and confirm each component before deploying. Accept the defaults to proceed.
32+
33+
Once deployment completes, verify the ArgoCD resources are running:
34+
35+
```bash
36+
zarf tools kubectl get all -n argocd
37+
```
38+
39+
You should see the pods, services, deployments, and replica sets that make up the ArgoCD Helm chart.
40+
41+
## Step 3: Retrieve the ArgoCD admin password
42+
43+
Before we access the ArgoCD Dashboard, we need to retrieve the automatically generated admin password:
44+
45+
```bash
46+
zarf tools kubectl -n argocd get secret argocd-initial-admin-secret \
47+
-o jsonpath="{.data.password}" | base64 -d; echo
48+
```
49+
50+
## Step 4: Access the ArgoCD Dashboard
51+
52+
> [!NOTE]
53+
> If you completed the Zarf Connect Service section in Part 1, you can use `zarf connect argocd` as a shorthand for the port-forward command below.
54+
55+
Zarf is designed for environments with limited connectivity, so the ArgoCD service isn't exposed externally by default. Use `kubectl` to set up a port forward:
56+
57+
```bash
58+
zarf tools kubectl port-forward -n argocd service/argocd-server 42000:80
59+
```
60+
61+
Then open your browser to [http://localhost:42000](http://localhost:42000).
62+
63+
64+
## Conclusion
65+
66+
You've built and deployed a complete Zarf package end-to-end. From here, Zarf has a lot more to offer for air-gapped software delivery:
67+
68+
- Browse the [Zarf examples](https://github.com/zarf-dev/zarf/tree/main/examples) for more complex package configurations
69+
- Read the [Zarf documentation](https://docs.zarf.dev) for the full feature set
70+
71+
---
72+
73+
**Back:** [Part 1: Create a Zarf Package](../01-create-zarf-package/README.md)

README.md

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,44 @@
1-
# tutorial
2-
tutorial repository isolating package create and deploy
1+
# Intro to Zarf
2+
3+
[Zarf](https://zarf.dev) is an open source tool for packaging and deploying software into air-gapped Kubernetes environments. It bundles everything your application needs — Helm charts, container images, manifests — into a single portable artifact that can be deployed without internet access.
4+
5+
In this tutorial, you'll build a Zarf package for [ArgoCD](https://argo-cd.readthedocs.io/) from scratch, deploy it to a local Kubernetes cluster, and access the ArgoCD dashboard.
6+
7+
## What You'll Learn
8+
9+
- How a `zarf.yaml` package definition is structured
10+
- How to use `zarf dev find-images` to discover required container images
11+
- How to build a Zarf package tarball
12+
- How to deploy a Zarf package to a Kubernetes cluster
13+
14+
## Prerequisites
15+
16+
- [Zarf installed](https://docs.zarf.dev/getting-started/install/) and on your `PATH`
17+
- A Kubernetes cluster with `kubectl` configured to reach it
18+
- [Helm](https://helm.sh/docs/intro/install/) installed
19+
20+
### Kubernetes Options
21+
22+
Any local cluster will work. Some common choices:
23+
24+
| Option | Notes |
25+
|--------|-------|
26+
| [k3d](https://k3d.io) | K3s in Docker — closest to the Instruqt lab environment |
27+
| [kind](https://kind.sigs.k8s.io) | Well-documented, widely used in OSS tutorials |
28+
| [Docker Desktop](https://docs.docker.com/desktop/kubernetes/) | Enable Kubernetes in settings |
29+
| Existing cluster | Works as long as `kubectl` is configured |
30+
31+
Whichever you choose, verify your cluster is reachable before starting:
32+
33+
```bash
34+
kubectl cluster-info
35+
```
36+
37+
## Tutorial Structure
38+
39+
| Part | Description |
40+
|------|-------------|
41+
| [Part 1: Create a Zarf Package](./01-create-zarf-package/README.md) | Author a `zarf.yaml`, discover images, and build the package tarball |
42+
| [Part 2: Deploy a Zarf Package](./02-deploy-zarf-package/README.md) | Deploy the package to your cluster and access ArgoCD |
43+
44+
Work through the parts in order — Part 2 depends on the package tarball produced in Part 1.

0 commit comments

Comments
 (0)