DEV Community

Niklas Merz
Niklas Merz

Posted on • Originally published at blog.merzlabs.com on

2 1

Deploy to Kubernetes with Github Actions

Deploy to Kubernetes with Github Actions v0

Github Actions is now in limited public beta and while trying it out for deploying to Kubernetes, I built this workflow:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: myproject
name: myproject
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: myproject
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: myproject
spec:
containers:
image: eu.gcr.io/PROJECT_ID/APPLICATION_NAME:TAG
imagePullPolicy: Always
name: ponycar
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
view raw deployment.yaml hosted with ❤ by GitHub
workflow "Build and deploy" {
on = "push"
resolves = [
"notify on deploy",
]
}
action "build image" {
uses = "actions/docker/cli@76ff57a"
args = "build -t myproject ."
}
action "tag image gcloud" {
uses = "actions/docker/tag@76ff57a"
args = ["myproject", "eu.gcr.io/$PROJECT_ID/$APPLICATION_NAME"]
env = {
PROJECT_ID = "myproject-220562"
APPLICATION_NAME = "myproject"
}
needs = ["build image"]
}
action "gcloud auth" {
uses = "actions/gcloud/auth@8ec8bfa"
secrets = ["GCLOUD_AUTH"]
}
action "load docker credentials" {
uses = "actions/gcloud/cli@8ec8bfa"
args = ["auth", "configure-docker", "--quiet"]
needs = ["gcloud auth"]
}
action "push to GCR" {
needs = ["load docker credentials", "tag image gcloud"]
uses = "actions/gcloud/cli@master"
runs = "sh -c"
env = {
PROJECT_ID = "myproject-220562"
APPLICATION_NAME = "myproject"
}
args = ["docker push eu.gcr.io/$PROJECT_ID/$APPLICATION_NAME"]
}
action "load GKE kube credentials" {
uses = "actions/gcloud/cli@8ec8bfa"
args = "container clusters get-credentials myproject --zone europe-west3-a --project myproject-220562"
needs = ["gcloud auth"]
}
action "deploy to GKE" {
needs = ["push to GCR", "load GKE kube credentials"]
uses = "docker://gcr.io/cloud-builders/kubectl"
env = {
PROJECT_ID = "myproject-220562"
APPLICATION_NAME = "myproject"
DEPLOYMENT_NAME = "myproject"
}
runs = "sh -l -c"
args = ["SHORT_REF=$(echo ${GITHUB_SHA} | head -c7) && cat $GITHUB_WORKSPACE/Kubernetes/deployment.yaml | sed 's/PROJECT_ID/'\"$PROJECT_ID\"'/' | sed 's/APPLICATION_NAME/'\"$APPLICATION_NAME\"'/' | sed 's/TAG/'\"$SHORT_REF\"'/' | kubectl apply -f - "]
}
action "verify GKE deployment" {
needs = ["deploy to GKE"]
uses = "docker://gcr.io/cloud-builders/kubectl"
env = {
DEPLOYMENT_NAME = "myproject"
}
args = "rollout status deployment/myproject"
}
action "notify on deploy" {
uses = "niklasmerz/bin/curl@curl"
needs = ["verify GKE deployment"]
secrets = ["SLACK_HOOK"]
args = ["-X", "POST", "--data-urlencode", "\"payload={\\\"channel\\\": \\\"#myproject\\\", \\\"username\\\": \\\"myproject-deployments\\\", \\\"text\\\": \\\"Deployment ready\\\", \\\"icon_emoji\\\": \\\":alarm_clock:\\\"}\"", "$SLACK_HOOK"]
}
view raw main.workflow hosted with ❤ by GitHub

Lets go through it. This is workflow is based on the gcloud example action with my first own action which notifies me on Slack when the workflow is finished.

The first step is building my Dockerfile, I mentioned earlier and simultaneously logging into Google Cloud. I am running my Kubernetes Cluster on Google Cloud and using the Google Cloud Container Registry for my images. The image then gets tagged with the convenient tag action and pushed to the registry. Now I have image tagged with the branchname, short Git hash and the latest tag available.

The deploy to GKE action now uses the tag with the Git SHA and replaces the placeholders in my deployment file and applies it to the cluster.

After that the deployment gets verified and a Slack hook gets triggered to notify about the end of the workflow. The Slack hook is just a curl command to the URL I got from the Slack integration “Incomming webhooks”.

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay