Skip to content
Docs

Workflow Examples

Overview

This page provides complete, production-ready workflow examples that you can use as templates for your own deployment pipelines.

Basic Workflows

Simple Deployment

A basic deployment workflow for Kubernetes applications:

apiVersion: v1
kind: Workflow
metadata:
name: simple-deploy
description: Basic application deployment
spec:
env:
APP_NAME: my-app
NAMESPACE: default
jobs:
- name: deploy
description: Deploy application
steps:
- name: apply-manifests
command: kubectl apply -f manifests/
- name: wait-for-rollout
command: kubectl rollout status deployment/${APP_NAME} -n ${NAMESPACE}
- name: verify
command: kubectl get pods -n ${NAMESPACE} -l app=${APP_NAME}

Configuration Update

Update application configuration:

apiVersion: v1
kind: Workflow
metadata:
name: update-config
description: Update application configuration
spec:
env:
APP_NAME: my-app
NAMESPACE: default
jobs:
- name: update
steps:
- name: update-configmap
command: kubectl create configmap ${APP_NAME}-config --from-file=config/ -n ${NAMESPACE} --dry-run=client -o yaml | kubectl apply -f -
- name: restart-deployment
command: kubectl rollout restart deployment/${APP_NAME} -n ${NAMESPACE}
- name: wait
command: kubectl rollout status deployment/${APP_NAME} -n ${NAMESPACE}

Docker Workflows

Build and Push

Build Docker image with validation:

apiVersion: v1
kind: Workflow
metadata:
name: docker-build
description: Build and push Docker images
spec:
requirements:
tools:
- name: docker
version: "20.10"
description: Docker CLI for building images
secrets:
- name: DOCKER_TOKEN
provider: docker
required: true
description: Docker Hub authentication token
env:
IMAGE_NAME: my-app
IMAGE_TAG: latest
REGISTRY: docker.io
REGISTRY_USER: myuser
jobs:
- name: build
description: Build Docker image
steps:
- name: docker-build
script: |
docker build \
-t ${REGISTRY}/${REGISTRY_USER}/${IMAGE_NAME}:${IMAGE_TAG} \
-t ${REGISTRY}/${REGISTRY_USER}/${IMAGE_NAME}:$(git rev-parse --short HEAD) \
.
echo "✅ Build complete"
- name: push
description: Push to registry
dependsOn: [build]
steps:
- name: docker-login
script: |
echo "$DOCKER_TOKEN" | docker login ${REGISTRY} -u ${REGISTRY_USER} --password-stdin
- name: docker-push
script: |
docker push ${REGISTRY}/${REGISTRY_USER}/${IMAGE_NAME}:${IMAGE_TAG}
docker push ${REGISTRY}/${REGISTRY_USER}/${IMAGE_NAME}:$(git rev-parse --short HEAD)
echo "✅ Push complete"

Multi-Architecture Build

Build for multiple architectures:

apiVersion: v1
kind: Workflow
metadata:
name: docker-multi-arch
description: Build multi-architecture Docker images
spec:
requirements:
tools:
- name: docker
version: "20.10"
- name: buildx
description: Docker Buildx for multi-platform builds
secrets:
- name: DOCKER_TOKEN
provider: docker
required: true
env:
IMAGE_NAME: my-app
VERSION: "1.0.0"
PLATFORMS: "linux/amd64,linux/arm64,linux/arm/v7"
jobs:
- name: setup
steps:
- name: create-builder
command: docker buildx create --name multiarch --use
- name: build-push
dependsOn: [setup]
steps:
- name: login
script: echo "$DOCKER_TOKEN" | docker login -u ${DOCKER_USER} --password-stdin
- name: build-multi-platform
script: |
docker buildx build \
--platform ${PLATFORMS} \
--tag ${IMAGE_NAME}:${VERSION} \
--tag ${IMAGE_NAME}:latest \
--push \
.

Kubernetes Deployment Workflows

Complete Deployment Pipeline

Full deployment with pre-checks and post-validation:

