Say you're doing CI/CD like the cool kids: push to git, some CI pipeline runs and builds your image, some automated push to git happens updating a reference to your deployment, and ArgoCD goes and syncs your application to the new state.
That all sounds fine, and pretty scalable for many deployment environments. But the reality is it's quite a slow development loop when you're working with a single environment. So what can you do?
Oh and your kubernetes manifests are rendered (but no deployed) with
Helm,
and it's in a top level subdirectory in your repo (repo-root/helm/Chart.yaml
).
There are a multitude of options for tools orchestrating the local-to-k8s development flow, but here we're going to focus on skaffold because I like it. (Other options include tilt, telepresence, devspace.)
skaffold v2 (which uses a config version of skaffold/v3
...)
comes with separate render
and deploy
phases.
Because we're targeting an environment normally deployed with ArgoCD,
our only option for the deploy phase is kubectl
.
We don't want to leave around helm deployment records that will interfere with ArgoCD operations.
As for the render phase, it's not as easy as just choose helm
...
ArgoCD adds an extra label to deployed manifests
to allow it to track which resources are associated with which ArgoCD Application.
We need to keep those so ArgoCD will still be able to cleanup/sync after we're done with local dev.
The obvious solution for this is to use kustomize
with its built in labels
transform.
Helm has the option for hooking in to a post render tool.
What this looks like is a shell script to write the contents of stdin to a file,
and calling kustomize
with the configured label transform.
1# skaffold.yaml
2apiVersion: skaffold/v3
3kind: Config
4manifests:
5 helm:
6 flags:
7 global:
8 - --post-renderer=./render/render.sh
9 releases:
10 - name: my-app
11 chartPath: ./helm
12 valuesFiles:
13 - helm/values.yaml
14 - helm/values/my-env.yaml
1#!/bin/sh
2# render/render.sh
3
4cp /dev/stdin out.yaml
5
6kustomize build .
7
8rm out.yaml
1# render/kustomization.yaml
2apiVersion: kustomize.config.k8s.io/v1beta1
3kind: Kustomization
4resources:
5 - all.yaml
6labels:
7 - pairs:
8 my-argocd-tracking: label
9 includeSelectors: false
10 includeTemplates: false
Another option using the same tools inverts the control and gets rid of the shell script,
instead using skaffold hooks to run helm template
.
While kustomize has a helmCharts builtin for rendering helm Charts, it's not quite flexible enough, requiring a parent directory holding charts, and only allowing a single values file.
1# skaffold.yaml
2apiVersion: skaffold/v3
3kind: Config
4manifests:
5 kustomize:
6 paths:
7 - render
8 hooks:
9 before:
10 - host:
11 command:
12 - sh
13 - -c
14 - |
15 helm template my-app ./helm -f helm/values.yaml -f helm/values/my-env.yaml > render/all.yaml
1# render/kustomization.yaml
2apiVersion: kustomize.config.k8s.io/v1beta1
3kind: Kustomization
4resources:
5 - all.yaml
6labels:
7 - pairs:
8 my-argocd-tracking: label
9 includeSelectors: false
10 includeTemplates: false