Build an Air Gap Mattermost Deployment Package with Zarf
Introduction
In secure and disconnected environments, the open-source project Mattermost is an excellent collaboration technology that allows technical teams to seamlessly collaborate on distributed teams. The features in Mattermost parallel competing connected Software as a Service (SaaS) offerings like Slack and Microsoft Teams.
In this blog, you will learn step-by-step how to Package and Deploy a running Mattermost instance with Zarf. This is not a deep dive into long-term air gap planning with Mattermost, but an introduction and a getting started with components required to run Mattermost in an air-gapped environment.
This blog has a companion video you can follow along with on YouTube.
Install the Zarf Binary
- Use the Zarf Installation Instructions to install the Zarf binary onto your machine.
- You can check the version with the
zarf version
command.
doug in ~/src/github.com/defenseunicorns 🦄 zarf version
v0.24.2
Clone the Zarf Repository
We’ll be using the Zarf examples in the source code for some of the components to set up Mattermost.
- Navigate to https://github.com/defenseunicorns/zarf
- Press the < > Code button
- Copy the HTTPS url.
- Open your favorite terminal and use git to clone the repository.
doug in ~ 🦄
doug in ~ 🦄 mkdir -p src/github.com/defenseunicorns
doug in ~ 🦄 cd src/github.com/defenseunicorns
doug in ~/src/github.com/defenseunicorns 🦄 git clone https://github.com/defenseunicorns/zarf.git
Cloning into 'zarf'...
remote: Enumerating objects: 15495, done.
remote: Counting objects: 100% (1594/1594), done.
remote: Compressing objects: 100% (626/626), done.
remote: Total 15495 (delta 1092), reused 1395 (delta 944), pack-reused 13901
Receiving objects: 100% (15495/15495), 37.56 MiB | 14.04 MiB/s, done.
Resolving deltas: 100% (10123/10123), done.
Initialize Zarf
You’ll need a Kubernetes cluster. Installing a container runtime like Docker and setting up a Kubernetes cluster is beyond the scope of this tutorial. But I’ll quickly show you how to create a cluster with K3d.
- Use the instructions for your OS to install k3d.
- Create a Kubernetes cluster with k3d.
doug in ~/src/github.com/defenseunicorns 🦄 k3d cluster create mattermost-example
INFO[0000] Prep: Network
INFO[0000] Created network 'k3d-mattermost-example'
INFO[0000] Created image volume k3d-mattermost-example-images
INFO[0000] Starting new tools node...
INFO[0000] Starting Node 'k3d-mattermost-example-tools'
INFO[0001] Creating node 'k3d-mattermost-example-server-0'
INFO[0001] Creating LoadBalancer 'k3d-mattermost-example-serverlb'
INFO[0001] Using the k3d-tools node to gather environment information
INFO[0001] Starting new tools node...
INFO[0001] Starting Node 'k3d-mattermost-example-tools'
INFO[0002] Starting cluster 'mattermost-example'
INFO[0002] Starting servers...
INFO[0002] Starting Node 'k3d-mattermost-example-server-0'
INFO[0006] All agents already running.
INFO[0006] Starting helpers...
INFO[0006] Starting Node 'k3d-mattermost-example-serverlb'
INFO[0012] Injecting records for hostAliases (incl. host.k3d.internal) and for 3 network members into CoreDNS configmap...
INFO[0015] Cluster 'mattermost-example' created successfully!
INFO[0015] You can now use it like this:
kubectl cluster-info
- Note: If you get this error, make sure Docker is running.
doug in ~/src/github.com/defenseunicorns 🦄 k3d cluster create
ERRO[0000] Failed to get nodes for cluster 'k3s-default': docker failed to get containers with labels 'map[k3d.cluster:k3s-default]': failed to list containers: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
INFO[0000] Prep: Network
ERRO[0000] Failed Cluster Preparation: Failed Network Preparation: failed to create cluster network: failed to check for duplicate docker networks: docker failed to list networks: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
ERRO[0000] Failed to create cluster >>> Rolling Back
INFO[0000] Deleting cluster 'k3s-default'
ERRO[0000] Failed to get nodes for cluster 'k3s-default': docker failed to get containers with labels 'map[k3d.cluster:k3s-default]': failed to list containers: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
ERRO[0000] failed to get cluster: No nodes found for given cluster
FATA[0000] Cluster creation FAILED, also FAILED to rollback changes!
Initialize Zarf
You now have a Kubernetes cluster. You’re going to initialize Zarf with the zarf init
command. It will look different depending on your operating system. Feel free to reject or take optional components. It’s not important to our work today.
doug in ~/src/github.com/defenseunicorns 🦄 zarf init
Saving log file to
/var/folders/bk/rz1xx2sd5zn134c0_j1s2n5r0000gp/T/zarf-2023-02-23-11-39-26-2360079011.log
*,
*(((&&&&&/*.
*(((((%&&&&&&&*,
*(((((((&&&&&&&&&* ,,*****,. **%&&&&&((((((
*(((((((((&&&&&&&@* **@@@@@@&&&&&&&&&&@@@@@** */&&&&&&((((((((((
*((((((///(&&&&&&@@@@&&&&@@@@@@@@@&&&&&&&&&&&&&&@/* *%&&&&&&/////((((((*
*(((///////&&&&&&&&&&&&&@@@@@@@@@&&&&&&&&&&&&&&&&&(%&&&/**///////(/*
*/&&&&&&&&&&&&&&&&*/***&%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/*******///*
*&%&&&&&&&&&&&&&&&&&&&&&&&***&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&****/&&&&&&&&&&&&(/*
*/((((((((((((((///////******%%&&&&&&&&//&@@*&&&&&&&&&&&&&&&&&&&#%&&&&*/####(/////((((/.
*/((((((((((///////******%%%%%%%%%(##@@@//%&%%%%%%%&%&%%&&/(@@(/&&(***///////(((*
***(((((/////********%%%%%%%/&%***/((%%%%%%%%%%%%%%%%(#&@*%/%%***/////**
*&&%%%%%%//*******%%%%%%%%@@****%%/%%%%%%%%%%%%%%%%%%***@@%%**(%%%&&*
*&&%%%%%(////******/(%%%%%%%@@@**@@&%%%%%%%%%%%%%%%%%(@@*%@@%%*****////%&*
*&%%%%%#////////***/////%%%%%%*@@@@@/%%%%%%%%%%%%%%%%%%%%@@@@%%*****///////((*
*%%%%((((///////* *////(%%%%%%##%%%%%%%%%%%(%%%%*%%%%%%%%%%%*
*(((((((/*** */////#%%%%%%%%%%#%%%%%%%%%%%%%%%%%%%%#*
%%( ,*///((%%%%%%%%(**/#%%%##**/%%%%%*
%%%&&&& *///*/(((((########//######**
%&&&&&* *#######(((((((//////((((*
###%##############(((#####*
%@&& *&#(%######*#########(#####/
/&&* .. ,&#(/%####(*#########/#####/ #%@%&&&
** && ./%##((*&####/(#######(#####*(* %&&&&&&
*@%%@* *&#####((((####*(#####(*###(*(##* , %@&
*@%%%%* *%######((((*%####/*((*%####/*(###* *
*@%%%%%%* *##* **#(###((((///#*#*(((((/#**#((*(##**#,*/##*, %@&&
*@%%%*%%%* ****,*##/*#*##(((((((/(((((((((/(((*(((((###########*, #&&#
*@%%%*(%%%/* **######(#((..((((((((((((((((((* ,*(#####(((((*,
*@%%%#(*%%%%* ,**/####(* */(((((((((((((((((* ,**,
*@%%%*(/(%%%%/* ******(((((((((((*(((((*
*@%%%#(((*/%%%%%%##%%*((((((((((((**((((*
*@%%%%*(((((((((((((((((((((((*/%*((*. (&&&(
,*%%%%%%*((((((((((((((((**%%%**, (&
*%%%%%%%%%(/*****(#%%%%%** &%
,**%%%%%%%%%%%%%***
,((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((,
.....(((((((/////////////////((((((((.....
/////////////// /////// ***************** ***************,
////. /// //// */// *** ****
////, /// //// *///////////////. /////**/******
///// ////////////// */// */// ///*
./////////////// //// /// */// //// ///*
It seems the init package could not be found locally, but can be downloaded from
https://github.com/defenseunicorns/zarf/releases/download/v0.24.2/zarf-init-arm64-v0.24.2.tar.zst
Note: This will require an internet connection.
? Do you want to download this init package? Yes
✔ Downloading https://github.com/defenseunicorns/zarf/releases/download/v0.24.2/zarf-init-arm64-v0.24.2.tar.zst
✔ Loading Zarf Package /Users/jason/.zarf-cache/zarf-init-arm64-v0.24.2.tar.zst
kind: ZarfInitConfig
metadata:
name: init
description: Used to establish a new Zarf cluster
architecture: arm64
build:
terminal: fv-az363-679
user: runner
architecture: arm64
timestamp: Tue, 14 Feb 2023 02:03:31 +0000
version: v0.24.2
migrations:
- scripts-to-actions
components:
- name: zarf-injector
description: |
Bootstraps a Kubernetes cluster by cloning a running pod in the cluster and hosting the registry image.
Removed and destroyed after the Zarf Registry is self-hosting the registry image.
required: true
cosignKeyPath: cosign.pub
files:
- source: sget://defenseunicorns/zarf-injector:arm64-2023-02-09
target: "###ZARF_TEMP###/zarf-injector"
executable: true
- name: zarf-seed-registry
description: |
Deploys the Zarf Registry using the registry image provided by the Zarf Injector.
required: true
charts:
- name: docker-registry
releaseName: zarf-docker-registry
version: 1.0.0
namespace: zarf
valuesFiles:
- packages/zarf-registry/registry-values.yaml
- packages/zarf-registry/registry-values-seed.yaml
localPath: packages/zarf-registry/chart
- name: zarf-registry
description: |
Updates the Zarf Registry to use the self-hosted registry image.
Serves as the primary docker registry for the cluster.
required: true
charts:
- name: docker-registry
releaseName: zarf-docker-registry
version: 1.0.0
namespace: zarf
valuesFiles:
- packages/zarf-registry/registry-values.yaml
localPath: packages/zarf-registry/chart
manifests:
- name: registry-connect
namespace: zarf
files:
- packages/zarf-registry/connect.yaml
- name: kep-1755-registry-annotation
namespace: zarf
files:
- packages/zarf-registry/configmap.yaml
images:
- registry:2.8.1
- name: zarf-agent
description: |
A Kubernetes mutating webhook to enable automated URL rewriting for container
images and git repository references in Kubernetes manifests. This prevents
the need to manually update URLs from their original sources to the Zarf-managed
docker registry and git server.
required: true
actions:
onCreate:
before:
- cmd: make init-package-local-agent AGENT_IMAGE="agent:v0.24.2"
manifests:
- name: zarf-agent
namespace: zarf
files:
- packages/zarf-agent/manifests/service.yaml
- packages/zarf-agent/manifests/secret.yaml
- packages/zarf-agent/manifests/deployment.yaml
- packages/zarf-agent/manifests/webhook.yaml
images:
- ghcr.io/defenseunicorns/zarf/agent:v0.24.2
- name: logging
description: |
Deploys the Promtail Grafana & Loki (PGL) stack.
Aggregates logs from different containers and presents them in a web dashboard.
Recommended if no other logging stack is deployed in the cluster.
charts:
- name: loki-stack
releaseName: zarf-loki-stack
url: https://grafana.github.io/helm-charts
version: 2.8.9
namespace: zarf
valuesFiles:
- packages/logging-pgl/pgl-values.yaml
manifests:
- name: logging-connect
namespace: zarf
files:
- packages/logging-pgl/connect.yaml
images:
- docker.io/grafana/promtail:2.7.0
- grafana/grafana:8.3.5
- grafana/loki:2.6.1
- quay.io/kiwigrid/k8s-sidecar:1.19.2
- name: git-server
description: |
Deploys Gitea to provide git repositories for Kubernetes configurations.
Required for GitOps deployments if no other git server is available.
actions:
onDeploy:
after:
- maxTotalSeconds: 60
maxRetries: 3
cmd: ./zarf internal create-read-only-gitea-user
charts:
- name: gitea
releaseName: zarf-gitea
url: https://dl.gitea.io/charts
version: 7.0.2
namespace: zarf
valuesFiles:
- packages/gitea/gitea-values.yaml
manifests:
- name: git-connect
namespace: zarf
files:
- packages/gitea/connect.yaml
images:
- gitea/gitea:1.18.3
variables:
- name: K3S_ARGS
description: Arguments to pass to K3s
default: --disable traefik
- name: REGISTRY_EXISTING_PVC
description: "Optional: Use an existing PVC for the registry instead of creating a new one. If this is set, the REGISTRY_PVC_SIZE variable will be ignored."
- name: REGISTRY_PVC_SIZE
description: The size of the persistent volume claim for the registry
default: 20Gi
- name: REGISTRY_CPU_REQ
description: The CPU request for the registry
default: 100m
- name: REGISTRY_MEM_REQ
description: The memory request for the registry
default: 256Mi
- name: REGISTRY_CPU_LIMIT
description: The CPU limit for the registry
default: "3"
- name: REGISTRY_MEM_LIMIT
description: The memory limit for the registry
default: 2Gi
- name: REGISTRY_HPA_MIN
description: The minimum number of registry replicas
default: "1"
- name: REGISTRY_HPA_MAX
description: The maximum number of registry replicas
default: "5"
- name: REGISTRY_HPA_ENABLE
description: Enable the Horizontal Pod Autoscaler for the registry
default: "true"
- name: GIT_SERVER_EXISTING_PVC
description: "Optional: Use an existing PVC for the git server instead of creating a new one. If this is set, the GIT_SERVER_PVC_SIZE variable will be ignored."
- name: GIT_SERVER_PVC_SIZE
description: The size of the persistent volume claim for git server
default: 10Gi
- name: GIT_SERVER_CPU_REQ
description: The CPU request for git server
default: 200m
- name: GIT_SERVER_MEM_REQ
description: The memory request for git server
default: 512Mi
- name: GIT_SERVER_CPU_LIMIT
description: The CPU limit for git server
default: "3"
- name: GIT_SERVER_MEM_LIMIT
description: The memory limit for git server
default: 2Gi
constants:
- name: AGENT_IMAGE
value: agent:v0.24.2
This package has 9 artifacts with software bill-of-materials (SBOM) included. You can view them now
in the zarf-sbom folder in this directory or to go directly to one, open this in your browser:
/Users/jason/src/github.com/defenseunicorns/zarf-sbom/sbom-viewer-docker.io_grafana_promtail_2.7.0.html
* This directory will be removed after package deployment.
? Deploy this Zarf package? Yes
───────────────────────────────────────────────────────────────────────────────────────
name: logging
charts:
- name: loki-stack
releaseName: zarf-loki-stack
url: https://grafana.github.io/helm-charts
version: 2.8.9
namespace: zarf
valuesFiles:
- packages/logging-pgl/pgl-values.yaml
manifests:
- name: logging-connect
namespace: zarf
files:
- packages/logging-pgl/connect.yaml
images:
- docker.io/grafana/promtail:2.7.0
- grafana/grafana:8.3.5
- grafana/loki:2.6.1
- quay.io/kiwigrid/k8s-sidecar:1.19.2
Deploys the Promtail Grafana & Loki (PGL) stack. Aggregates logs from different containers and
presents them in a web dashboard. Recommended if no other logging stack is deployed in the cluster.
? Deploy the logging component? No
───────────────────────────────────────────────────────────────────────────────────────
name: git-server
actions:
onDeploy:
after:
- maxTotalSeconds: 60
maxRetries: 3
cmd: ./zarf internal create-read-only-gitea-user
charts:
- name: gitea
releaseName: zarf-gitea
url: https://dl.gitea.io/charts
version: 7.0.2
namespace: zarf
valuesFiles:
- packages/gitea/gitea-values.yaml
manifests:
- name: git-connect
namespace: zarf
files:
- packages/gitea/connect.yaml
images:
- gitea/gitea:1.18.3
Deploys Gitea to provide git repositories for Kubernetes configurations. Required for GitOps
deployments if no other git server is available.
? Deploy the git-server component? No
📦 ZARF-INJECTOR COMPONENT
✔ Copying 1 files
✔ Gathering cluster information
⠋ Attempting to bootstrap with the [k3d-mattermost-example-server-0]/rancher/mirrored-library-tr ⠙ Attempting to bootstrap with the [k3d-mattermost-example-server-0]/rancher/mirrored-library-tr ⠹ Attempting to bootstrap with the [k3d-mattermost-example-server-0]/rancher/mirrored-library-tr ⠸ Attempting to bootstrap with the [k3d-mattermost-example-server-0]/rancher/mirrored-library-tr ⠼ Attempting to bootstrap with the [k3d-mattermost-example-server-0]/rancher/mirrored-library-tr ⠴ Attempting to bootstrap with the [k3d-mattermost-example-server-0]/rancher/mirrored-library-tr ✔ Attempting to bootstrap the seed image into the cluster
📦 ZARF-SEED-REGISTRY COMPONENT
✔ Loading the Zarf State from the Kubernetes cluster
✔ Processing helm chart docker-registry:1.0.0 from Zarf-generated helm chart
📦 ZARF-REGISTRY COMPONENT
✔ Creating port forwarding tunnel at http://127.0.0.1:61003/v2/_catalog
✔ Storing images in the zarf registry
✔ Processing helm chart docker-registry:1.0.0 from Zarf-generated helm chart
✔ Starting helm chart generation registry-connect
⠋ Processing helm chart raw-init-zarf-registry-registry-connect:0.1.1677170366 from Zarf-generat ✔ Processing helm chart raw-init-zarf-registry-registry-connect:0.1.1677170366 from Zarf-generated helm chart
✔ Starting helm chart generation kep-1755-registry-annotation
⠋ Processing helm chart raw-init-zarf-registry-kep-1755-registry-annotation:0.1.1677170366 from ✔ Processing helm chart raw-init-zarf-registry-kep-1755-registry-annotation:0.1.1677170366 from Zarf-generated helm chart
📦 ZARF-AGENT COMPONENT
✔ Creating port forwarding tunnel at http://127.0.0.1:61015/v2/_catalog
✔ Storing images in the zarf registry
✔ Starting helm chart generation zarf-agent
⠋ Processing helm chart raw-init-zarf-agent-zarf-agent:0.1.1677170366 from Zarf-generated helm c ✔ Processing helm chart raw-init-zarf-agent-zarf-agent:0.1.1677170366 from Zarf-generated helm chart
✔ Zarf deployment complete
Application | Username | Password | Connect
Registry | zarf-push | QFFiAMQ4GBW6BJ01fc4czE2W | zarf connect registry
doug in ~/src/github.com/defenseunicorns 🦄
Configure PostgreSQL Database
- Navigate to the postgres-operator example.
doug in ~/src/github.com/defenseunicorns 🦄 cd zarf/examples/postgres-operator
doug in ~/src/github.com/defenseunicorns/zarf/examples/postgres-operator on main 🦄
- Create postgres-operator package using the
zarf package create
command.
doug in ~/src/github.com/defenseunicorns/zarf/examples/postgres-operator on main 🦄 zarf package cr
eate .
Saving log file to
/var/folders/bk/rz1xx2sd5zn134c0_j1s2n5r0000gp/T/zarf-2023-02-23-11-45-50-1378292225.log
Using build directory .
kind: ZarfPackageConfig
metadata:
name: postgres-operator-demo
description: Demo of prod-like Postgres database(s) on an edge cluster
architecture: arm64
build:
terminal: JvBUnicornMBP5
user: jason
architecture: arm64
timestamp: Thu, 23 Feb 2023 11:45:50 -0500
version: v0.24.2
migrations:
- scripts-to-actions
components:
- name: postgres-operator
required: true
charts:
- name: postgres-operator
url: https://opensource.zalando.com/postgres-operator/charts/postgres-operator
version: 1.8.2
namespace: postgres-operator
valuesFiles:
- postgres/operator-values.yaml
- name: postgres-operator-ui
url: https://opensource.zalando.com/postgres-operator/charts/postgres-operator-ui
version: 1.8.2
namespace: postgres-operator
valuesFiles:
- postgres/operator-ui-values.yaml
manifests:
- name: postgres-operator-zarf-connect
files:
- postgres/zarf-connect.yaml
images:
- registry.opensource.zalan.do/acid/postgres-operator-ui:v1.8.2
- registry.opensource.zalan.do/acid/postgres-operator:v1.8.2
- registry.opensource.zalan.do/acid/pgbouncer:master-22
- registry.opensource.zalan.do/acid/spilo-14:2.1-p6
- name: pgadmin
required: true
charts:
- name: pgadmin4
url: https://helm.runix.net
version: 1.11.0
namespace: postgres-operator
valuesFiles:
- pgadmin/values.yaml
manifests:
- name: pgadmin-zarf-connect
files:
- pgadmin/zarf-connect.yaml
images:
- docker.io/dpage/pgadmin4:6.10
- name: example-db
manifests:
- name: example-db
files:
- example-db/demo-cluster.yaml
variables:
- name: PGADMIN_PASSWORD
prompt: true
? Create this Zarf package? Yes
Specify a maximum file size for this package in Megabytes. Above this size, the package will be
split into multiple files. 0 will disable this feature.
? Please provide a value for "Maximum Package Size" 0
📦 POSTGRES-OPERATOR COMPONENT
⠋ Processing helm chart postgres-operator:1.8.2 from repo https://opensource.zalando.com/postgre ⠙ Processing helm chart postgres-operator:1.8.2 from repo https://opensource.zalando.com/postgre ✔ Processing helm chart postgres-operator:1.8.2 from repo https://opensource.zalando.com/postgres-operator/charts/postgres-operator
⠋ Processing helm chart postgres-operator-ui:1.8.2 from repo https://opensource.zalando.com/post ✔ Processing helm chart postgres-operator-ui:1.8.2 from repo https://opensource.zalando.com/postgres-operator/charts/postgres-operator-ui
✔ Loading 1 K8s manifests
📦 PGADMIN COMPONENT
✔ Processing helm chart pgadmin4:1.11.0 from repo https://helm.runix.net
✔ Loading 1 K8s manifests
📦 EXAMPLE-DB COMPONENT
✔ Loading 1 K8s manifests
📦 COMPONENT IMAGES
⠋ Fetching image metadata (1 of 5): registry.opensource.zalan.do/acid/postgres-operator-ui:v1.8. ⠙ Fetching image metadata (1 of 5): registry.opensource.zalan.do/acid/postgres-operator-ui:v1.8. ⠹ Fetching image metadata (1 of 5): registry.opensource.zalan.do/acid/postgres-operator-ui:v1.8. ⠸ Fetching image metadata (1 of 5): registry.opensource.zalan.do/acid/postgres-operator-ui:v1.8. ⠼ Fetching image metadata (1 of 5): registry.opensource.zalan.do/acid/postgres-operator-ui:v1.8. ⠴ Fetching image metadata (1 of 5): registry.opensource.zalan.do/acid/postgres-operator-ui:v1.8. ⠦ Fetching image metadata (1 of 5): registry.opensource.zalan.do/acid/postgres-operator-ui:v1.8. ⠧ Fetching image metadata (1 of 5): registry.opensource.zalan.do/acid/postgres-operator-ui:v1.8. ⠇ Fetching image metadata (2 of 5): registry.opensource.zalan.do/acid/postgres-operator:v1.8.2 ( ⠏ Fetching image metadata (2 of 5): registry.opensource.zalan.do/acid/postgres-operator:v1.8.2 ( ⠋ Fetching image metadata (2 of 5): registry.opensource.zalan.do/acid/postgres-operator:v1.8.2 ( ⠙ Fetching image metadata (2 of 5): registry.opensource.zalan.do/acid/postgres-operator:v1.8.2 ( ✔ Loading metadata for 5 images.
Pulling 5 images (272.55 MBs o^C659.41 MBs) ██████████ 41% | 1m3s
doug in ~/src/github.com/defenseunicorns/zarf/examples/postgres-operator on main 🦄
doug in ~/src/github.com/defenseunicorns/zarf/examples/postgres-operator on main 🦄
doug in ~/src/github.com/defenseunicorns/zarf/examples/postgres-operator on main 🦄
doug in ~/src/github.com/defenseunicorns/zarf/examples/postgres-operator on main 🦄 zarf package create .
Saving log file to
/var/folders/bk/rz1xx2sd5zn134c0_j1s2n5r0000gp/T/zarf-2023-02-23-11-47-08-100862483.log
Using build directory .
kind: ZarfPackageConfig
metadata:
name: postgres-operator-demo
description: Demo of prod-like Postgres database(s) on an edge cluster
architecture: arm64
build:
terminal: JvBUnicornMBP5
user: jason
architecture: arm64
timestamp: Thu, 23 Feb 2023 11:47:08 -0500
version: v0.24.2
migrations:
- scripts-to-actions
components:
- name: postgres-operator
required: true
charts:
- name: postgres-operator
url: https://opensource.zalando.com/postgres-operator/charts/postgres-operator
version: 1.8.2
namespace: postgres-operator
valuesFiles:
- postgres/operator-values.yaml
- name: postgres-operator-ui
url: https://opensource.zalando.com/postgres-operator/charts/postgres-operator-ui
version: 1.8.2
namespace: postgres-operator
valuesFiles:
- postgres/operator-ui-values.yaml
manifests:
- name: postgres-operator-zarf-connect
files:
- postgres/zarf-connect.yaml
images:
- registry.opensource.zalan.do/acid/postgres-operator-ui:v1.8.2
- registry.opensource.zalan.do/acid/postgres-operator:v1.8.2
- registry.opensource.zalan.do/acid/pgbouncer:master-22
- registry.opensource.zalan.do/acid/spilo-14:2.1-p6
- name: pgadmin
required: true
charts:
- name: pgadmin4
url: https://helm.runix.net
version: 1.11.0
namespace: postgres-operator
valuesFiles:
- pgadmin/values.yaml
manifests:
- name: pgadmin-zarf-connect
files:
- pgadmin/zarf-connect.yaml
images:
- docker.io/dpage/pgadmin4:6.10
- name: example-db
manifests:
- name: example-db
files:
- example-db/demo-cluster.yaml
variables:
- name: PGADMIN_PASSWORD
prompt: true
? Create this Zarf package? Yes
Specify a maximum file size for this package in Megabytes. Above this size, the package will be
split into multiple files. 0 will disable this feature.
? Please provide a value for "Maximum Package Size" 0
📦 POSTGRES-OPERATOR COMPONENT
✔ Processing helm chart postgres-operator:1.8.2 from repo https://opensource.zalando.com/postgres-operator/charts/postgres-operator
✔ Processing helm chart postgres-operator-ui:1.8.2 from repo https://opensource.zalando.com/postgres-operator/charts/postgres-operator-ui
✔ Loading 1 K8s manifests
📦 PGADMIN COMPONENT
✔ Processing helm chart pgadmin4:1.11.0 from repo https://helm.runix.net
✔ Loading 1 K8s manifests
📦 EXAMPLE-DB COMPONENT
✔ Loading 1 K8s manifests
📦 COMPONENT IMAGES
✔ Loading metadata for 5 images.
✔ Pulling 5 images (659.41 MBs)
✔ Creating SBOMs for 5 images and 0 components with files.
- Deploy the PostgreSQL operator with the
zarf package deploy
command. - You’ll be prompted to create a PGADMIN password, make note of this you’ll need it to create the PostgreSQL database.
- Also say “y”es to the prompted for the example database. We’ll use it for Mattermost.
doug in ~/src/github.com/defenseunicorns/zarf/examples/postgres-operator on main 🦄 zarf package deploy zarf-package-postgres-operator-demo-arm64.tar.zst
Saving log file to
/var/folders/bk/rz1xx2sd5zn134c0_j1s2n5r0000gp/T/zarf-2023-02-23-11-53-23-1686449327.log
✔ Loading Zarf Package zarf-package-postgres-operator-demo-arm64.tar.zst
kind: ZarfPackageConfig
metadata:
name: postgres-operator-demo
description: Demo of prod-like Postgres database(s) on an edge cluster
architecture: arm64
build:
terminal: JvBUnicornMBP5
user: jason
architecture: arm64
timestamp: Thu, 23 Feb 2023 11:47:08 -0500
version: v0.24.2
migrations:
- scripts-to-actions
components:
- name: postgres-operator
required: true
charts:
- name: postgres-operator
url: https://opensource.zalando.com/postgres-operator/charts/postgres-operator
version: 1.8.2
namespace: postgres-operator
valuesFiles:
- postgres/operator-values.yaml
- name: postgres-operator-ui
url: https://opensource.zalando.com/postgres-operator/charts/postgres-operator-ui
version: 1.8.2
namespace: postgres-operator
valuesFiles:
- postgres/operator-ui-values.yaml
manifests:
- name: postgres-operator-zarf-connect
files:
- postgres/zarf-connect.yaml
images:
- registry.opensource.zalan.do/acid/postgres-operator-ui:v1.8.2
- registry.opensource.zalan.do/acid/postgres-operator:v1.8.2
- registry.opensource.zalan.do/acid/pgbouncer:master-22
- registry.opensource.zalan.do/acid/spilo-14:2.1-p6
- name: pgadmin
required: true
charts:
- name: pgadmin4
url: https://helm.runix.net
version: 1.11.0
namespace: postgres-operator
valuesFiles:
- pgadmin/values.yaml
manifests:
- name: pgadmin-zarf-connect
files:
- pgadmin/zarf-connect.yaml
images:
- docker.io/dpage/pgadmin4:6.10
- name: example-db
manifests:
- name: example-db
files:
- example-db/demo-cluster.yaml
variables:
- name: PGADMIN_PASSWORD
prompt: true
This package has 5 artifacts with software bill-of-materials (SBOM) included. You can view them now
in the zarf-sbom folder in this directory or to go directly to one, open this in your browser:
/Users/jason/src/github.com/defenseunicorns/zarf/examples/postgres-operator/zarf-sbom/sbom-viewer-docker.io_dpage_pgadmin4_6.10.html
* This directory will be removed after package deployment.
? Deploy this Zarf package? Yes
? Please provide a value for "PGADMIN_PASSWORD" 12345
───────────────────────────────────────────────────────────────────────────────────────
name: example-db
manifests:
- name: example-db
files:
? Deploy the example-db component? Yes
📦 POSTGRES-OPERATOR COMPONENT
✔ Loading the Zarf State from the Kubernetes cluster
✔ Creating port forwarding tunnel at http://127.0.0.1:61192/v2/_catalog
✔ Storing images in the zarf registry
✔ Processing helm chart postgres-operator:1.8.2 from https://opensource.zalando.com/postgres-operator/charts/postgres-operator
✔ Processing helm chart postgres-operator-ui:1.8.2 from https://opensource.zalando.com/postgres-operator/charts/postgres-operator-ui
✔ Starting helm chart generation postgres-operator-zarf-connect
✔ Processing helm chart raw-postgres-operator-demo-postgres-operator-postgres-operator-zarf-connect:0.1.1677171203 from Zarf-generated helm chart
📦 PGADMIN COMPONENT
✔ Creating port forwarding tunnel at http://127.0.0.1:61239/v2/_catalog
✔ Storing images in the zarf registry
✔ Processing helm chart pgadmin4:1.11.0 from https://helm.runix.net
✔ Starting helm chart generation pgadmin-zarf-connect
✔ Processing helm chart raw-postgres-operator-demo-pgadmin-pgadmin-zarf-connect:0.1.1677171203 from Zarf-generated helm chart
📦 EXAMPLE-DB COMPONENT
✔ Starting helm chart generation example-db
✔ Processing helm chart raw-postgres-operator-demo-example-db-example-db:0.1.1677171203 from Zarf-generated helm chart
✔ Zarf deployment complete
Connect Command | Description
zarf connect postgres-operator-ui | Launch the postgres opertor web interface
zarf connect pgadmin | Launch the pgadmin web interface
doug in ~/src/github.com/defenseunicorns/zarf/examples/postgres-operator on main 🦄
Well, come back to this database later when we install Mattermost. For now, you can see everything working using kubectl
doug in ~/src/github.com/defenseunicorns/zarf/examples/postgres-operator on main 🦄 kubectl get all -n postgres-operator
NAME READY STATUS RESTARTS AGE
pod/postgres-operator-6cf64f9c8c-fgz6z 1/1 Running 1 (138m ago) 138m
pod/postgres-operator-ui-84dc67cc44-4wl6c 1/1 Running 0 138m
pod/pgadmin4-d8544df47-vzq7c 1/1 Running 0 138m
pod/acid-zarf-test-1 1/1 Running 0 18m
pod/acid-zarf-test-0 1/1 Running 0 17m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/postgres-operator ClusterIP 10.43.64.218 <none> 8080/TCP 138m
service/postgres-operator-ui ClusterIP 10.43.200.226 <none> 80/TCP 138m
service/postgres-operator-ui-zarf-connect ClusterIP 10.43.162.116 <none> 80/TCP 138m
service/pgadmin4 ClusterIP 10.43.34.29 <none> 80/TCP 138m
service/pgadmin-zarf-connect ClusterIP 10.43.38.201 <none> 80/TCP 136m
service/acid-zarf-test ClusterIP 10.43.185.13 <none> 5432/TCP 136m
service/acid-zarf-test-repl ClusterIP 10.43.36.173 <none> 5432/TCP 136m
service/acid-zarf-test-config ClusterIP None <none> <none> 136m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/postgres-operator 1/1 1 1 138m
deployment.apps/postgres-operator-ui 1/1 1 1 138m
deployment.apps/pgadmin4 1/1 1 1 138m
NAME DESIRED CURRENT READY AGE
replicaset.apps/postgres-operator-6cf64f9c8c 1 1 1 138m
replicaset.apps/postgres-operator-ui-84dc67cc44 1 1 1 138m
replicaset.apps/pgadmin4-d8544df47 1 1 1 138m
NAME READY AGE
statefulset.apps/acid-zarf-test 2/2 136m
NAME TEAM VERSION PODS VOLUME CPU-REQUEST MEMORY-REQUEST AGE STATUS
postgresql.acid.zalan.do/acid-zarf-test acid 13 2 2Gi 100m 100Mi 136m Running
NAME IMAGE CLUSTER-LABEL SERVICE-ACCOUNT MIN-INSTANCES AGE
operatorconfiguration.acid.zalan.do/postgres-operator registry.opensource.zalan.do/acid/spilo-14:2.1-p6 cluster-name postgres-pod -1 138m
doug in ~/src/github.com/defenseunicorns/zarf/examples/postgres-operator on main 🦄
Package and Deploy MinIO
MinIO is used by Mattermost to store files, and again we can use the existing MinIO example with Zarf.
- Navigate to the MinIO example in the Zarf source code.
doug in ~/src/github.com/defenseunicorns/zarf/examples/postgres-operator on main 🦄 cd ../minio
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main 🦄
Note: While authoring this blog post, I found a bug in the MinIO example. I’ll be changing this documentation, but in the meantime, modify the zarf-connect.yaml. You’ll need to change the selector in the spec.
- Change this part of the selector
spec:
selector:
app.kubernetes.io/instance: zarf-minio-operator-console
- To this
spec:
selector:
app.kubernetes.io/instance: minio-operator-console
app.kubernetes.io/name: operator
- Package the MinIO example using the
zarf package create
command.
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main 🦄 zarf package create .
Saving log file to
/var/folders/bk/rz1xx2sd5zn134c0_j1s2n5r0000gp/T/zarf-2023-02-23-14-17-55-691300379.log
Using build directory .
kind: ZarfPackageConfig
metadata:
name: minio
description: Deploy minio
version: 4.3.7
url: https://operator.min.io/
image: https://raw.githubusercontent.com/minio/minio/master/.github/logo.svg?sanitize=true
architecture: arm64
build:
terminal: JvBUnicornMBP5
user: jason
architecture: arm64
timestamp: Thu, 23 Feb 2023 14:17:55 -0500
version: v0.24.2
migrations:
- scripts-to-actions
components:
- name: minio
required: true
charts:
- name: operator
releaseName: minio-operator
url: https://operator.min.io/
version: 4.4.28
namespace: minio-operator
valuesFiles:
- operator-values.yaml
- name: tenant
releaseName: minio-tenant
url: https://operator.min.io/
version: 4.4.28
namespace: minio-operator
valuesFiles:
- tenant-values.yaml
manifests:
- name: zarf-connect
files:
- zarf-connect.yaml
images:
- minio/console:v0.19.4
- minio/operator:v4.4.28
- quay.io/minio/minio:RELEASE.2022-05-26T05-48-41Z
- library/postgres:13
- busybox:1.33.1
- alpine
- quay.io/prometheus/prometheus:latest
? Create this Zarf package? Yes
Specify a maximum file size for this package in Megabytes. Above this size, the package will be
split into multiple files. 0 will disable this feature.
? Please provide a value for "Maximum Package Size" 0
📦 MINIO COMPONENT
✔ Processing helm chart operator:4.4.28 from repo https://operator.min.io/
✔ Processing helm chart tenant:4.4.28 from repo https://operator.min.io/
✔ Loading 1 K8s manifests
📦 COMPONENT IMAGES
✔ Loading metadata for 7 images. This step may take several seconds to complete.
✔ Pulling 7 images (467.19 MBs)
✔ Creating SBOMs for 7 images and 0 components with files.
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main 🦄
- Now deploy the MinIO package you created with the
zarf package deploy
command.
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main 🦄 zarf package create .
Saving log file to
/var/folders/bk/rz1xx2sd5zn134c0_j1s2n5r0000gp/T/zarf-2023-02-23-14-17-55-691300379.log
Using build directory .
kind: ZarfPackageConfig
metadata:
name: minio
description: Deploy minio
version: 4.3.7
url: https://operator.min.io/
image: https://raw.githubusercontent.com/minio/minio/master/.github/logo.svg?sanitize=true
architecture: arm64
build:
terminal: JvBUnicornMBP5
user: jason
architecture: arm64
timestamp: Thu, 23 Feb 2023 14:17:55 -0500
version: v0.24.2
migrations:
- scripts-to-actions
components:
- name: minio
required: true
charts:
- name: operator
releaseName: minio-operator
url: https://operator.min.io/
version: 4.4.28
namespace: minio-operator
valuesFiles:
- operator-values.yaml
- name: tenant
releaseName: minio-tenant
url: https://operator.min.io/
version: 4.4.28
namespace: minio-operator
valuesFiles:
- tenant-values.yaml
manifests:
- name: zarf-connect
files:
- zarf-connect.yaml
images:
- minio/console:v0.19.4
- minio/operator:v4.4.28
- quay.io/minio/minio:RELEASE.2022-05-26T05-48-41Z
- library/postgres:13
- busybox:1.33.1
- alpine
- quay.io/prometheus/prometheus:latest
? Create this Zarf package? Yes
Specify a maximum file size for this package in Megabytes. Above this size, the package will be
split into multiple files. 0 will disable this feature.
? Please provide a value for "Maximum Package Size" 0
📦 MINIO COMPONENT
✔ Processing helm chart operator:4.4.28 from repo https://operator.min.io/
✔ Processing helm chart tenant:4.4.28 from repo https://operator.min.io/
✔ Loading 1 K8s manifests
📦 COMPONENT IMAGES
✔ Loading metadata for 7 images. This step may take several seconds to complete.
✔ Pulling 7 images (467.19 MBs)
✔ Creating SBOMs for 7 images and 0 components with files.
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main 🦄
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main 🦄 zarf package deploy zarf-package-minio-arm64-4.3.7.tar.zst
Saving log file to
/var/folders/bk/rz1xx2sd5zn134c0_j1s2n5r0000gp/T/zarf-2023-02-23-14-20-22-3365707464.log
✔ Loading Zarf Package zarf-package-minio-arm64-4.3.7.tar.zst
kind: ZarfPackageConfig
metadata:
name: minio
description: Deploy minio
version: 4.3.7
url: https://operator.min.io/
image: https://raw.githubusercontent.com/minio/minio/master/.github/logo.svg?sanitize=true
architecture: arm64
build:
terminal: JvBUnicornMBP5
user: jason
architecture: arm64
timestamp: Thu, 23 Feb 2023 14:17:55 -0500
version: v0.24.2
migrations:
- scripts-to-actions
components:
- name: minio
required: true
charts:
- name: operator
releaseName: minio-operator
url: https://operator.min.io/
version: 4.4.28
namespace: minio-operator
valuesFiles:
- operator-values.yaml
- name: tenant
releaseName: minio-tenant
url: https://operator.min.io/
version: 4.4.28
namespace: minio-operator
valuesFiles:
- tenant-values.yaml
manifests:
- name: zarf-connect
files:
- zarf-connect.yaml
images:
- minio/console:v0.19.4
- minio/operator:v4.4.28
- quay.io/minio/minio:RELEASE.2022-05-26T05-48-41Z
- library/postgres:13
- busybox:1.33.1
- alpine
- quay.io/prometheus/prometheus:latest
This package has 7 artifacts with software bill-of-materials (SBOM) included. You can view them now
in the zarf-sbom folder in this directory or to go directly to one, open this in your browser:
/Users/jason/src/github.com/defenseunicorns/zarf/examples/minio/zarf-sbom/sbom-viewer-alpine.html
* This directory will be removed after package deployment.
? Deploy this Zarf package? Yes
📦 MINIO COMPONENT
✔ Loading the Zarf State from the Kubernetes cluster
✔ Creating port forwarding tunnel at http://127.0.0.1:63299/v2/_catalog
✔ Storing images in the zarf registry
✔ Processing helm chart operator:4.4.28 from https://operator.min.io/
✔ Processing helm chart tenant:4.4.28 from https://operator.min.io/
✔ Starting helm chart generation zarf-connect
✔ Processing helm chart raw-minio-minio-zarf-connect:0.1.1677180022 from Zarf-generated helm chart
✔ Zarf deployment complete
Connect Command | Description
zarf connect minio | Launch the minio console, to get a JWT run:
zarf tools kubectl -n minio-operator get secrets console-sa-secret -o jsonpath="{.data.token}" | base64 --decode
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main 🦄
Gathering the MinIO Credentials
In order to connect to MinIO we’ll need the JWT token to authenticate with the MinIO console. The command was output at the end of the Zarf package deploy.
Note: There’s a bug in the documentation here. The zarf tools
command is attempting to process the -n argument for kubectl. You’ll get this error, the latest version of zarf as of the time of this blog post (i.e. v0.24.2). So use your own kubectl
binary.
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main 🦄 kubectl -n minio-operator get secrets console-sa-secret -o jsonpath="{.data.token}" | base64 --decode
eyJhbGciOiJSUzI1NiIsImtpZCI6IjMzT1FZNlcxTzZmRkhVMFFPRy05WHVwZ3d4cmxxdF9ud2FybXV5SHBCWFUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJtaW5pby1vcGVyYXRvciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjb25zb2xlLXNhLXNlY3JldCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJjb25zb2xlLXNhIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiMGFkNTY3ODYtMjRiOC00OGM4LWIyNzEtOTEwNjIwOWJiYTIwIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Om1pbmlvLW9wZXJhdG9yOmNvbnNvbGUtc2EifQ.Xq7P7O2TPJIL8lSaXLH_Z_0vrrfdohMqxdl4zlGo9KNuWs2QGKUWTEJvH4M7Cd9rhl_4ggGpaPyOEH_jpDFHWC-UKXWC9c7lPzvYmc9M3FjsxFfutycCwGX5usIWHfYd4PfeMD952ItWpJDIYkkJb6QFdBFMF7lpi9v1XEaWQObKEZ5CYHT15zAwYcU3JwJm5ruPrzCBGVLuTtSnTtLPCXfSuxNVEiHK2ueATpNJJdCEI7GCUSPsaOhTuhK91P73MfXDkq_bVNDoLfNM7aZ8SBIaiC69tb2raH-EMjNgP9hEPGf_9PeOaDzHB1WaZ4b-UxHPkRhjJamcMAMAXDExJQ%
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main 🦄
Configuring MinIO
- Once the MinIO infrastructure is stable, you can connect to the MinIO console. To see if everything is ready, you can use the
kubectl
command. Wait until all the pods are running
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main ● 🦄 kubectl get all -n minio-operator
NAME READY STATUS RESTARTS AGE
pod/console-c84ff4894-n7gs8 1/1 Running 0 51s
pod/minio-operator-554c9f446f-wqtj9 1/1 Running 0 51s
pod/minio-operator-554c9f446f-zg7wj 1/1 Running 0 51s
pod/minio1-log-0 1/1 Running 0 38s
pod/minio1-log-search-api-85c4d558c6-v26xq 1/1 Running 2 (35s ago) 38s
pod/minio1-ss-0-0 1/1 Running 0 40s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/operator ClusterIP 10.43.234.193 <none> 4222/TCP 51s
service/console ClusterIP 10.43.137.182 <none> 9090/TCP,9443/TCP 51s
service/minio-console-zarf-connect ClusterIP 10.43.40.24 <none> 9443/TCP 48s
service/minio ClusterIP 10.43.65.130 <none> 443/TCP 42s
service/minio1-console ClusterIP 10.43.121.217 <none> 9443/TCP 41s
service/minio1-hl ClusterIP None <none> 9000/TCP 41s
service/minio1-log-hl-svc ClusterIP None <none> 5432/TCP 39s
service/minio1-log-search-api ClusterIP 10.43.24.251 <none> 8080/TCP 38s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/console 1/1 1 1 51s
deployment.apps/minio-operator 2/2 2 2 51s
deployment.apps/minio1-log-search-api 1/1 1 1 38s
NAME DESIRED CURRENT READY AGE
replicaset.apps/console-c84ff4894 1 1 1 51s
replicaset.apps/minio-operator-554c9f446f 2 2 2 51s
replicaset.apps/minio1-log-search-api-85c4d558c6 1 1 1 38s
NAME READY AGE
statefulset.apps/minio1-log 1/1 39s
statefulset.apps/minio1-ss-0 1/1 40s
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main ● 🦄
- Use the
zarf connect
command to connect to the MinIO console.
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main 🦄 zarf connect minio
Saving log file to
/var/folders/bk/rz1xx2sd5zn134c0_j1s2n5r0000gp/T/zarf-2023-02-23-15-05-07-2545738381.log
⠋ Looking for a Zarf Connect Label in the cluster (0s)
✔ Creating port forwarding tunnel at http://127.0.0.1:64431
http://127.0.0.1:64431
- This will open your web browser if it doesn’t, you can navigate to the tunnel created by the
zarf connect
command. In the example above, that’shttp://127.0.0.1:64431
- Use the JWT string you received in the Gathering The MinIO Credentials step. To review that command is below. If the
%
is rendered, ignore it. It’s an end-of-line artifact.
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main 🦄 kubectl -n minio-operator get secrets console-sa-secret -o jsonpath="{.data.token}" | base64 --decode
eyJhbGciOiJSUzI1NiIsImtpZCI6IjMzT1FZNlcxTzZmRkhVMFFPRy05WHVwZ3d4cmxxdF9ud2FybXV5SHBCWFUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJtaW5pby1vcGVyYXRvciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjb25zb2xlLXNhLXNlY3JldCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJjb25zb2xlLXNhIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiMGFkNTY3ODYtMjRiOC00OGM4LWIyNzEtOTEwNjIwOWJiYTIwIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Om1pbmlvLW9wZXJhdG9yOmNvbnNvbGUtc2EifQ.Xq7P7O2TPJIL8lSaXLH_Z_0vrrfdohMqxdl4zlGo9KNuWs2QGKUWTEJvH4M7Cd9rhl_4ggGpaPyOEH_jpDFHWC-UKXWC9c7lPzvYmc9M3FjsxFfutycCwGX5usIWHfYd4PfeMD952ItWpJDIYkkJb6QFdBFMF7lpi9v1XEaWQObKEZ5CYHT15zAwYcU3JwJm5ruPrzCBGVLuTtSnTtLPCXfSuxNVEiHK2ueATpNJJdCEI7GCUSPsaOhTuhK91P73MfXDkq_bVNDoLfNM7aZ8SBIaiC69tb2raH-EMjNgP9hEPGf_9PeOaDzHB1WaZ4b-UxHPkRhjJamcMAMAXDExJQ%
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main 🦄
Create a Bucket for Object Storage in the default MinIO Tenant
- Click on the minio1 tenant.
- In the minio1 tenant, click the Console button
- In the Tenants > minio1 > Management page, click the Create Bucket button.
- Give the bucket a name, and then click the Create Bucket button.
- The Management page will now show the MinIO bucket that you created in the minio1 tenant.
Creating a MinIO Tenant User to MinIO Bucket access
- Expand the Identity drop-down, and select Users.
- On the Users page, click the Create User button.
- Give the user a Username and Password, check the readwrite policy. Make note of these, you’ll need it to configure Mattermost.
- Click the Save button.
Create a Mattermost Package
- Create a new subdirectory for your Mattermost Zarf package.
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main 🦄 mkdir ../mattermost
doug in ~/src/github.com/defenseunicorns/zarf/examples/minio on main 🦄 cd ../mattermost
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄
- We’ll be creating 5 files.
- The Mattermost Operator
- A Mattermost Installation Manifest
- A PostgreSQL secret so Mattermost can access the PostgreSQL database.
- A MinIO secret so Mattermost can access the bucket you created earlier in the minio1 tenant.
Mattermost Operator
- Get the URL for the Mattermost Operator from the document Install Mattermost on Kubernetes. At the time of this blog post that operator can be found at https://raw.githubusercontent.com/mattermost/mattermost-operator/master/docs/mattermost-operator/mattermost-operator.yaml. Save this document to your mattermost folder as mattermost-operator.yaml
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄 curl -LO https://raw.githubusercontent.com/mattermost/mattermost-operator/master/docs/mattermost-operator/mattermost-operator.yaml
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 409k 100 409k 0 0 1800k 0 --:--:-- --:--:-- --:--:-- 1851k
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄 ls
mattermost-operator.yaml
- We want to be explicit about which version of the Mattermost operator and container images we’re going to use.
- Open the matttermost-operator.yaml file in your favorite editor, and scroll to the very bottom. Replace this :latest tag with the latest version of the mattermost-operator image. You can find this version at https://github.com/mattermost/mattermost-operator/releases. At the time of this blog that is v1.19.0
command:
- /mattermost-operator
env:
- name: MAX_RECONCILING_INSTALLATIONS
value: "20"
- name: REQUEUE_ON_LIMIT_DELAY
value: 20s
- name: MAX_RECONCILE_CONCURRENCY
value: "10"
image: mattermost/mattermost-operator:latest # <----- Replace this.
imagePullPolicy: IfNotPresent
name: mattermost-operator
ports:
- containerPort: 8383
name: metrics
serviceAccountName: mattermost-operator
- In this case when you’re done, it should look like this.
command:
- /mattermost-operator
env:
- name: MAX_RECONCILING_INSTALLATIONS
value: "20"
- name: REQUEUE_ON_LIMIT_DELAY
value: 20s
- name: MAX_RECONCILE_CONCURRENCY
value: "10"
image: mattermost/mattermost-operator:v1.19.0
imagePullPolicy: IfNotPresent
name: mattermost-operator
ports:
- containerPort: 8383
name: metrics
serviceAccountName: mattermost-operator
Mattermost Installation Manifest
- We’re skipping the nginx instructions as k3d uses k3s, which ships and enables traefik by default.
- We’re skipping the license file since this is a getting-started blog.
- Use your favorite editor, and copy the installation manifest.
- Change the ingress.class to traefik.
- Don’t forget to change your host as needed.
- Scroll down to get the format for the sections needed for the MinIO and PostgreSQL secrets we’ll need to create.
- Save the file as
mattermost-installation.yaml
. It will look like my example below. I changed the size to100users
. You’ll notice we’ll have to create secrets called minio-secret, and postgres-secret. You’ll also notice the bucket name is the same as the bucket I created in the MinIO console. The service name is the kubernetes default <service name>.<namespace name>.svc.cluster.local.
apiVersion: installation.mattermost.com/v1beta1
kind: Mattermost
metadata:
name: mm-example-full # Chose the desired name
spec:
size: 100users # Adjust to your requirements
ingress:
enabled: true
host: example.mattermost-example.com # Adjust to your domain
annotations:
kubernetes.io/ingress.class: traefik
version: 6.0.1
fileStore:
external:
url: minio.minio-operator.svc.cluster.local
bucket: mattermost-bucket
secret: minio-secret
database:
external:
secret: postgres-secret
licenseSecret: "" # If you have created secret in step 1, put its name here
PostgreSQL secret
- Create a file called postgres-secret.yaml
- Copy the format from the Mattermost documentation under Deploy Mattermost, step 3. That file looks like this.
apiVersion: v1
data:
DB_CONNECTION_CHECK_URL: cG9zdGdyZXM6Ly91c2VyOnN1cGVyX3NlY3JldF9wYXNzd29yZEBteS1kYXRhYmFzZS5jbHVzdGVyLWFiY2QudXMtZWFzdC0xLnJkcy5hbWF6b25hd3MuY29tOjU0MzIvbWF0dGVybW9zdD9jb25uZWN0X3RpbWVvdXQ9MTAK
DB_CONNECTION_STRING: cG9zdGdyZXM6Ly91c2VyOnN1cGVyX3NlY3JldF9wYXNzd29yZEBteS1kYXRhYmFzZS5jbHVzdGVyLWFiY2QudXMtZWFzdC0xLnJkcy5hbWF6b25hd3MuY29tOjU0MzIvbWF0dGVybW9zdD9jb25uZWN0X3RpbWVvdXQ9MTAK
MM_SQLSETTINGS_DATASOURCEREPLICAS: cG9zdGdyZXM6Ly91c2VyOnN1cGVyX3NlY3JldF9wYXNzd29yZEBteS1kYXRhYmFzZS5jbHVzdGVyLXJvLWFiY2QudXMtZWFzdC0xLnJkcy5hbWF6b25hd3MuY29tOjU0MzIvbWF0dGVybW9zdD9jb25uZWN0X3RpbWVvdXQ9MTAK
kind: Secret
metadata:
name: my-postgres-connection
type: Opaque
- Remove the line with the DB_CONNECTION_CHECK_URL setting
- Remove the line with the MM_SQLSETTINGS_DATASOURCEREPLICAS setting
- Decode the DB_CONNECTION_STRING, we’re going to use it to get the connection string format.
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄 echo "cG9zdGdyZXM6Ly91c2VyOnN1cGVyX3NlY3JldF9wYXNzd29yZEBteS1kYXRhYmFzZS5jbHVzdGVyLWFiY2QudXMtZWFzdC0xLnJkcy5hbWF6b25hd3MuY29tOjU0MzIvbWF0dGVybW9zdD9jb25uZWN0X3RpbWVvdXQ9MTAK" | base64 -d
postgres://user:super_secret_password@my-database.cluster-abcd.us-east-1.rds.amazonaws.com:5432/mattermost?connect_timeout=10
- Replace the username, password, server hostname, and database name, as per the Zarf Postgres Operator example.
- The server hostname is acid-zarf-test.postgres-operator.svc.cluster.local
- The database is zarf
- The username is zarf
- The password you can get from a Kubernetes secret using the
kubectl
command in the documentation. Again remember the % is an end-of-line token, not part of the password.
echo $(kubectl get secret zarf.acid-zarf-test.credentials.postgresql.acid.zalan.do -n postgres-operator --template={{.data.password}}) | base64 -d
HHqVPnTdd9dAH766unHsJMdkyBavk9mTUuiwFGOv9G7GdCelvVyS5wGrH8JJK8G4%
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄
- In this case, that makes the Database Connection String
postgres://zarf:HHqVPnTdd9dAH766unHsJMdkyBavk9mTUuiwFGOv9G7GdCelvVyS5wGrH8JJK8G4@acid-zarf-test.postgres-operator.svc.cluster.local:5432/zarf?connect_timeout=10
- This needs to be encoded for the Kubernetes secret.
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄 echo -n "postgres://zarf:HHqVPnTdd9dAH766unHsJMdkyBavk9mTUuiwFGOv9G7GdCelvVyS5wGrH8JJK8G4@acid-zarf-test.postgres-operator.svc.cluster.local:5432/zarf?connect_timeout=10" | base64
cG9zdGdyZXM6Ly96YXJmOkhIcVZQblRkZDlkQUg3NjZ1bkhzSk1ka3lCYXZrOW1UVXVpd0ZHT3Y5RzdHZENlbHZWeVM1d0dySDhKSks4RzRAYWNpZC16YXJmLXRlc3QucG9zdGdyZXMtb3BlcmF0b3Iuc3ZjLmNsdXN0ZXIubG9jYWw6NTQzMi96YXJmP2Nvbm5lY3RfdGltZW91dD0xMA==
- In this example the postgres-secret.yaml file will look like this.
apiVersion: v1
data:
DB_CONNECTION_STRING: cG9zdGdyZXM6Ly96YXJmOkhIcVZQblRkZDlkQUg3NjZ1bkhzSk1ka3lCYXZrOW1UVXVpd0ZHT3Y5RzdHZENlbHZWeVM1d0dySDhKSks4RzRAYWNpZC16YXJmLXRlc3QucG9zdGdyZXMtb3BlcmF0b3Iuc3ZjLmNsdXN0ZXIubG9jYWw6NTQzMi96YXJmP2Nvbm5lY3RfdGltZW91dD0xMA==
kind: Secret
metadata:
name: postgres-secret
type: Opaque
MinIO Secret
- Copy the format for the MinIO secret from the Mattermost documentation and save to a file called minio-secret.yaml. Under step 4. It will look something like this.
apiVersion: v1
data:
accesskey: QUNDRVNTX0tFWQo=
secretkey: U1VQRVJfU0VDUkVUX0tFWQo=
kind: Secret
metadata:
name: my-s3-iam-access-key
type: Opaque
- We’ll be replacing the accesskey and secretkey. We’ll also rename it to minio-secret.
- The username will be the base64 encoded username you created when you created the Minio Tenant User in the minio1 tenant.
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄 echo -n "mattermost-user" | base64
bWF0dGVybW9zdC11c2Vy
- The password will be the base64 encodes password you created when you created the Minio Tenant User in the minio1 tenant.
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄 echo -n "ReallyStrongMattermostPassword" | base64
UmVhbGx5U3Ryb25nTWF0dGVybW9zdFBhc3N3b3Jk
- With that the minio-secret.yaml file will look something like this.
apiVersion: v1
data:
accesskey: bWF0dGVybW9zdC11c2Vy
secretkey: UmVhbGx5U3Ryb25nTWF0dGVybW9zdFBhc3N3b3Jk
kind: Secret
metadata:
name: minio-secret
type: Opaque
Zarf Package Manifest
Now we’re ready to create our zarf.yaml file. Create a new file called zarf.yaml.
We’ll create items in the mattermost component for each of the files we’ve created and all of the images that are referenced by the mattermost operator.
The final package manifest will look something like this. You can get the version of the Mattermost Enterprise Edition Image at https://github.com/mattermost/mattermost-server/releases
kind: ZarfPackageConfig
metadata:
name: mattermost-example
description: "Deploy Mattermost"
version: v1.19.0
url: https://mattermost.com
image: https://avatars.githubusercontent.com/u/9828093?s=200&v=4
components:
- name: mattermost
required: true
images:
- "mattermost/mattermost-operator:v1.19.0"
- "mattermost/mattermost-enterprise-edition:7.8.0"
manifests:
- name: mattermost-operator-installation
namespace: mattermost-operator
files:
- "mattermost-operator.yaml"
- name: postgres-secret
files:
- "postgres-secret.yaml"
- name: minio-secret
files:
- "minio-secret.yaml"
- name: mattermost-installation-manifest
files:
- "mattermost-installation.yaml"
Build the Zarf Package
- Use the
zarf package create
command to build the package.
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄 zarf package create .
Saving log file to
/var/folders/bk/rz1xx2sd5zn134c0_j1s2n5r0000gp/T/zarf-2023-02-23-18-12-32-3214058833.log
Using build directory .
kind: ZarfPackageConfig
metadata:
name: mattermost-example
description: Deploy Mattermost
version: v1.19.0
url: https://mattermost.com
image: https://avatars.githubusercontent.com/u/9828093?s=200&v=4
architecture: arm64
build:
terminal: JvBUnicornMBP5
user: jason
architecture: arm64
timestamp: Thu, 23 Feb 2023 18:12:32 -0500
version: v0.24.2
migrations:
- scripts-to-actions
components:
- name: mattermost
required: true
manifests:
- name: mattermost-operator-installation
namespace: mattermost-operator
files:
- mattermost-operator.yaml
- name: postgres-secret
files:
- postgres-secret.yaml
- name: minio-secret
files:
- minio-secret.yaml
- name: mattermost-installation-manifest
files:
- mattermost-installation.yaml
images:
- mattermost/mattermost-operator:v1.19.0
- mattermost/mattermost-enterprise-edition:7.8.0
? Create this Zarf package? Yes
Specify a maximum file size for this package in Megabytes. Above this size, the package will be
split into multiple files. 0 will disable this feature.
? Please provide a value for "Maximum Package Size" 0
📦 MATTERMOST COMPONENT
✔ Loading 4 K8s manifests
📦 COMPONENT IMAGES
✔ Loading metadata for 2 images.
✔ Pulling 2 images (493.24 MBs)
✔ Creating SBOMs for 2 images and 0 components with files.
Deploy the Mattermost Zarf Package
- Use the
zarf package deploy
command to deploy the Zarf package you created.
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄 zarf package deploy zarf-package-mattermost-example-arm64-v1.19.0.tar.zst
Saving log file to
/var/folders/bk/rz1xx2sd5zn134c0_j1s2n5r0000gp/T/zarf-2023-02-23-18-13-47-3169555226.log
✔ Loading Zarf Package zarf-package-mattermost-example-arm64-v1.19.0.tar.zst
kind: ZarfPackageConfig
metadata:
name: mattermost-example
description: Deploy Mattermost
version: v1.19.0
url: https://mattermost.com
image: https://avatars.githubusercontent.com/u/9828093?s=200&v=4
architecture: arm64
build:
terminal: JvBUnicornMBP5
user: jason
architecture: arm64
timestamp: Thu, 23 Feb 2023 18:12:32 -0500
version: v0.24.2
migrations:
- scripts-to-actions
components:
- name: mattermost
required: true
manifests:
- name: mattermost-operator-installation
namespace: mattermost-operator
files:
- mattermost-operator.yaml
- name: postgres-secret
files:
- postgres-secret.yaml
- name: minio-secret
files:
- minio-secret.yaml
- name: mattermost-installation-manifest
files:
- mattermost-installation.yaml
images:
- mattermost/mattermost-operator:v1.19.0
- mattermost/mattermost-enterprise-edition:7.8.0
This package has 2 artifacts with software bill-of-materials (SBOM) included. You can view them now
in the zarf-sbom folder in this directory or to go directly to one, open this in your browser:
/Users/jason/src/github.com/defenseunicorns/zarf/examples/mattermost/zarf-sbom/sbom-viewer-mattermost_mattermost-enterprise-edition_7.8.0.html
* This directory will be removed after package deployment.
? Deploy this Zarf package? Yes
📦 MATTERMOST COMPONENT
✔ Loading the Zarf State from the Kubernetes cluster
✔ Creating port forwarding tunnel at http://127.0.0.1:52578/v2/_catalog
✔ Storing images in the zarf registry
✔ Starting helm chart generation mattermost-operator-installation
✔ Processing helm chart raw-mattermost-example-mattermost-mattermost-operator-installation:0.1.1677194027 from Zarf-generated helm chart
✔ Starting helm chart generation postgres-secret
✔ Processing helm chart raw-mattermost-example-mattermost-postgres-secret:0.1.1677194027 from Zarf-generated helm chart
✔ Starting helm chart generation minio-secret
✔ Processing helm chart raw-mattermost-example-mattermost-minio-secret:0.1.1677194027 from Zarf-generated helm chart
✔ Starting helm chart generation mattermost-installation-manifest
✔ Processing helm chart raw-mattermost-example-mattermost-mattermost-installation-manifest:0.1.1677194027 from Zarf-generated helm chart
✔ Zarf deployment complete
Checking our work
- Check your work with
kubectl
.
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄 kubectl -n mattermost-operator get all
NAME READY STATUS RESTARTS AGE
pod/mattermost-operator-7684b7d685-xs9sv 1/1 Running 0 104s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/mattermost-operator ClusterIP 10.43.67.144 <none> 8383/TCP 104s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/mattermost-operator 1/1 1 1 104s
NAME DESIRED CURRENT READY AGE
replicaset.apps/mattermost-operator-7684b7d685 1 1 1 104s
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄 kubectl get mattermosts.installation.mattermost.com
NAME STATE IMAGE VERSION ENDPOINT
mm-example-full reconciling
- When it’s ready, the mattermost installation will look like this.
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄 kubectl get mattermosts.installation.mattermost.com
NAME STATE IMAGE VERSION ENDPOINT
mm-example-full stable mattermost/mattermost-enterprise-edition 6.0.1 example.mattermost-example.com
Connecting to Mattermost
- Use
kubectl port-forward
to connect to mattermost.
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄 kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 6h48m
mm-example-full ClusterIP None <none> 8065/TCP,8067/TCP 2m51s
doug in ~/src/github.com/defenseunicorns/zarf/examples/mattermost on main 🦄 kubectl port-forward svc/mm-example-full 8888:8065
Forwarding from 127.0.0.1:8888 -> 8065
Forwarding from [::1]:8888 -> 8065
Closing
Success! If this was helpful to you please let us know. If you have any questions you can reach us in the #Zarf channel on the Kubernetes Slack. You can also reach us on Twitter, LinkedIn, and YouTube!