Generalize deploy scripts to work w/ both production and staging

Max Brunsfeld and Nathan Sobo created

Co-Authored-By: Nathan Sobo <nathan@zed.dev>

Change summary

script/deploy                         | 32 ++++++++++++++++++----
script/deploy-migration               | 41 +++++++++++++++++++++++++---
server/k8s/environments/production.sh |  1 
server/k8s/environments/staging.sh    |  1 
server/k8s/manifest.template.yml      | 11 ++++++-
server/k8s/migrate.template.yml       | 18 ++++++++++++
server/migrate.yml                    | 17 ------------
7 files changed, 91 insertions(+), 30 deletions(-)

Detailed changes

script/deploy 🔗

@@ -5,13 +5,33 @@
 # - Log in to the DigitalOcean docker registry
 #   doctl registry login
 #
-# - Set the default K8s context to production
+# - Target the `zed-1` kubernetes cluster
 #   doctl kubernetes cluster kubeconfig save zed-1
 
-set -e
+set -eu
 
-IMAGE_ID=registry.digitalocean.com/zed/zed-server
+if [[ $# < 1 ]]; then
+  echo "Usage: $0 [production|staging|...]"
+  exit 1
+fi
 
-docker build . --tag $IMAGE_ID
-docker push $IMAGE_ID
-kubectl rollout restart deployment zed
+export ZED_KUBE_NAMESPACE=$1
+ENV_FILE="server/k8s/environments/${ZED_KUBE_NAMESPACE}.sh"
+if [[ ! -f $ENV_FILE ]]; then
+  echo "Invalid environment name '${ZED_KUBE_NAMESPACE}'"
+  exit 1
+fi
+
+if [[ -n $(git status --short) ]]; then
+  echo "Cannot deploy with uncommited changes"
+  exit 1
+fi
+
+git_sha=$(git rev-parse HEAD)
+export ZED_IMAGE_ID=registry.digitalocean.com/zed/zed-server:${ZED_KUBE_NAMESPACE}-${git_sha}
+export $(cat $ENV_FILE)
+
+docker build . --tag $ZED_IMAGE_ID
+docker push $ZED_IMAGE_ID
+
+envsubst < server/k8s/manifest.template.yml | kubectl apply -f -

script/deploy-migration 🔗

@@ -1,11 +1,42 @@
 #!/bin/bash
 
-set -e
+# Prerequisites:
+#
+# - Log in to the DigitalOcean docker registry
+#   doctl registry login
+#
+# - Target the `zed-1` kubernetes cluster
+#   doctl kubernetes cluster kubeconfig save zed-1
 
-IMAGE_ID=registry.digitalocean.com/zed/zed-migrator
+set -eu
+
+if [[ $# < 1 ]]; then
+  echo "Usage: $0 [production|staging|...]"
+  exit 1
+fi
+
+export ZED_KUBE_NAMESPACE=$1
+ENV_FILE="server/k8s/environments/${ZED_KUBE_NAMESPACE}.sh"
+if [[ ! -f $ENV_FILE ]]; then
+  echo "Invalid environment name '${ZED_KUBE_NAMESPACE}'"
+  exit 1
+fi
+
+if [[ -n $(git status --short) ]]; then
+  echo "Cannot deploy with uncommited changes"
+  exit 1
+fi
+
+git_sha=$(git rev-parse HEAD)
+export ZED_IMAGE_ID=registry.digitalocean.com/zed/zed-migrator:${ZED_KUBE_NAMESPACE}-${git_sha}
+export ZED_MIGRATE_JOB_NAME=zed-migrate-${git_sha}
 
 docker build . \
   --file ./Dockerfile.migrator \
-  --tag $IMAGE_ID
-docker push $IMAGE_ID
-kubectl apply -f ./server/migrate.yml
+  --tag $ZED_IMAGE_ID
+docker push $ZED_IMAGE_ID
+
+envsubst < server/k8s/migrate.template.yml | kubectl apply -f -
+
+pod=$(kubectl --namespace=${ZED_KUBE_NAMESPACE} get pods --selector=job-name=${ZED_MIGRATE_JOB_NAME} --output=jsonpath='{.items[*].metadata.name}')
+echo "pod:" $pod

server/manifest.yml → server/k8s/manifest.template.yml 🔗

@@ -1,11 +1,17 @@
 ---
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: ${ZED_KUBE_NAMESPACE}
+---
 kind: Service
 apiVersion: v1
 metadata:
+  namespace: ${ZED_KUBE_NAMESPACE}
   name: zed
   annotations:
     service.beta.kubernetes.io/do-loadbalancer-tls-ports: "443"
-    service.beta.kubernetes.io/do-loadbalancer-certificate-id: "606e2db9-2b58-4ae7-b12c-a0c7d56af49b"
+    service.beta.kubernetes.io/do-loadbalancer-certificate-id: "${ZED_LOAD_BALANCER_CERT_ID}"
 spec:
   type: LoadBalancer
   selector:
@@ -19,6 +25,7 @@ spec:
 apiVersion: apps/v1
 kind: Deployment
 metadata:
+  namespace: ${ZED_KUBE_NAMESPACE}
   name: zed
 spec:
   replicas: 1
@@ -32,7 +39,7 @@ spec:
     spec:
       containers:
         - name: zed
-          image: registry.digitalocean.com/zed/zed-server
+          image: "${ZED_IMAGE_ID}"
           ports:
             - containerPort: 8080
               protocol: TCP

server/k8s/migrate.template.yml 🔗

@@ -0,0 +1,18 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+  namespace: ${ZED_KUBE_NAMESPACE}
+  name: ${ZED_MIGRATE_JOB_NAME}
+spec:
+  template:
+    spec:
+      restartPolicy: Never
+      containers:
+        - name: migrator
+          image: ${ZED_IMAGE_ID}
+          env:
+            - name: DATABASE_URL
+              valueFrom:
+                secretKeyRef:
+                  name: database
+                  key: url

server/migrate.yml 🔗

@@ -1,17 +0,0 @@
-apiVersion: batch/v1
-kind: Job
-metadata:
-  name: migrate
-spec:
-  template:
-    spec:
-      restartPolicy: Never
-      containers:
-      - name: migrator
-        image: registry.digitalocean.com/zed/zed-migrator
-        env:
-          - name: DATABASE_URL
-            valueFrom:
-              secretKeyRef:
-                name: database
-                key: url