From 3a04f7e5148b7b8cb61eccc6575ce2957f5d49a9 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Sun, 9 Oct 2022 17:55:36 +0200 Subject: [PATCH] feat: add basic helm workshop initial version --- .gitignore | 2 + helm-template-advanced/index.json | 25 --------- helm-template-advanced/intro.md | 1 - helm-template-advanced/step1/verify.sh | 3 -- helm-template-basic/assets/step2/Chart.yaml | 4 ++ .../assets/step2/policy/test.rego | 13 +++++ .../assets/step2/templates/deployment.yaml | 8 +++ helm-template-basic/assets/step3/Chart.yaml | 4 ++ .../assets/step3/policy/test.rego | 32 ++++++++++++ .../assets/step3/templates/deployment.yaml | 7 +++ helm-template-basic/assets/step3/values.yaml | 5 ++ helm-template-basic/assets/step4/Chart.yaml | 4 ++ .../assets/step4/policy/test.rego | 39 ++++++++++++++ .../assets/step4/templates/deployment.yaml | 10 ++++ helm-template-basic/assets/step4/values.yaml | 2 + helm-template-basic/assets/step5/Chart.yaml | 9 ++++ .../assets/step5/policy/test.rego | 31 +++++++++++ .../assets/step5/templates/deployment.yaml | 6 +++ helm-template-basic/assets/step5/values.yaml | 0 helm-template-basic/background.sh | 9 ++++ helm-template-basic/foreground.sh | 3 ++ helm-template-basic/index.json | 35 +++++++++++++ helm-template-basic/intro.md | 3 ++ .../step1/foreground.sh | 0 .../step1/instruction.md | 6 +++ helm-template-basic/step1/verify.sh | 4 ++ helm-template-basic/step2/instruction.md | 23 +++++++++ helm-template-basic/step2/verify.sh | 5 ++ helm-template-basic/step3/instruction.md | 51 +++++++++++++++++++ helm-template-basic/step3/verify.sh | 5 ++ helm-template-basic/step4/instruction.md | 50 ++++++++++++++++++ helm-template-basic/step4/verify.sh | 5 ++ helm-template-basic/step5/instruction.md | 50 ++++++++++++++++++ helm-template-basic/step5/verify.sh | 19 +++++++ 34 files changed, 444 insertions(+), 29 deletions(-) delete mode 100644 helm-template-advanced/index.json delete mode 100644 helm-template-advanced/intro.md delete mode 100644 helm-template-advanced/step1/verify.sh create mode 100644 helm-template-basic/assets/step2/Chart.yaml create mode 100644 helm-template-basic/assets/step2/policy/test.rego create mode 100644 helm-template-basic/assets/step2/templates/deployment.yaml create mode 100644 helm-template-basic/assets/step3/Chart.yaml create mode 100644 helm-template-basic/assets/step3/policy/test.rego create mode 100644 helm-template-basic/assets/step3/templates/deployment.yaml create mode 100644 helm-template-basic/assets/step3/values.yaml create mode 100644 helm-template-basic/assets/step4/Chart.yaml create mode 100644 helm-template-basic/assets/step4/policy/test.rego create mode 100644 helm-template-basic/assets/step4/templates/deployment.yaml create mode 100644 helm-template-basic/assets/step4/values.yaml create mode 100644 helm-template-basic/assets/step5/Chart.yaml create mode 100644 helm-template-basic/assets/step5/policy/test.rego create mode 100644 helm-template-basic/assets/step5/templates/deployment.yaml create mode 100644 helm-template-basic/assets/step5/values.yaml create mode 100644 helm-template-basic/background.sh create mode 100644 helm-template-basic/foreground.sh create mode 100644 helm-template-basic/index.json create mode 100644 helm-template-basic/intro.md rename {helm-template-advanced => helm-template-basic}/step1/foreground.sh (100%) rename {helm-template-advanced => helm-template-basic}/step1/instruction.md (60%) create mode 100644 helm-template-basic/step1/verify.sh create mode 100644 helm-template-basic/step2/instruction.md create mode 100644 helm-template-basic/step2/verify.sh create mode 100644 helm-template-basic/step3/instruction.md create mode 100644 helm-template-basic/step3/verify.sh create mode 100644 helm-template-basic/step4/instruction.md create mode 100644 helm-template-basic/step4/verify.sh create mode 100644 helm-template-basic/step5/instruction.md create mode 100755 helm-template-basic/step5/verify.sh diff --git a/.gitignore b/.gitignore index 485dee6..7185749 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .idea +assets/**/charts +Chart.lock diff --git a/helm-template-advanced/index.json b/helm-template-advanced/index.json deleted file mode 100644 index eb59fe0..0000000 --- a/helm-template-advanced/index.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "title": "Advanced helm templating", - "description": "Train to work with helm templates", - "details": { - "intro": { - "text": "intro.md" - }, - "steps": [ - { - "title": "Install Helm", - "foreground": "step1/foreground.sh", - "text": "step1/instruction.md", - "verify": "step1/verify.sh" - }, - { - "title": "Delete a pod", - "text": "step2/text.md", - "verify": "step2/verify.sh" - } - ] - }, - "backend": { - "imageid": "ubuntu" - } -} diff --git a/helm-template-advanced/intro.md b/helm-template-advanced/intro.md deleted file mode 100644 index 14cf46c..0000000 --- a/helm-template-advanced/intro.md +++ /dev/null @@ -1 +0,0 @@ -Helm template demo diff --git a/helm-template-advanced/step1/verify.sh b/helm-template-advanced/step1/verify.sh deleted file mode 100644 index 6288bf6..0000000 --- a/helm-template-advanced/step1/verify.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -command -v helm diff --git a/helm-template-basic/assets/step2/Chart.yaml b/helm-template-basic/assets/step2/Chart.yaml new file mode 100644 index 0000000..44c8fdd --- /dev/null +++ b/helm-template-basic/assets/step2/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +name: step2 +type: application +version: 0.1.0 diff --git a/helm-template-basic/assets/step2/policy/test.rego b/helm-template-basic/assets/step2/policy/test.rego new file mode 100644 index 0000000..61f7e33 --- /dev/null +++ b/helm-template-basic/assets/step2/policy/test.rego @@ -0,0 +1,13 @@ +package main + +name = input.metadata.name + +is_deployment { + input.kind = "Deployment" +} + +deny[msg] { + is_deployment + not name == "fancy" + msg = sprintf("your deployment should have name %s and not %s ", ["fancy", name]) +} diff --git a/helm-template-basic/assets/step2/templates/deployment.yaml b/helm-template-basic/assets/step2/templates/deployment.yaml new file mode 100644 index 0000000..0d11ad9 --- /dev/null +++ b/helm-template-basic/assets/step2/templates/deployment.yaml @@ -0,0 +1,8 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ required "need to set some name for deployment" .Values.name }} + annotations: + chart: {{ default .Chart.Name .Values.nameOverride }} + labels: + app: nginx diff --git a/helm-template-basic/assets/step3/Chart.yaml b/helm-template-basic/assets/step3/Chart.yaml new file mode 100644 index 0000000..c0ef07c --- /dev/null +++ b/helm-template-basic/assets/step3/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +name: step3 +type: application +version: 0.1.0 diff --git a/helm-template-basic/assets/step3/policy/test.rego b/helm-template-basic/assets/step3/policy/test.rego new file mode 100644 index 0000000..9fa7989 --- /dev/null +++ b/helm-template-basic/assets/step3/policy/test.rego @@ -0,0 +1,32 @@ +package main + +name = input.metadata.name + +is_deployment { + input.kind = "Deployment" +} + +required_labels { + input.metadata.labels["env"] + input.metadata.labels["team"] +} + +deny[msg] { + is_deployment + not required_labels + msg = sprintf("deployment %s must have labels env and team", [name]) +} + +deny[msg] { + is_deployment + label := input.metadata.labels["env"] + not label == "prod" + msg = sprintf("label %s must have value %s but found %s", ["env", "prod", label]) +} + +deny[msg] { + is_deployment + label := input.metadata.labels["team"] + not label == "dev" + msg = sprintf("label %s must have value %s but has value %s", ["team", "dev", label]) +} diff --git a/helm-template-basic/assets/step3/templates/deployment.yaml b/helm-template-basic/assets/step3/templates/deployment.yaml new file mode 100644 index 0000000..82d72ff --- /dev/null +++ b/helm-template-basic/assets/step3/templates/deployment.yaml @@ -0,0 +1,7 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx + annotations: + chart: {{ default .Chart.Name .Values.nameOverride }} + labels: diff --git a/helm-template-basic/assets/step3/values.yaml b/helm-template-basic/assets/step3/values.yaml new file mode 100644 index 0000000..524a4f4 --- /dev/null +++ b/helm-template-basic/assets/step3/values.yaml @@ -0,0 +1,5 @@ +customLabels: + - name: env + value: "prod" + - name: team + value: "dev" diff --git a/helm-template-basic/assets/step4/Chart.yaml b/helm-template-basic/assets/step4/Chart.yaml new file mode 100644 index 0000000..d289575 --- /dev/null +++ b/helm-template-basic/assets/step4/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +name: step4 +type: application +version: 0.1.0 diff --git a/helm-template-basic/assets/step4/policy/test.rego b/helm-template-basic/assets/step4/policy/test.rego new file mode 100644 index 0000000..7d78c27 --- /dev/null +++ b/helm-template-basic/assets/step4/policy/test.rego @@ -0,0 +1,39 @@ +package main + +name = input.metadata.name + +required_deployment_labels { + input.metadata.labels["app"] + input.metadata.labels["addon"] + input.metadata.labels["triple"] +} + +is_deployment { + input.kind = "Deployment" +} + +deny[msg] { + is_deployment + not required_deployment_labels + msg = sprintf("deployment %s must have labels app, addon and triple", [name]) +} + +deny[msg] { + is_deployment + label := input.metadata.labels["app"] + not label = "nginx-trace-addon" + msg = sprintf("label %s must have value %s but have %s", ["app", "nginx-trace-addon", label]) +} + +deny[msg] { + is_deployment + label := input.metadata.labels["addon"] + not label = "TRACE-ADDON" + msg = sprintf("label %s must have value %s but have %s", ["addon", "TRACE-ADDON", label]) +} + +deny[msg] { + is_deployment + not input.metadata.labels["triple"] = "nginx-trace-addonnginx-trace-addonnginx-trace-addon" + msg = sprintf("label %s must have value %s", ["triple", "nginx-trace-addonnginx-trace-addonnginx-trace-addon"]) +} diff --git a/helm-template-basic/assets/step4/templates/deployment.yaml b/helm-template-basic/assets/step4/templates/deployment.yaml new file mode 100644 index 0000000..99d9649 --- /dev/null +++ b/helm-template-basic/assets/step4/templates/deployment.yaml @@ -0,0 +1,10 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx2 + annotations: + chart: {{ default .Chart.Name .Values.nameOverride }} + labels: + app: {{ .Values.app.name }} + addon: {{ .Values.app.name }} + triple: {{ .Values.app.name }} diff --git a/helm-template-basic/assets/step4/values.yaml b/helm-template-basic/assets/step4/values.yaml new file mode 100644 index 0000000..a3f8065 --- /dev/null +++ b/helm-template-basic/assets/step4/values.yaml @@ -0,0 +1,2 @@ +app: + name: "nginx-trace-addon" diff --git a/helm-template-basic/assets/step5/Chart.yaml b/helm-template-basic/assets/step5/Chart.yaml new file mode 100644 index 0000000..5211678 --- /dev/null +++ b/helm-template-basic/assets/step5/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +name: step5 +type: application +version: 0.1.0 +dependencies: + - name: step2 + alias: steps2 + version: 0.1.0 + repository: file://../step2 diff --git a/helm-template-basic/assets/step5/policy/test.rego b/helm-template-basic/assets/step5/policy/test.rego new file mode 100644 index 0000000..5fe3e19 --- /dev/null +++ b/helm-template-basic/assets/step5/policy/test.rego @@ -0,0 +1,31 @@ +package main + +name = input.metadata.name +chart = input.metadata.annotations.chart +manifest = input[_] + +is_deployment { + input.kind = "Deployment" +} + +deny[msg] { + is_deployment + name = "nginx" + chart != "frontend" + msg = sprintf("Expected alias frontend for step 3 chart but found %s", [chart]) +} + +deny[msg] { + is_deployment + name = "nginx2" + chart != "backend" + msg = sprintf("Expected alias backend for step 4 chart but found %s", [chart]) +} + +deny[msg] { + is_deployment + name = "nginx2" + label := input.metadata.labels["app"] + label != "umbrella" + msg = sprintf("Expected value app.name of step4 chart to be equal to umbrella but found %s", [label]) +} diff --git a/helm-template-basic/assets/step5/templates/deployment.yaml b/helm-template-basic/assets/step5/templates/deployment.yaml new file mode 100644 index 0000000..02ea3b8 --- /dev/null +++ b/helm-template-basic/assets/step5/templates/deployment.yaml @@ -0,0 +1,6 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx3 + annotations: + chart: {{ default .Chart.Name .Values.nameOverride }} diff --git a/helm-template-basic/assets/step5/values.yaml b/helm-template-basic/assets/step5/values.yaml new file mode 100644 index 0000000..e69de29 diff --git a/helm-template-basic/background.sh b/helm-template-basic/background.sh new file mode 100644 index 0000000..0e758b2 --- /dev/null +++ b/helm-template-basic/background.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -x # to test stderr output in /var/log/killercoda + +echo starting... # to test stdout output in /var/log/killercoda + +sleep 3 # add some time to wait for IDE + +touch /tmp/finished diff --git a/helm-template-basic/foreground.sh b/helm-template-basic/foreground.sh new file mode 100644 index 0000000..61703ce --- /dev/null +++ b/helm-template-basic/foreground.sh @@ -0,0 +1,3 @@ +echo "waiting for IDE..." +while [ ! -f /tmp/finished ]; do sleep 1; done +echo DONE diff --git a/helm-template-basic/index.json b/helm-template-basic/index.json new file mode 100644 index 0000000..4c25b3d --- /dev/null +++ b/helm-template-basic/index.json @@ -0,0 +1,35 @@ +{ + "title": "Basic Helm Templating", + "description": "Train to work with helm templates", + "details": { + "intro": { + "text": "intro.md", + "foreground": "foreground.sh", + "background": "background.sh" + }, + "steps": [ + { + "title": "Install Helm", + "foreground": "step1/foreground.sh", + "text": "step1/instruction.md", + "verify": "step1/verify.sh" + }, + { + "title": "Umbrella Chart", + "text": "step5/instruction.md", + "verify": "step5/verify.sh" + } + ], + "assets": { + "host01": [ + {"file": "**", "target": "/app", "chmod": "+w"} + ] + } + }, + "backend": { + "imageid": "ubuntu" + }, + "interface": { + "layout": "ide" + } +} diff --git a/helm-template-basic/intro.md b/helm-template-basic/intro.md new file mode 100644 index 0000000..1258c16 --- /dev/null +++ b/helm-template-basic/intro.md @@ -0,0 +1,3 @@ +Helm template demo + +Please wait for IDE to finish loading before starting. diff --git a/helm-template-advanced/step1/foreground.sh b/helm-template-basic/step1/foreground.sh similarity index 100% rename from helm-template-advanced/step1/foreground.sh rename to helm-template-basic/step1/foreground.sh diff --git a/helm-template-advanced/step1/instruction.md b/helm-template-basic/step1/instruction.md similarity index 60% rename from helm-template-advanced/step1/instruction.md rename to helm-template-basic/step1/instruction.md index 13bffe8..132b033 100644 --- a/helm-template-advanced/step1/instruction.md +++ b/helm-template-basic/step1/instruction.md @@ -3,6 +3,12 @@ Check [Helm documentation](https://helm.sh/docs/intro/install/) to see how to install helm. In this scenario it's already done for you. +Install Helm plugin which will be used to verify scenarios. +``` +helm plugin install https://github.com/instrumenta/helm-conftest +```{{exec}} + ### Verify installation check helm version `helm version`{{exec}} + diff --git a/helm-template-basic/step1/verify.sh b/helm-template-basic/step1/verify.sh new file mode 100644 index 0000000..33684b8 --- /dev/null +++ b/helm-template-basic/step1/verify.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +command -v helm +helm plugin ls | grep "conftest" diff --git a/helm-template-basic/step2/instruction.md b/helm-template-basic/step2/instruction.md new file mode 100644 index 0000000..f4c5f5d --- /dev/null +++ b/helm-template-basic/step2/instruction.md @@ -0,0 +1,23 @@ +### Create Values Files + +First create a file values.yaml in chart directory. +`touch /app/step2/values.yaml`{{exec}} + +Add the key `name` with the value `fancy` to created file. + +You can read more in [official helm documentation](https://helm.sh/docs/chart_template_guide/values_files/) + +### Verify + +Move to helm chart dir. +`cd /app/step2`{{exec}} + +Check if you can render helm template correctly. +`helm template .`{{exec}} + +Check if you have passed the task. +`helm conftest .`{{exec}} + +See error and result log in +`cat /tmp/results.log`{{exec}} + diff --git a/helm-template-basic/step2/verify.sh b/helm-template-basic/step2/verify.sh new file mode 100644 index 0000000..0079cef --- /dev/null +++ b/helm-template-basic/step2/verify.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +rm -rf /tmp/results.log +cd /app/step2 +helm conftest . > /tmp/results.log 2>&1 diff --git a/helm-template-basic/step3/instruction.md b/helm-template-basic/step3/instruction.md new file mode 100644 index 0000000..02e22f7 --- /dev/null +++ b/helm-template-basic/step3/instruction.md @@ -0,0 +1,51 @@ +### Loops + +Fix the chart of step 3 `cd /app/step3`{{exec}} + +The goal is to add all labels defined in `customLabels` in `values.yaml` by using a loop. + +The result helm template should look like this: +```yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx + labels: + env: prod + team: dev +``` + +You can read more about control structures in [helm docu](https://helm.sh/docs/chart_template_guide/control_structures/#looping-with-the-range-action) + +You can loop over a list of values +```yaml +toppings: |- + {{- range .Values.pizzaToppings }} + - {{ . | title | quote }} + {{- end }} +``` +You can loop over a key-value map by +```yaml +toppings: |- + {{- range .Values.pizzaToppings }} + {{ .name }}: {{ .value }} + {{- end }} +``` +If you are inside the loop you are in the scope of the object. You have access to attributes with `.`{{}}. +But in order to reference other values, you need to prepend `$`{{}} e.g. `$.Values.otherValue`{{}} + +### Verify + +Move to helm chart dir. +`cd /app/step3`{{exec}} + +Check if you can render helm template correctly. +`helm template .`{{exec}} + +Check if you have passed the task. +`helm conftest .`{{exec}} + +See error and result log in +`cat /tmp/results.log`{{exec}} + diff --git a/helm-template-basic/step3/verify.sh b/helm-template-basic/step3/verify.sh new file mode 100644 index 0000000..f5fb1f3 --- /dev/null +++ b/helm-template-basic/step3/verify.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +rm -rf /tmp/results.log +cd /app/step3 +helm conftest . > /tmp/results.log 2>&1 diff --git a/helm-template-basic/step4/instruction.md b/helm-template-basic/step4/instruction.md new file mode 100644 index 0000000..ba9a8d5 --- /dev/null +++ b/helm-template-basic/step4/instruction.md @@ -0,0 +1,50 @@ +### Sprig function + +Helm used go template behind the scenes and supports sprig function within templates. +This is often quite handy to reduce line of codes e.g. when you need to base64 encode strings. +Get to know some sprig template functions. +* [overview](http://masterminds.github.io/sprig/) +* [string function needed for this example](http://masterminds.github.io/sprig/strings.html) + +One example of a simple chain of function is to quote a value +``` +pizza: {{ .Values.pizza | quote }} +``` + +### Your Task + +Fix the chart of step 4 `cd /app/step4`{{exec}} +Find suitable sprig function and chain them with values in `deplyoment.yaml` + +* **addon**: should remove the prefix `nginx-` and write all chars in Capital Letters +* **triple**: should repeat `.Values.app.name` three times + +see [helm docu for functions and pipelines](https://helm.sh/docs/chart_template_guide/functions_and_pipelines/) +**Hint** you can chain function with `|` + +The helm template result should look like this: +``` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx2 + labels: + app: nginx-trace-addon + addon: TRACE-ADDON + triple: nginx-trace-addonnginx-trace-addonnginx-trace-addon +``` + +### Verify + +Move to helm chart dir. +`cd /app/step4`{{exec}} + +Check if you can render helm template correctly. +`helm template .`{{exec}} + +Check if you have passed the task. +`helm conftest .`{{exec}} + +See error and result log in +`cat /tmp/results.log`{{exec}} + diff --git a/helm-template-basic/step4/verify.sh b/helm-template-basic/step4/verify.sh new file mode 100644 index 0000000..677297e --- /dev/null +++ b/helm-template-basic/step4/verify.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +rm -rf /tmp/results.log +cd /app/step4 +helm conftest . > /tmp/results.log 2>&1 diff --git a/helm-template-basic/step5/instruction.md b/helm-template-basic/step5/instruction.md new file mode 100644 index 0000000..c6b3b69 --- /dev/null +++ b/helm-template-basic/step5/instruction.md @@ -0,0 +1,50 @@ +### Umbrella Chart + +Typically, you have one application per helm chart. +[Umbrella Chart](https://v2.helm.sh/docs/developing_charts/#complex-charts-with-many-dependencies) can be used to compose multiple charts. +In such cases, a single umbrella chart may have multiple subcharts, each of which functions as a piece of the whole. + +### Add a chart dependency + +Fix the chart of step 5 `cd /app/step5`{{exec}} + +Chart dependencies can be added in `Chart.yaml` within key `dependencies`. +The chart of `step2` is already added. + * Add the other two previously created charts `step3` and `step4` as dependencies. + * Change the alias of step3 chart to `frontend` + * Change the alias of step4 chart to `backend` + +you need to initially build dependencies after your added them to `Chart.yaml`. +`helm dep build`{{exec}} +You can verify full template with +`helm template .`{{exec}} + +Now modify the `app.name` of chart `step4` in `/app/step5/values.yaml`. +Note when reference the chart you need to use the defined alias `backend`. + +```bash +cat < /app/step5/values.yaml +backend: + app: + name: umbrella +EOF +```{{exec}} + + +### Verify + +Move to helm chart dir. +`cd /app/step5`{{exec}} + +Check if you can render helm template correctly. +`helm template .`{{exec}} + +Check if you can helm dependencies were installed correctly. +`helm dep ls`{{exec}} + +Check if you have passed the task. +`helm conftest .`{{exec}} + +See error and result log in +`cat /tmp/results.log`{{exec}} + diff --git a/helm-template-basic/step5/verify.sh b/helm-template-basic/step5/verify.sh new file mode 100755 index 0000000..8545772 --- /dev/null +++ b/helm-template-basic/step5/verify.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -e +set -o pipefail + +rm -rf /tmp/results.log + +cd /app/step5 + +num=$(helm dep ls | wc -l) +expected=4 +if ((num <= expected)); then + helm dep ls >> /tmp/results.log + echo "expected 3 helm dependencies. You need to add the sub-charts to dependencies." >> /tmp/results.log + exit 1 +fi + +helm conftest . >> /tmp/results.log 2>&1 +