apiVersion: v1
kind: Workflow
metadata:
name: deployment-pipeline
description: Complete deployment pipeline
spec:
requirements:
tools:
- name: kubectl
version: "1.28"
- name: helm
version: "3.12"
env:
APP_NAME: my-application
NAMESPACE: production
CHART_PATH: ./charts/my-app
jobs:
- name: pre-checks
description: Pre-deployment validation
steps:
- name: check-cluster
command: kubectl cluster-info
- name: check-namespace
script: |
if ! kubectl get namespace ${NAMESPACE}; then
kubectl create namespace ${NAMESPACE}
fi
- name: lint-chart
command: helm lint ${CHART_PATH}
- name: deploy
description: Deploy application
dependsOn: [pre-checks]
steps:
- name: helm-upgrade
command: |
helm upgrade --install ${APP_NAME} ${CHART_PATH} \
--namespace ${NAMESPACE} \
--wait \
--timeout 10m
- name: wait-for-pods
command: kubectl wait --for=condition=ready pod -l app=${APP_NAME} -n ${NAMESPACE} --timeout=300s
- name: post-checks
description: Post-deployment validation
dependsOn: [deploy]
steps:
- name: check-pods
command: kubectl get pods -n ${NAMESPACE} -l app=${APP_NAME}
- name: check-services
command: kubectl get services -n ${NAMESPACE} -l app=${APP_NAME}
- name: smoke-test
script: |
SERVICE_URL=$(kubectl get service ${APP_NAME} -n ${NAMESPACE} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -f http://${SERVICE_URL}/health || exit 1
echo "✅ Smoke test passed"

Blue-Green Deployment

Zero-downtime deployment pattern:

apiVersion: v1
kind: Workflow
metadata:
name: blue-green-deploy
description: Blue-green deployment strategy
spec:
env:
APP_NAME: my-app
NAMESPACE: production
NEW_VERSION: "v2"
jobs:
- name: deploy-green
description: Deploy new version (green)
steps:
- name: create-green-deployment
script: |
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: ${APP_NAME}-green
namespace: ${NAMESPACE}
spec:
replicas: 3
selector:
matchLabels:
app: ${APP_NAME}
version: ${NEW_VERSION}
slot: green
template:
metadata:
labels:
app: ${APP_NAME}
version: ${NEW_VERSION}
slot: green
spec:
containers:
- name: app
image: myapp:${NEW_VERSION}
EOF
- name: wait-green-ready
command: kubectl wait --for=condition=available deployment/${APP_NAME}-green -n ${NAMESPACE} --timeout=5m
- name: test-green
description: Test green deployment
dependsOn: [deploy-green]
steps:
- name: smoke-test
script: |
# Test green deployment through temporary service
kubectl run test-${NEW_VERSION} --image=curlimages/curl:latest --rm -i --restart=Never -- \
curl -f http://${APP_NAME}-green:8080/health
- name: switch-traffic
description: Switch traffic to green
dependsOn: [test-green]
steps:
- name: update-service
script: |
kubectl patch service ${APP_NAME} -n ${NAMESPACE} -p '{"spec":{"selector":{"slot":"green"}}}'
- name: verify-traffic
command: kubectl describe service ${APP_NAME} -n ${NAMESPACE}
- name: cleanup-blue
description: Remove old deployment
dependsOn: [switch-traffic]
steps:
- name: scale-down-blue
command: kubectl scale deployment/${APP_NAME}-blue --replicas=0 -n ${NAMESPACE}
- name: delete-blue
command: kubectl delete deployment/${APP_NAME}-blue -n ${NAMESPACE}

CI/CD Workflows

GitOps Deployment

Triggered by Git commits:

apiVersion: v1
kind: Workflow
metadata:
name: gitops-deploy
description: GitOps continuous deployment
spec:
requirements:
tools:
- name: git
- name: kubectl
version: "1.28"
secrets:
- name: GITHUB_TOKEN
provider: github
required: false
env:
REPO_URL: https://github.com/company/k8s-manifests.git
BRANCH: main
MANIFEST_DIR: manifests/production
jobs:
- name: fetch-manifests
description: Fetch latest manifests from Git
steps:
- name: clone-repo
script: |
rm -rf /tmp/k8s-manifests
git clone ${REPO_URL} /tmp/k8s-manifests
cd /tmp/k8s-manifests
git checkout ${BRANCH}
- name: deploy
description: Apply manifests
dependsOn: [fetch-manifests]
steps:
- name: apply-all
command: kubectl apply -f /tmp/k8s-manifests/${MANIFEST_DIR} --recursive
- name: wait-rollout
script: |
for deployment in $(kubectl get deployments -n production -o name); do
kubectl rollout status $deployment -n production
done

Test and Deploy

Run tests before deployment:

apiVersion: v1
kind: Workflow
metadata:
name: test-and-deploy
description: Test before deploying
spec:
requirements:
tools:
- name: go
version: "1.21"
- name: kubectl
version: "1.28"
env:
APP_NAME: my-service
NAMESPACE: production
jobs:
- name: test
description: Run tests
steps:
- name: unit-tests
command: go test ./... -v
- name: integration-tests
command: go test ./tests/integration -v
- name: build
command: go build -o app .
- name: deploy
description: Deploy if tests pass
dependsOn: [test]
steps:
- name: update-image
script: |
kubectl set image deployment/${APP_NAME} \
${APP_NAME}=myregistry/myapp:$(git rev-parse --short HEAD) \
-n ${NAMESPACE}
- name: wait-rollout
command: kubectl rollout status deployment/${APP_NAME} -n ${NAMESPACE}

Infrastructure Workflows

Database Backup

Regular database backup:

apiVersion: v1
kind: Workflow
metadata:
name: db-backup
description: Backup database
spec:
requirements:
tools:
- name: kubectl
- name: aws
description: AWS CLI for S3 upload
secrets:
- name: AWS_ACCESS_KEY_ID
provider: aws
required: true
- name: AWS_SECRET_ACCESS_KEY
provider: aws
required: true
env:
DB_POD: postgres-0
DB_NAME: myapp
NAMESPACE: database
S3_BUCKET: my-backups
BACKUP_PREFIX: postgres
jobs:
- name: backup
steps:
- name: create-backup
script: |
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
kubectl exec ${DB_POD} -n ${NAMESPACE} -- \
pg_dump -U postgres ${DB_NAME} > /tmp/backup-${TIMESTAMP}.sql
- name: upload-s3
script: |
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
aws s3 cp /tmp/backup-${TIMESTAMP}.sql \
s3://${S3_BUCKET}/${BACKUP_PREFIX}/backup-${TIMESTAMP}.sql
- name: cleanup-old
script: |
# Keep last 7 days
find /tmp -name "backup-*.sql" -mtime +7 -delete

Certificate Renewal

Renew SSL certificates:

apiVersion: v1
kind: Workflow
metadata:
name: cert-renewal
description: Renew SSL certificates
spec:
requirements:
tools:
- name: kubectl
- name: certbot
description: Let's Encrypt certificate tool
env:
DOMAIN: example.com
EMAIL: admin@example.com
SECRET_NAME: tls-secret
NAMESPACE: default
jobs:
- name: renew
steps:
- name: certbot-renew
script: |
certbot renew --non-interactive --agree-tos -m ${EMAIL}
- name: update-secret
script: |
kubectl create secret tls ${SECRET_NAME} \
--cert=/etc/letsencrypt/live/${DOMAIN}/fullchain.pem \
--key=/etc/letsencrypt/live/${DOMAIN}/privkey.pem \
--namespace=${NAMESPACE} \
--dry-run=client -o yaml | kubectl apply -f -
- name: restart-ingress
command: kubectl rollout restart deployment nginx-ingress -n ingress-nginx

Monitoring and Observability

Deploy Monitoring Stack

apiVersion: v1
kind: Workflow
metadata:
name: setup-monitoring
description: Deploy monitoring stack
spec:
requirements:
tools:
- name: helm
version: "3.12"
- name: kubectl
secrets:
- name: DATADOG_API_KEY
provider: datadog
required: false
env:
NAMESPACE: monitoring
jobs:
- name: prometheus
description: Install Prometheus
steps:
- name: add-repo
command: helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
- name: update-repos
command: helm repo update
- name: install-prometheus
command: |
helm upgrade --install prometheus prometheus-community/kube-prometheus-stack \
--namespace ${NAMESPACE} \
--create-namespace \
--wait
- name: grafana
description: Configure Grafana
dependsOn: [prometheus]
steps:
- name: get-password
script: |
kubectl get secret -n ${NAMESPACE} prometheus-grafana \
-o jsonpath="{.data.admin-password}" | base64 --decode
echo ""
- name: port-forward-info
script: |
echo "To access Grafana:"
echo "kubectl port-forward -n ${NAMESPACE} svc/prometheus-grafana 3000:80"