From ae138368b1b8faaf5428c797257cb4acc5ca844f Mon Sep 17 00:00:00 2001 From: Chris Oloff Date: Wed, 1 Jan 2025 13:24:16 +0200 Subject: [PATCH 01/10] add hello-world action as per https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-docker-container-action --- .hadolint.yaml | 2 ++ Dockerfile | 21 +++++++++++++++++++++ action.yml | 16 ++++++++++++++++ entrypoint.sh | 5 +++++ 4 files changed, 44 insertions(+) create mode 100644 .hadolint.yaml create mode 100644 Dockerfile create mode 100644 action.yml create mode 100755 entrypoint.sh diff --git a/.hadolint.yaml b/.hadolint.yaml new file mode 100644 index 0000000..8f7e23e --- /dev/null +++ b/.hadolint.yaml @@ -0,0 +1,2 @@ +ignored: + - DL3008 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b0a2add --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +# Container image that runs your code +FROM debian:12.8-slim + +# compare https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/ +RUN apt-get update && \ + export DEBIAN_FRONTEND=noninteractive && \ + apt-get install --no-install-recommends -y git nodejs gpg npm dnsutils \ + apt-transport-https ca-certificates curl gnupg # packages in this line required for kubectl && \ + curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg && \ + chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg && \ + echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.32/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list && \ + chmod 644 /etc/apt/sources.list.d/kubernetes.list # helps tools such as command-not-found to work correctly && \ + apt-get update && apt-get install -y kubectl && \ + apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# Copies your code file from your action repository to the filesystem path `/` of the container +COPY entrypoint.sh /entrypoint.sh + +# Code file to execute when the docker container starts up (`entrypoint.sh`) +ENTRYPOINT ["/entrypoint.sh"] + diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..25caa1f --- /dev/null +++ b/action.yml @@ -0,0 +1,16 @@ +# action.yml +name: "Hello World" +description: "Greet someone and record the time" +inputs: + who-to-greet: # id of input + description: "Who to greet" + required: true + default: "World" +outputs: + time: # id of output + description: "The time we greeted you" +runs: + using: "docker" + image: "Dockerfile" + args: + - ${{ inputs.who-to-greet }} diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..0d7874b --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,5 @@ +#!/bin/sh -l + +echo "Hello $1" +time=$(date) +echo "time=$time" >>"$GITHUB_OUTPUT" From 22ff2f2c04d335df928a3e7fd2abeaa20f00f2d5 Mon Sep 17 00:00:00 2001 From: Chris Oloff Date: Wed, 1 Jan 2025 14:18:42 +0200 Subject: [PATCH 02/10] add env debug output --- entrypoint.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/entrypoint.sh b/entrypoint.sh index 0d7874b..59e64e4 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -2,4 +2,5 @@ echo "Hello $1" time=$(date) +env echo "time=$time" >>"$GITHUB_OUTPUT" From 94931ef4e37996aef95511590d1ddbce55712db5 Mon Sep 17 00:00:00 2001 From: Chris Oloff Date: Wed, 1 Jan 2025 14:27:48 +0200 Subject: [PATCH 03/10] more debugging, why is output not coming through in next step --- entrypoint.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/entrypoint.sh b/entrypoint.sh index 59e64e4..ac39c74 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -2,5 +2,8 @@ echo "Hello $1" time=$(date) -env echo "time=$time" >>"$GITHUB_OUTPUT" +echo "env:" +env +echo "github output:" +cat "$GITHUB_OUTPUT" From 44a237aed4c3d8257478be266ebf38b7f3f0ad80 Mon Sep 17 00:00:00 2001 From: Chris Oloff Date: Wed, 1 Jan 2025 15:23:25 +0200 Subject: [PATCH 04/10] add calling kubectl etc to apply kustomizations and then deploy by applying the manifests --- entrypoint.sh | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/entrypoint.sh b/entrypoint.sh index ac39c74..d0fd436 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -7,3 +7,31 @@ echo "env:" env echo "github output:" cat "$GITHUB_OUTPUT" + +KUST_CONFIG=$1 + +echo "Going to apply kustomization configuration at ${KUST_CONFIG}" +echo "K3S_YAML:" +echo "$K3S_YAML" +echo "$K3S_YAML" | base64 -d >/tmp/k3s.yaml +chmod 600 /tmp/k3s.yaml +ls -lth /tmp/ +echo "K3S_YAML, deserialized:" +cat /tmp/k3s.yaml +cp -r ./kustomize /tmp/ # TODO: we expect the kustomize folder to be present in the root of the repository +find /tmp/kustomize -type f -print0 | xargs -0 sed -i "s/GIT_VERSION/${CI_COMMIT_SHA}/" +echo "try and get nodes and version... (debugging)" +kubectl --kubeconfig /tmp/k3s.yaml get all +kubectl --kubeconfig /tmp/k3s.yaml version +echo "determine kustomize version..." +KUSTOMIZE_VERSION=$(kubectl --kubeconfig /tmp/k3s.yaml version | grep Kustomize | awk '{ print $3 }') +echo "KUSTOMIZE_VERSION=${KUSTOMIZE_VERSION}" +echo "run kustomize, and print output to console" +kubectl --kubeconfig /tmp/k3s.yaml kustomize "/tmp/${KUST_CONFIG}" +echo "replace faulty kustomize version (compare https://github.com/kubernetes/kubectl/issues/1495)" +kubectl --kubeconfig /tmp/k3s.yaml kustomize "/tmp/${KUST_CONFIG}" | sed "s/kustomize-(devel)/kustomize-$KUSTOMIZE_VERSION/" >/tmp/manifests.yaml +echo "UPDATED YAML:" +cat /tmp/manifests.yaml +echo "applying..." +kubectl --kubeconfig /tmp/k3s.yaml apply -f - Date: Wed, 1 Jan 2025 16:02:44 +0200 Subject: [PATCH 05/10] fix confused 'apt install' command --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b0a2add..b3fa8b4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ RUN apt-get update && \ curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg && \ chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg && \ echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.32/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list && \ - chmod 644 /etc/apt/sources.list.d/kubernetes.list # helps tools such as command-not-found to work correctly && \ + chmod 644 /etc/apt/sources.list.d/kubernetes.list && \ apt-get update && apt-get install -y kubectl && \ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* From edcc936564f6a49319fd8bae1c94478332fde697 Mon Sep 17 00:00:00 2001 From: Chris Oloff Date: Wed, 1 Jan 2025 16:30:17 +0200 Subject: [PATCH 06/10] fix Dockerfile, tested locally --- Dockerfile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index b3fa8b4..1cd747d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,15 +2,19 @@ FROM debian:12.8-slim # compare https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/ + +# https://stackoverflow.com/a/69684246 +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + RUN apt-get update && \ export DEBIAN_FRONTEND=noninteractive && \ apt-get install --no-install-recommends -y git nodejs gpg npm dnsutils \ - apt-transport-https ca-certificates curl gnupg # packages in this line required for kubectl && \ + apt-transport-https ca-certificates curl gnupg && \ curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg && \ chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg && \ echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.32/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list && \ chmod 644 /etc/apt/sources.list.d/kubernetes.list && \ - apt-get update && apt-get install -y kubectl && \ + apt-get update && apt-get install -y --no-install-recommends kubectl && \ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # Copies your code file from your action repository to the filesystem path `/` of the container From e79d57928ad47eed08c5df03581856fffe11405e Mon Sep 17 00:00:00 2001 From: Chris Oloff Date: Wed, 1 Jan 2025 16:37:06 +0200 Subject: [PATCH 07/10] Update config to use properly named input param --- action.yml | 10 +++++----- entrypoint.sh | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/action.yml b/action.yml index 25caa1f..18cc0f3 100644 --- a/action.yml +++ b/action.yml @@ -2,15 +2,15 @@ name: "Hello World" description: "Greet someone and record the time" inputs: - who-to-greet: # id of input - description: "Who to greet" + kust_config: # id of input + description: "the kustomization configuration, e.g. kustomize/overlays/testing" required: true - default: "World" + default: "kustomize/overlays/testing" outputs: time: # id of output - description: "The time we greeted you" + description: "The time we started" runs: using: "docker" image: "Dockerfile" args: - - ${{ inputs.who-to-greet }} + - ${{ inputs.kust_config }} diff --git a/entrypoint.sh b/entrypoint.sh index d0fd436..12ce77a 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,6 +1,7 @@ #!/bin/sh -l -echo "Hello $1" +set -e # fail if any command fails + time=$(date) echo "time=$time" >>"$GITHUB_OUTPUT" echo "env:" From 6a94eb6279868fff0fec38e2be173a2163786c28 Mon Sep 17 00:00:00 2001 From: Chris Oloff Date: Wed, 1 Jan 2025 17:17:20 +0200 Subject: [PATCH 08/10] add error handling for missing input --- entrypoint.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/entrypoint.sh b/entrypoint.sh index 12ce77a..cb37ebf 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -11,6 +11,16 @@ cat "$GITHUB_OUTPUT" KUST_CONFIG=$1 +if [ -z "$KUST_CONFIG" ]; then + echo "KUST_CONFIG not defined, pass it in a 'with:' clause to the action" && exit 1 +fi +if [ -z "$K3S_YAML" ]; then + echo "K3S_YAML not defined, pass it in the environment with an 'env:' clause to the action" && exit 1 +fi +if [ -z "$GITHUB_SHA" ]; then + echo "GITHUB_SHA not defined, pass it in the environment with an 'env:' clause to the action" && exit 1 +fi + echo "Going to apply kustomization configuration at ${KUST_CONFIG}" echo "K3S_YAML:" echo "$K3S_YAML" @@ -20,7 +30,7 @@ ls -lth /tmp/ echo "K3S_YAML, deserialized:" cat /tmp/k3s.yaml cp -r ./kustomize /tmp/ # TODO: we expect the kustomize folder to be present in the root of the repository -find /tmp/kustomize -type f -print0 | xargs -0 sed -i "s/GIT_VERSION/${CI_COMMIT_SHA}/" +find /tmp/kustomize -type f -print0 | xargs -0 sed -i "s/GIT_VERSION/${GITHUB_SHA}/" echo "try and get nodes and version... (debugging)" kubectl --kubeconfig /tmp/k3s.yaml get all kubectl --kubeconfig /tmp/k3s.yaml version From b305152e9fb91b6fb7e9d6c339aa5042e62e3b42 Mon Sep 17 00:00:00 2001 From: Chris Oloff Date: Wed, 1 Jan 2025 17:26:31 +0200 Subject: [PATCH 09/10] cleanup, add docs --- README.md | 23 ++++++++++++++++++++--- entrypoint.sh | 10 +++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 748de93..d6739bf 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,23 @@ This is a [Github Action](https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-docker-container-action) using Docker, with the intention to efficiently deploy to a k3s or k8s cluster using kustomize. +# How to Use + +```yaml +jobs: + deploy_staging: + steps: + - name: deploy to staging + id: deploy + uses: https://gitea.uber5.com/Uber5-Public/gha-deploy-to-k3s@v2 + with: + kust_config: kustomize/overlays/testing + env: + K3S_YAML: ${{ secrets.K3S_YAML }} + - name: Check output of previous step (kinda dummy) + run: echo "The start time was ${{ steps.deploy.outputs.time }}" +``` + # Open Questions - We use [kustomize](https://kustomize.io/). Is this overkill? As the complexity of deployments is not that high, usually, this may be more technical complexity than necessary. We could go back to using plain kubernetes manifests, and just have different ones for staging and prod. @@ -10,6 +27,6 @@ using Docker, with the intention to efficiently deploy to a k3s or k8s cluster u - Advantages Github Actions: - execution time should be faster - it's closer to the mainstream - - Advantages Woodpecker: - - Current deployments use woodpecker already - - Simpler technology (This is debatable) \ No newline at end of file + - Advantages Woodpecker: + - Current deployments use woodpecker already + - Simpler technology (This is debatable) diff --git a/entrypoint.sh b/entrypoint.sh index cb37ebf..081d428 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -31,14 +31,14 @@ echo "K3S_YAML, deserialized:" cat /tmp/k3s.yaml cp -r ./kustomize /tmp/ # TODO: we expect the kustomize folder to be present in the root of the repository find /tmp/kustomize -type f -print0 | xargs -0 sed -i "s/GIT_VERSION/${GITHUB_SHA}/" -echo "try and get nodes and version... (debugging)" -kubectl --kubeconfig /tmp/k3s.yaml get all -kubectl --kubeconfig /tmp/k3s.yaml version +# echo "try and get nodes and version... (debugging)" +# kubectl --kubeconfig /tmp/k3s.yaml get all +# kubectl --kubeconfig /tmp/k3s.yaml version echo "determine kustomize version..." KUSTOMIZE_VERSION=$(kubectl --kubeconfig /tmp/k3s.yaml version | grep Kustomize | awk '{ print $3 }') echo "KUSTOMIZE_VERSION=${KUSTOMIZE_VERSION}" -echo "run kustomize, and print output to console" -kubectl --kubeconfig /tmp/k3s.yaml kustomize "/tmp/${KUST_CONFIG}" +# echo "run kustomize, and print output to console" +# kubectl --kubeconfig /tmp/k3s.yaml kustomize "/tmp/${KUST_CONFIG}" echo "replace faulty kustomize version (compare https://github.com/kubernetes/kubectl/issues/1495)" kubectl --kubeconfig /tmp/k3s.yaml kustomize "/tmp/${KUST_CONFIG}" | sed "s/kustomize-(devel)/kustomize-$KUSTOMIZE_VERSION/" >/tmp/manifests.yaml echo "UPDATED YAML:" From 72d570731d0f2306f522111c25e11866d107cf1e Mon Sep 17 00:00:00 2001 From: Chris Oloff Date: Wed, 1 Jan 2025 17:35:32 +0200 Subject: [PATCH 10/10] update README --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d6739bf..1359fa1 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ using Docker, with the intention to efficiently deploy to a k3s or k8s cluster u # How to Use +## How to Configure in .github/workflows/main.yaml + ```yaml jobs: deploy_staging: @@ -15,11 +17,20 @@ jobs: with: kust_config: kustomize/overlays/testing env: - K3S_YAML: ${{ secrets.K3S_YAML }} + K3S_YAML: ${{ secrets.K3S_YAML }} # assuming that K3S_YAML is defined in a README, see also below - name: Check output of previous step (kinda dummy) run: echo "The start time was ${{ steps.deploy.outputs.time }}" ``` +## How to Setup K3S_YAML + +We assume you use k3s. Otherwise, use comparable kubectl configuration. + +- Grab k3s.yaml (\`/etc/rancher/k3s/k3s.yaml\`), copy it to /tmp/ and make it readable for you, then copy it from the master node of the k3s cluster: `scp your-node-123.uber5.com:/tmp/k3s.yaml /tmp/` +- Change the `server` entry to use its public DNS name +- Insert `tls-server-name: worker1` underneath the `server` key. The value (`worker1` in this case) needs to be one of the names that are in the cert. If you get it wrong, the error message in the pipeline will tell you. +- encode k3s.yaml with `base64 -i /tmp/k3s.yaml -o /tmp/encoded`, and set it as the value for a secret `K3S_YAML` in gitea for the repository under "Settings > Actions > Secrets" + # Open Questions - We use [kustomize](https://kustomize.io/). Is this overkill? As the complexity of deployments is not that high, usually, this may be more technical complexity than necessary. We could go back to using plain kubernetes manifests, and just have different ones for staging and prod.