Example Kubernetes manifests using Go templating
This topic describes how to make your Kubernetes manifests reusable and dynamic using Go templating and Harness built-in variables.
Basic values YAML and manifests for public image
This is a simple example using the Artifact reference <+artifact.image>
. It can be used whenever the public image is not hardcoded in manifests.
See Add Container Images as Artifacts for Kubernetes Deployments.
We use Go templates with a values.yaml file and manifests for deployment, namespace, and service. The manifests for deployment, namespace, and service are in a templates folder that's a peer of the values.yaml file.
values.yaml
templates/deployment.yaml
templates/namespace.yaml
templates/service.yaml
Private artifact example
When the image is in a private repo, you use the expression <+artifact.imagePullSecret>
in the Secret and Deployment objects in your manifest.
This key will import the credentials from the Docker credentials file in the artifact.
It's much simpler to simple use the <+artifact.imagePullSecret>
expression in the values.yaml file and then reference it in other manifests.
Using the values.yaml file above, we simply remove the comment in front of dockercfg: <+artifact.imagePullSecret>
:
name: <+stage.name>
replicas: 2
image: <+artifact.image>
dockercfg: <+artifact.imagePullSecret>
createNamespace: true
namespace: <+infra.namespace>
...
You don't need to make changes to the deployment manifest from earlier. It uses Go templating to check for the dockercfg
value in values.yaml and applies it to Secret and Deployment.
If using the condition {{- if .Values.dockercfg}}
to check for dockercfg
in values.yaml.
...
{{- if .Values.dockercfg}}
apiVersion: v1
kind: Secret
metadata:
name: {{.Values.name}}-dockercfg
annotations:
harness.io/skip-versioning: true
data:
.dockercfg: {{.Values.dockercfg}}
type: kubernetes.io/dockercfg
---
{{- end}}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{.Values.name}}-deployment
spec:
replicas: {{int .Values.replicas}}
selector:
matchLabels:
app: {{.Values.name}}
template:
metadata:
labels:
app: {{.Values.name}}
spec:
{{- if .Values.dockercfg}}
imagePullSecrets:
- name: {{.Values.name}}-dockercfg
{{- end}}
containers:
- name: {{.Values.name}}
image: {{.Values.image}}
...
Quotation marks
The following example puts quotations around whatever string is in the something
value. This can handle values that could otherwise be interpreted as numbers, or empty values, which would cause an error.
{{.Values.something | quote}}
You should use single quotes if you are using a value that might contain a YAML-like structure that could cause issues for the YAML parser.
Verbatim
Use indent
and toYaml
to put something from the values file into the manifest verbatim.
{{.Values.env.config | toYaml | indent 2}}
Indexing structures in templates
If the data passed to the template is a map, slice, or array it can be indexed from the template.
You can use {{index x number}}
where index
is the keyword, x
is the data, and number
is an integer for the index
value.
If we had {{index names 2}}
it is equivalent to names[2]
. We can add more integers to index deeper into data. {{index names 2 3 4}}
is equivalent to names[2][3][4]
.
Expand below to see the YAML example.
YAML example
Skip rendering of manifest files
In some cases, you might not want to use Go templating because your manifests use some other formatting.
Use the Skip Rendering K8s manifest files option in the Kubernetes Apply step if you want Harness to skip rendering your manifest files using Go templating.
Important notes
- Harness Variables and Expressions may be added to values.yaml, not the manifests themselves. This provides more flexibility.
- The values.yaml file used in a stage Service doesn't support Helm templating, only Go templating. Helm templating is fully supported in the remote Helm charts you add to your Service.
- Harness uses Go template version 0.4.5. If you're used to Helm templates, you can download Go template and try it out locally to find out if your manifests will work. This can help you avoid issues when adding your manifests to Harness.
- You can install Go template version 0.4.5 locally to test your manifests.
-
Mac OS:
- AMD64:
curl -O https://app.harness.io/public/shared/tools/go-template/release/v0.4.5/bin/darwin/amd64/go-template
- ARM64:
curl -O https://app.harness.io/public/shared/tools/go-template/release/v0.4.5/bin/darwin/arm64/go-template
- AMD64:
-
Linux:
- AMD64:
curl -O https://app.harness.io/public/shared/tools/go-template/release/v0.4.5/bin/linux/amd64/go-template
- ARM64:
curl -O https://app.harness.io/public/shared/tools/go-template/release/v0.4.5/bin/linux/arm64/go-template
- AMD64:
-
Windows:
curl -O https://app.harness.io/public/shared/tools/go-template/release/v0.4.5/bin/windows/amd64/go-template.exe
After installing Go template, you can run the
./go-template
command from your local machine to view the template usage. Here's a sample output:Usage:
Template: ./go-template <-t templateFilePath> [-f valuesFilePath] [-s variableOverride] [-o outputFolder]
Version : ./go-template -v
-
- Harness uses an internal build of Go templating. It cannot be upgraded. Harness uses Spring templates functions, excluding those functions that provide access to the underlying OS (env, expandenv) for security reasons. In addition, Harness uses the functions ToYaml, FromYaml, ToJson, FromJson.