Skip to content

Commit

Permalink
Update examples for Argo CD v0.11
Browse files Browse the repository at this point in the history
  • Loading branch information
jessesuen committed Dec 8, 2018
1 parent 62c4539 commit 382b858
Show file tree
Hide file tree
Showing 62 changed files with 287 additions and 150 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ to explore ArgoCD and GitOps!

| Application | Description |
|-------------|-------------|
| [guestbook](guestbook/) | A hello word application |
| [guestbook](guestbook/) | A hello word guestbook application as plain YAML |
| [ksonnet-guestbook](ksonnet-guestbook/) | The guestbook application as a ksonnet app |
| [helm-guestbook](helm-guestbook/) | The guestbook application as a Helm chart |
| [jsonnet-guestbook](jsonnet-guestbook/) | The guestbook application as a raw jsonnet |
| [kustomize-guestbook](kustomize-guestbook/) | The guestbook application as a kustomize app |
| [pre-post-sync](pre-post-sync/) | Demonstrates ArgoCD PreSync and PostSync hooks |
| [blue-green-deploy](blue-green-deploy/) | Demonstrates an ArgoCD Sync hook which performs a blue/green deployment |
| [pre-post-sync](pre-post-sync/) | Demonstrates Argo CD PreSync and PostSync hooks |
| [blue-green-deploy](blue-green-deploy/) | Demonstrates an Argo CD Sync hook which performs a blue/green deployment |
| [blue-green-deploy-workflow](blue-green-deploy-workflow/) | Demonstrates an ArgoCD Sync hook which performs a blue/green deployment as an Argo Workflow |
| [sock-shop](sock-shop/) | A microservices demo application (https://microservices-demo.github.io) |
File renamed without changes.
2 changes: 1 addition & 1 deletion sock-shop/app.yaml → blue-green-deploy-workflow/app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ environments:
k8sVersion: v1.10.0
path: default
kind: ksonnet.io/app
name: sock-shop
name: blue-green-deploy-workflow
version: 0.0.1
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
local env = std.extVar("__ksonnet/environments");
local params = std.extVar("__ksonnet/params").components["guestbook-ui"];
local params = std.extVar("__ksonnet/params").components["bg-guestbook"];
[
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": params.name
"name": params.name,
"annotations": {
"argocd.argoproj.io/hook": "Skip",
},
},
"spec": {
"ports": [
Expand All @@ -24,7 +27,10 @@ local params = std.extVar("__ksonnet/params").components["guestbook-ui"];
"apiVersion": "apps/v1beta2",
"kind": "Deployment",
"metadata": {
"name": params.name
"name": params.name,
"annotations": {
"argocd.argoproj.io/hook": "Skip",
},
},
"spec": {
"replicas": params.replicas,
Expand All @@ -42,21 +48,13 @@ local params = std.extVar("__ksonnet/params").components["guestbook-ui"];
"spec": {
"containers": [
{
"image": params.image,
"name": params.name,
"ports": [
"image": params.image,
"name": params.name,
"ports": [
{
"containerPort": params.containerPort
}
],
// dummy readiness probe to slow down the rollout for demo/testing
"readinessProbe": {
"exec": {
"command": [ "sh", "-c", "exit 0" ],
},
"initialDelaySeconds": 10,
"periodSeconds": 30,
}
]
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
components: {
// Component-level parameters, defined initially from 'ks prototype use ...'
// Each object below should correspond to a component in the components/ directory
"guestbook-ui": {
"bg-guestbook": {
containerPort: 80,
image: "gcr.io/heptio-images/ks-guestbook-demo:0.2",
name: "pre-post-sync",
replicas: 1,
name: "bg-guestbook",
replicas: 3,
servicePort: 80,
type: "ClusterIP",
type: "LoadBalancer",
},
"pre-sync-job": {},
"post-sync-job": {},
"bg-workflow": {},
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ spec:
args:
- kubectl get --export -o json deployment.apps/{{workflow.parameters.deployment-name}} > /original-deploy &&
jq -r '.metadata.name+="-blue" |
.spec.template.metadata.labels += (.spec.template.metadata.labels | to_entries | map(select(.key != "applications.argoproj.io/app-name")) | map(.value+="-blue") | from_entries) |
.spec.selector.matchLabels += (.spec.selector.matchLabels | to_entries | map(select(.key != "applications.argoproj.io/app-name")) | map(.value+="-blue") | from_entries)'
.spec.template.metadata.labels += (.spec.template.metadata.labels | to_entries | map(select(.key != "app.kubernetes.io/instance")) | map(.value+="-blue") | from_entries) |
.spec.selector.matchLabels += (.spec.selector.matchLabels | to_entries | map(select(.key != "app.kubernetes.io/instance")) | map(.value+="-blue") | from_entries)'
/original-deploy > /cloned-deploy &&
cat /cloned-deploy &&
kubectl apply -o yaml -f /cloned-deploy
Expand All @@ -103,12 +103,12 @@ spec:
command: [sh, -c, -x]
args:
- cp /manifest /manifest-new &&
APP_NAME=$(kubectl get -n default -f /manifest-new -o json | jq -r '.metadata.labels."applications.argoproj.io/app-name"') &&
APP_NAME=$(kubectl get -f /manifest-new -o json | jq -r '.metadata.labels."app.kubernetes.io/instance"') &&
if [ "$APP_NAME" != "null" ]; then
jq -r --arg APP_NAME "$APP_NAME" '.metadata.labels."applications.argoproj.io/app-name" = $APP_NAME' /manifest-new > /manifest-new.tmp &&
jq -r --arg APP_NAME "$APP_NAME" '.metadata.labels."app.kubernetes.io/instance" = $APP_NAME' /manifest-new > /manifest-new.tmp &&
mv /manifest-new.tmp /manifest-new &&
if [ "$(jq -r .spec.template.metadata.labels /manifest-new)" != "null" ]; then
jq -r --arg APP_NAME "$APP_NAME" '.spec.template.metadata.labels."applications.argoproj.io/app-name" = $APP_NAME' /manifest-new > /manifest-new.tmp &&
jq -r --arg APP_NAME "$APP_NAME" '.spec.template.metadata.labels."app.kubernetes.io/instance" = $APP_NAME' /manifest-new > /manifest-new.tmp &&
mv /manifest-new.tmp /manifest-new ;
fi ;
fi &&
Expand All @@ -131,7 +131,7 @@ spec:
image: argoproj/argoexec:v2.1.1
command: [sh, -c, -x]
args:
- kubectl get -n default service {{workflow.parameters.service-name}} --export -o json > /original-svc &&
- kubectl get service {{workflow.parameters.service-name}} --export -o json > /original-svc &&
jq '.spec.selector = (.spec.selector | with_entries(.value+="-blue"))' /original-svc > /blue-svc &&
kubectl apply -o yaml -f /blue-svc

Expand Down
File renamed without changes.
8 changes: 6 additions & 2 deletions blue-green-deploy/app.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
apiVersion: 0.1.0
apiVersion: 0.3.0
environments:
default:
destination:
namespace: default
namespace: blue-green-deploy
server: https://kubernetes.default.svc
k8sVersion: v1.10.0
path: default
kind: ksonnet.io/app
name: blue-green-deploy
registries:
incubator:
protocol: github
uri: github.com/ksonnet/parts/tree/master/incubator
version: 0.0.1
71 changes: 71 additions & 0 deletions blue-green-deploy/blue-green.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!bin/bash

DEPLOYMENT_NAME=$(echo "${DEPLOY_MANIFEST}" | jq -r '.metadata.name')
SERVICE_NAME=$(echo "${SERVICE_MANIFEST}" | jq -r '.metadata.name')

# 1. Check if the deployment exists. If it doesn't exist, this is the initial deployment and we
# can simply deploy without blue-green. Add the app label using jq
out=$(kubectl get --export -o json deployment.apps/${DEPLOYMENT_NAME} 2>&1)
if [ $? -ne 0 ]; then
if [[ "${out}" =~ "NotFound" ]] ; then
echo "Initial deployment"
echo ${DEPLOY_MANIFEST} | \
jq ".metadata.labels += {\"app.kubernetes.io/instance\": \"${APPNAME}\"}" | \
kubectl apply -o yaml -f - || exit 1
echo ${SERVICE_MANIFEST} | \
jq ".metadata.labels += {\"app.kubernetes.io/instance\": \"${APPNAME}\"}" | \
kubectl apply -o yaml -f - || exit 1
exit 0
fi
echo "Failed to get deployment: ${out}"
exit 1
fi
ORIGINAL_DEPLOY_MANIFEST=$out

# 2. Clone the original, running deployment to a temporary deployment, with tweaks to its name and
# selectors. The jq command carries over all labels and selectors and appends the `-temp` suffix.
TMP_DEPLOYMENT_NAME="${DEPLOYMENT_NAME}-temp"
echo ${ORIGINAL_DEPLOY_MANIFEST} | jq -r '.metadata.name+="-temp" |
.spec.template.metadata.labels += (.spec.template.metadata.labels | to_entries | map(.value+="-temp") | from_entries) |
.spec.selector.matchLabels += (.spec.selector.matchLabels | to_entries | map(.value+="-temp") | from_entries)' |
kubectl apply -f -

# 3. Wait for cloned deployment to become ready.
sleep 2
echo "Waiting for successful rollout of new (temporary) deployment"
kubectl rollout status --watch=true deployments.apps/${TMP_DEPLOYMENT_NAME} || exit 1
echo "Rollout of temporary deployment successful"

# 4. Patch the service object such that all traffic is redirected to the cloned, temporary
# deployment. After this step, the original deployment will no longer be receiving traffic.
kubectl get service ${SERVICE_NAME} --export -o json | \
jq '.spec.selector = (.spec.selector | with_entries(.value+="-temp"))' |
kubectl apply -f - || exit 1
sleep 5 # Sleep slightly to allow iptables to get propagated to all nodes in the cluster

# 5. Update the original deployment (now receiving no traffic) with the new manifest
echo "Updating original deployment"
echo ${DEPLOY_MANIFEST} | \
jq ".metadata.labels += {\"app.kubernetes.io/instance\": \"${APPNAME}\"}" | \
kubectl apply -f - || exit 1

# 6. Wait for the new deployment to become complete
sleep 2
echo "Waiting for successful rollout of new deployment"
kubectl rollout status --watch=true deployments.apps/${DEPLOYMENT_NAME} || exit 1
echo "Rollout of new deployment successful"

# dummy wait step for demo purposes
echo "sleeping for 30 seconds"
sleep 30

# 7. Apply the new service object. Traffic will be redirected to the new version of the deployment
echo "Updating original service object"
echo ${SERVICE_MANIFEST} | \
jq ".metadata.labels += {\"app.kubernetes.io/instance\": \"${APPNAME}\"}" | \
kubectl apply -f - || exit 1

sleep 10
# 8. Remove the cloned deployment, which is no longer receiving any traffic
echo "Deleting ephemeral deployment"
kubectl delete deployments/${TMP_DEPLOYMENT_NAME} --ignore-not-found=true || exit 1
6 changes: 3 additions & 3 deletions blue-green-deploy/components/bg-guestbook.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ local params = std.extVar("__ksonnet/params").components["bg-guestbook"];
"image": params.image,
"name": params.name,
"ports": [
{
"containerPort": params.containerPort
}
{
"containerPort": params.containerPort
}
]
}
]
Expand Down
131 changes: 131 additions & 0 deletions blue-green-deploy/components/bg-pod.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
local bgGuestbook = std.extVar("__ksonnet/components")["bg-guestbook"];
local bgGuestbookSvc = bgGuestbook[0];
local bgGuestbookDeploy = bgGuestbook[1];

[
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"generateName": "blue-green-",
"annotations": {
"argocd.argoproj.io/hook": "Sync",
"deploy-manifest": std.manifestJson(bgGuestbookDeploy),
"svc-manifest": std.manifestJson(bgGuestbookSvc),
},
},
"spec": {
"serviceAccountName": "blue-green-sa",
"restartPolicy": "Never",
"containers": [
{
"name": "blue-green",
"image": "argoproj/argoexec:latest",
"command": ["bash", "-c"],
"args": ["
curl -L -o /usr/local/bin/kubectl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl &&
chmod +x /usr/local/bin/kubectl &&
curl -sSL -o /usr/local/bin/blue-green.sh https://raw.githubusercontent.com/argoproj/argocd-example-apps/master/blue-green-deploy/blue-green.sh &&
chmod +x /usr/local/bin/blue-green.sh &&
blue-green.sh
"],
"env": [
{
"name": "DEPLOY_MANIFEST",
"valueFrom": {
"fieldRef": {
"fieldPath": "metadata.annotations['deploy-manifest']"
}
}
},
{
"name": "SERVICE_MANIFEST",
"valueFrom": {
"fieldRef": {
"fieldPath": "metadata.annotations['svc-manifest']"
}
}
},
// NOTE: app.kubernetes.io/instance will get injected into the hook object
{
"name": "APPNAME",
"valueFrom": {
"fieldRef": {
"fieldPath": "metadata.labels['app.kubernetes.io/instance']"
}
}
}
]
}
],
}
},
// RBAC to allow the blue-green pod privileges to manipulate deployments and services
{
"apiVersion": "v1",
"kind": "ServiceAccount",
"metadata": {
"name": "blue-green-sa"
}
},
{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "Role",
"metadata": {
"name": "blue-green-role"
},
"rules": [
{
"apiGroups": [
"apps",
"extensions"
],
"resources": [
"deployments",
],
"verbs": [
"list",
"get",
"create",
"update",
"patch",
"delete",
]
},
{
"apiGroups": [
""
],
"resources": [
"services"
],
"verbs": [
"list",
"get",
"create",
"update",
"patch",
"delete",
]
}
]
},
{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "RoleBinding",
"metadata": {
"name": "blue-green-rolebinding"
},
"roleRef": {
"apiGroup": "rbac.authorization.k8s.io",
"kind": "Role",
"name": "blue-green-role"
},
"subjects": [
{
"kind": "ServiceAccount",
"name": "blue-green-sa"
}
]
}
]
4 changes: 2 additions & 2 deletions blue-green-deploy/components/params.libsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
"bg-guestbook": {
containerPort: 80,
image: "gcr.io/heptio-images/ks-guestbook-demo:0.2",
name: "bg-guestbook",
name: "blue-green-guestbook",
replicas: 3,
servicePort: 80,
type: "LoadBalancer",
},
"bg-workflow": {},
"bg-pod": {},
},
}
3 changes: 2 additions & 1 deletion blue-green-deploy/environments/default/main.jsonnet
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
local base = import "base.libsonnet";
// uncomment if you reference ksonnet-lib
// local k = import "k.libsonnet";
// local deployment = k.apps.v1beta2.deployment;

base + {
// Insert user-specified overrides here. For example if a component is named \"nginx-deployment\", you might have something like:\n")
// "nginx-deployment"+: k.deployment.mixin.metadata.labels({foo: "bar"})
// "nginx-deployment"+: deployment.mixin.metadata.withLabels({foo: "bar"})
}
Loading

0 comments on commit 382b858

Please sign in to comment.