Orchestration

Standardize Dev Workflows: Golden Paths

Introduction

In the fast-paced world of Kubernetes, developer productivity can often be hampered by inconsistent workflows, ad-hoc configurations, and a lack of standardized practices. Teams spend valuable time reinventing the wheel, debugging environment-specific issues, and navigating a labyrinth of disparate tools. This fragmentation leads to slower development cycles, increased cognitive load, and a higher risk of errors in production. The solution? Establishing Golden Paths.

Golden Paths represent a curated, opinionated, and well-documented set of tools, practices, and configurations that guide developers from idea to production with minimal friction. They codify best practices, automate repetitive tasks, and provide a clear, paved road for application development and deployment within a Kubernetes ecosystem. By defining these paths, organizations empower their developers to focus on writing code, knowing that the underlying infrastructure, security, and operational concerns are handled by a robust, pre-approved framework. This guide will walk you through the principles of creating and implementing Golden Paths in your Kubernetes environment, ultimately boosting developer velocity and system reliability.

TL;DR: Standardizing Developer Workflows with Golden Paths

Golden Paths streamline Kubernetes development by providing opinionated, automated, and well-documented workflows. This guide covers defining, implementing, and maintaining these paths using tools like Helm, Kustomize, and CI/CD pipelines. Key takeaways:

  • Define Clear Standards: Establish consistent patterns for application structure, deployment, and operations.
  • Automate Everything: Leverage CI/CD for builds, tests, and deployments.
  • Provide Self-Service: Empower developers with templated projects and easy access to environments.
  • Version Control: Manage all configurations and templates in Git.
  • Iterate & Document: Continuously improve and keep documentation up-to-date.

Key Commands & Concepts:

# Initialize a new Helm chart from a Golden Path template
helm create my-app-golden-path --starter my-golden-starter-chart

# Apply Kustomize overlay for environment-specific configurations
kubectl apply -k overlays/production/

# Example CI/CD pipeline step (using GitHub Actions syntax)
# - name: Deploy to Staging
#   run: |
#     helm upgrade --install my-app ./charts/my-app -n staging --wait

# Verify deployment
kubectl get pods -n staging -l app.kubernetes.io/name=my-app

# Check logs
kubectl logs -n staging -l app.kubernetes.io/name=my-app

Prerequisites

To follow this guide effectively, you should have:

  • A fundamental understanding of Kubernetes concepts (Pods, Deployments, Services, Ingress).
  • Familiarity with kubectl and basic Kubernetes commands.
  • Experience with Git and version control systems.
  • Basic knowledge of CI/CD pipelines (e.g., Jenkins, GitHub Actions, GitLab CI).
  • Helm installed (Helm Installation Guide).
  • Kustomize installed (usually bundled with kubectl, but can be installed separately: Kustomize Installation).
  • Access to a Kubernetes cluster (local like Minikube/Kind, or cloud-based).

Step-by-Step Guide: Implementing Golden Paths

1. Define Your Golden Application Structure

The first step in establishing a Golden Path is to define a standardized application structure. This includes directory layouts, common files (Dockerfile, .helmignore, .gitignore), and a consistent way to define application metadata. This structure will serve as the blueprint for all new services, ensuring uniformity and predictability across your microservices landscape. It reduces the “time to hello world” significantly.

A typical Golden Path application structure might include a src directory for application code, a charts directory for Helm charts, a kustomize directory for overlays, and a ci directory for pipeline definitions. This consistency makes it easier for developers to navigate new codebases and for automation tools to process applications.

# Example of a Golden Path application structure
.
β”œβ”€β”€ .github/workflows/    # CI/CD pipeline definitions (e.g., for GitHub Actions)
β”‚   └── main.yaml
β”œβ”€β”€ charts/               # Helm chart for deploying the application
β”‚   └── my-golden-app/
β”‚       β”œβ”€β”€ Chart.yaml
β”‚       β”œβ”€β”€ values.yaml
β”‚       β”œβ”€β”€ templates/
β”‚       β”‚   β”œβ”€β”€ deployment.yaml
β”‚       β”‚   β”œβ”€β”€ service.yaml
β”‚       β”‚   └── _helpers.tpl
β”‚       └── ...
β”œβ”€β”€ kustomize/            # Kustomize base and overlays for environment-specific configs
β”‚   β”œβ”€β”€ base/
β”‚   β”‚   β”œβ”€β”€ kustomization.yaml
β”‚   β”‚   └── deployment.yaml
β”‚   └── overlays/
β”‚       β”œβ”€β”€ development/
β”‚       β”‚   └── kustomization.yaml
β”‚       └── production/
β”‚           └── kustomization.yaml
β”œβ”€β”€ src/                  # Application source code
β”‚   β”œβ”€β”€ main.go
β”‚   └── Dockerfile
β”œβ”€β”€ .dockerignore
β”œβ”€β”€ .gitignore
β”œβ”€β”€ README.md
└── ...

Verify:
While there’s no direct “verification” command here, the goal is to have a template repository that adheres to this structure. You can clone your template and verify its layout.

git clone https://github.com/your-org/golden-app-template.git
cd golden-app-template
ls -F
.github/  charts/  kustomize/  src/  .dockerignore  .gitignore  README.md

2. Standardize Deployment with Helm Charts

Helm is the de-facto package manager for Kubernetes, making it an excellent candidate for standardizing application deployments. A Golden Path should provide a robust, parameterized Helm chart that encapsulates all common deployment patterns: deployments, services, ingresses (or Gateway API resources), horizontal pod autoscalers (HPAs), and even Network Policies.

Creating a reusable base Helm chart allows developers to quickly deploy their applications without needing deep Kubernetes YAML knowledge. They only need to provide application-specific values (e.g., image name, tag, replica count), and the Golden Chart handles the rest. This promotes consistency and reduces the likelihood of misconfigurations.

# charts/my-golden-app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-golden-app.fullname" . }}
  labels:
    {{- include "my-golden-app.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "my-golden-app.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "my-golden-app.selectorLabels" . | nindent 8 }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: {{ .Values.service.port }}
              protocol: TCP
          livenessProbe:
            httpGet:
              path: {{ .Values.livenessProbe.path }}
              port: http
            initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
            periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
          readinessProbe:
            httpGet:
              path: {{ .Values.readinessProbe.path }}
              port: http
            initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
            periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
---
# charts/my-golden-app/values.yaml
replicaCount: 1

image:
  repository: nginx
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: "latest"

service:
  type: ClusterIP
  port: 80

livenessProbe:
  path: /
  initialDelaySeconds: 5
  periodSeconds: 10

readinessProbe:
  path: /
  initialDelaySeconds: 5
  periodSeconds: 10

resources:
  limits:
    cpu: 100m
    memory: 128Mi
  requests:
    cpu: 50m
    memory: 64Mi

Verify:
You can test rendering the Helm chart locally to see the generated Kubernetes manifests.

helm template my-app charts/my-golden-app --debug
---
# Source: my-golden-app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-my-golden-app
  labels:
    helm.sh/chart: my-golden-app-0.1.0
    app.kubernetes.io/name: my-golden-app
    app.kubernetes.io/instance: my-app
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: my-golden-app
      app.kubernetes.io/instance: my-app
  template:
    metadata:
      labels:
        app.kubernetes.io/name: my-golden-app
        app.kubernetes.io/instance: my-app
    spec:
      containers:
        - name: my-golden-app
          image: "nginx:latest"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /
              port: http
            initialDelaySeconds: 5
            periodSeconds: 10
          resources:
            limits:
              cpu: 100m
              memory: 128Mi
            requests:
              cpu: 50m
              memory: 64Mi
---
# Source: my-golden-app/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-app-my-golden-app
  labels:
    helm.sh/chart: my-golden-app-0.1.0
    app.kubernetes.io/name: my-golden-app
    app.kubernetes.io/instance: my-app
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: my-golden-app
    app.kubernetes.io/instance: my-app

3. Manage Environment-Specific Overlays with Kustomize

While Helm charts provide a great baseline, environments (development, staging, production) often require subtle variations. Kustomize is an excellent tool for managing these environment-specific configurations without templating. It allows you to define a base set of Kubernetes manifests and then apply non-destructive overlays for different environments.

This approach keeps your Helm charts clean and generic, while Kustomize handles the specifics like replica counts, resource limits, ingress hostnames, or specific ConfigMaps for production. This separation of concerns simplifies maintenance and reduces the risk of accidental environment-specific changes affecting other environments.

# kustomize/base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../charts/my-golden-app # Refer to the rendered Helm chart output or static manifests

# kustomize/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base

patches:
  - path: deployment-patch.yaml
    target:
      kind: Deployment
      name: my-golden-app # Name from the base manifest

# kustomize/overlays/production/deployment-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-golden-app # Must match the name in the base
spec:
  replicas: 3 # Scale up for production
  template:
    spec:
      containers:
        - name: my-golden-app
          resources: # Increase resources for production
            limits:
              cpu: 500m
              memory: 512Mi
            requests:
              cpu: 250m
              memory: 256Mi

Verify:
Apply the Kustomize overlay to see the differences. You’ll need to generate the base manifests first.

# For demonstration, let's assume we've "baked" the Helm chart output into the base
# In a real CI/CD, this would be a step: `helm template my-app charts/my-golden-app > kustomize/base/deployment.yaml`
# For this example, let's create a dummy base deployment
cat < kustomize/base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-golden-app
spec:
  replicas: 1
  template:
    spec:
      containers:
        - name: my-golden-app
          image: nginx:latest
EOF

# Now, generate the production manifests
kubectl kustomize kustomize/overlays/production/
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-golden-app
spec:
  replicas: 3 # Scaled up
  template:
    spec:
      containers:
        - name: my-golden-app
          image: nginx:latest
          resources: # Resources added
            limits:
              cpu: 500m
              memory: 512Mi
            requests:
              cpu: 250m
              memory: 256Mi

4. Implement CI/CD Pipelines for Automation

A Golden Path is incomplete without robust CI/CD automation. Pipelines should handle everything from code linting and testing to building container images, scanning for vulnerabilities (perhaps with tools integrated with Sigstore and Kyverno for supply chain security), and deploying to various environments. This automation ensures consistency, reduces manual errors, and frees developers from operational burdens.

Your CI/CD pipeline should:

  • Trigger on code pushes (e.g., to main or feature branches).
  • Build and push container images to a registry.
  • Run unit and integration tests.
  • Generate Kubernetes manifests (e.g., using helm template and kustomize build).
  • Apply manifests to target clusters (e.g., dev, staging, production).
  • Perform post-deployment checks (e.g., readiness/liveness, eBPF Observability with Hubble).
# .github/workflows/main.yaml (Example using GitHub Actions)
name: Golden Path CI/CD

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.20' # Or your application's language

      - name: Run unit tests
        run: go test ./src/...

      - name: Build Docker image
        run: |
          docker build -t my-org/my-golden-app:${{ github.sha }} -f src/Dockerfile src/
          echo "IMAGE_TAG=my-org/my-golden-app:${{ github.sha }}" >> $GITHUB_ENV

      - name: Log in to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Push Docker image
        run: docker push ${{ env.IMAGE_TAG }}

  deploy-to-staging:
    needs: build-and-test
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Kubeconfig
        uses: azure/k8s-set-context@v2
        with:
          method: kubeconfig
          kubeconfig: ${{ secrets.KUBE_CONFIG_STAGING }}

      - name: Install Helm
        uses: azure/helm-install-action@v1.2
        with:
          version: v3.8.1 # Or your preferred Helm version

      - name: Deploy to Staging
        run: |
          helm upgrade --install my-golden-app ./charts/my-golden-app \
            --namespace staging \
            --create-namespace \
            --set image.repository=my-org/my-golden-app \
            --set image.tag=${{ github.sha }} \
            --wait # Wait for the deployment to be ready

      - name: Verify Staging Deployment
        run: |
          kubectl get pods -n staging -l app.kubernetes.io/name=my-golden-app
          kubectl rollout status deployment/my-golden-app -n staging

  deploy-to-production:
    needs: deploy-to-staging
    runs-on: ubuntu-latest
    environment: production
    # Manual approval for production deployment
    environment:
      name: production
      url: https://your-production-app.com
    # Only run if staging deployment was successful
    if: success()
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Kubeconfig
        uses: azure/k8s-set-context@v2
        with:
          method: kubeconfig
          kubeconfig: ${{ secrets.KUBE_CONFIG_PRODUCTION }}

      - name: Install Helm
        uses: azure/helm-install-action@v1.2
        with:
          version: v3.8.1

      - name: Deploy to Production
        run: |
          helm upgrade --install my-golden-app ./charts/my-golden-app \
            --namespace production \
            --create-namespace \
            --set image.repository=my-org/my-golden-app \
            --set image.tag=${{ github.sha }} \
            -f kustomize/overlays/production/values.yaml # Apply production-specific values
            --wait

      - name: Verify Production Deployment
        run: |
          kubectl get pods -n production -l app.kubernetes.io/name=my-golden-app
          kubectl rollout status deployment/my-golden-app -n production

Verify:
Trigger a push to your main branch and observe the CI/CD pipeline execution in your chosen platform (e.g., GitHub Actions, GitLab CI, Jenkins). Ensure all steps pass and deployments are successful.

# After pipeline completion, verify deployments on the cluster
kubectl get pods -n staging -l app.kubernetes.io/name=my-golden-app
kubectl get pods -n production -l app.kubernetes.io/name=my-golden-app
NAME                               READY   STATUS    RESTARTS   AGE
my-golden-app-7b8c7b8c7c-abcde     1/1     Running   0          5m

NAME                               READY   STATUS    RESTARTS   AGE
my-golden-app-f5f5f5f5f5-vwxyz     1/1     Running   0          2m
my-golden-app-f5f5f5f5f5-12345     1/1     Running   0          2m
my-golden-app-f5f5f5f5f5-67890     1/1     Running   0          2m

5. Provide Developer Self-Service and Documentation

A Golden Path is only effective if developers can easily adopt and use it. This requires comprehensive documentation and self-service capabilities. Documentation should cover:

  • How to create a new application using the Golden Path template.
  • How to deploy to different environments.
  • Common debugging strategies.
  • How to extend the Golden Path for specific needs.
  • Guidelines for security, observability (eBPF Observability), and cost optimization (Karpenter).

Self-service can be enabled via:

  • Template Repositories: GitHub’s “Use this template” feature or similar tools allow developers to quickly scaffold new projects adhering to the Golden Path.
  • Internal Developer Portals: Tools like Backstage (Backstage.io) can provide a single pane of glass for creating, managing, and observing applications.
# Example of using a GitHub template repository
# Go to your Golden Path template repository on GitHub
# Click "Use this template" -> "Create a new repository"

Verify:
Ensure your documentation is accessible and up-to-date. Walk through the process of creating a new application from your template as if you were a new developer. Can you get a “hello world” deployed to a dev environment quickly and easily?

Production Considerations

  • Security Hardening: Integrate security best practices directly into your Golden Path charts and pipelines. This includes Pod Security Standards, Network Policies, image scanning, and secrets management. Consider tools like Kyverno or OPA Gatekeeper for policy enforcement at admission.
  • Observability: Ensure all Golden Path applications are automatically configured for logging, metrics, and tracing. This means including sidecars (if using a service mesh like Istio Ambient Mesh) or agents for Prometheus, Grafana Loki, Jaeger, etc., directly in your base Helm charts.
  • Resource Management: Implement sensible default resource requests and limits in your Helm charts. Use Kustomize overlays to fine-tune these for production. Consider tools like Vertical Pod Autoscaler (VPA) in non-production environments to recommend optimal settings.
  • Disaster Recovery & Backup: Define how application data is backed up and recovered. This might involve cloud provider-specific services or Kubernetes-native solutions like Velero.
  • Cost Optimization: Integrate cost-aware configurations. For example, define node affinities/anti-affinities to leverage spot instances or specific node pools. Tools like Karpenter can be instrumental in dynamic node provisioning for cost efficiency.
  • Infrastructure as Code (IaC): Manage the underlying Kubernetes cluster and its addons (e.g., ingress controllers, service meshes, CNI like Cilium) using IaC tools like Terraform or CloudFormation. Your Golden Paths for applications sit on top of this.
  • GitOps: For production deployments, consider adopting a GitOps approach with tools like Argo CD or Flux CD. This ensures that the desired state of your cluster is always defined in Git and automatically reconciled.

Troubleshooting

1. Helm Chart Rendering Issues

Issue: helm template fails with syntax errors or missing values.

Solution:

  • Syntax Check: Helm uses Go templating. Ensure correct syntax (e.g., {{ .Values.foo }}).
  • Debug Mode: Use helm template --debug to get more verbose output, including the values being used.
  • Linting: Run helm lint charts/my-golden-app to catch common errors.
  • Missing Values: Check if all referenced .Values are defined in values.yaml or passed via --set.
helm lint charts/my-golden-app
helm template my-app charts/my-golden-app --debug --dry-run

2. Kustomize Overlay Not Applying Correctly

Issue: Kustomize changes (e.g., replica count, image tag) are not reflected in the output.

Solution:

  • Correct Path: Ensure the resources path in your kustomization.yaml points to the correct base or rendered manifests.
  • Target Matching: For patches, verify that the target (kind, name, apiVersion) exactly matches the resource in the base you intend to modify.
  • Name Reference: If your base uses Helm, ensure Kustomize refers to the exact name Helm generated (e.g., my-app-my-golden-app if using fullname helper).
  • Kustomize Version: Ensure you’re using a compatible version of Kustomize.
# Check kustomization build output
kubectl kustomize kustomize/overlays/production/

3. CI/CD Pipeline Failure to Deploy

Issue: Pipeline fails at the deployment step (e.g., “Error: UPGRADE FAILED” or “kubectl authentication failed”).

Solution:

  • Kubeconfig: Verify that the Kubernetes context (KUBE_CONFIG secret) used in your CI/CD is valid and has the necessary permissions for the target namespace.
  • Namespace: Ensure the target namespace exists or is created by the pipeline (--create-namespace for Helm).
  • Helm Release Name: Check for conflicting Helm release names in the target namespace.
  • Image Pull Errors: If pods are stuck in ImagePullBackOff, verify the image name/tag, registry authentication, and image pull policy.
  • Cluster Access: Test kubectl get pods -n manually from a machine with the same Kubeconfig.
# Example to debug Kubeconfig locally
export KUBECONFIG=./path/to/your/ci-kubeconfig.yaml
kubectl get pods -n staging
# If you get errors, your Kubeconfig or permissions are likely the issue.

4. Application Not Ready After Deployment

Issue: Pods are stuck in Pending, CrashLoopBackOff, or NotReady status after deployment.

Solution:

  • Describe Pod: Use kubectl describe pod -n to check events, volume mounts, and container status.
  • Check Logs: Use kubectl logs -n to see application startup errors.
  • Resource Limits: If pods are Pending with FailedScheduling, check if the cluster has enough resources or if your pod requests are too high. Consider GPU scheduling if applicable.
  • Liveness/Readiness Probes: Verify probe paths and ports are correct. If probes fail, the application won’t be marked ready.
  • ConfigMaps/Secrets: Ensure all required ConfigMaps and Secrets are mounted and accessible.
kubectl get pods -n staging
kubectl describe pod  -n staging
kubectl logs  -n staging

5. Network Connectivity Issues

Issue: Application deployed, but cannot be accessed from outside the cluster or between pods.

Solution:

  • Service Selector: Verify the Service’s selector matches the Deployment’s labels.
  • Ingress/Gateway: Check your Ingress or Gateway API resource configuration, rules, and backend service names. Ensure the Ingress controller is running.
  • Network Policies: If Network Policies are in place, ensure they permit traffic to and from your application.
  • DNS Resolution: Check if internal DNS resolution is working (e.g., can pods resolve other service names?).
  • CNI Plugin: Ensure your CNI plugin (e.g., Cilium, Calico) is healthy and configured correctly.
kubectl get svc -n staging
kubectl describe svc  -n staging
kubectl get ingress -n staging # Or Gateway/HTTPRoute
kubectl describe ingress  -n staging

FAQ Section

1. What is a “Golden Path” in Kubernetes?

A Golden Path is a set of standardized, opinionated, and automated workflows, tools, and configurations that guide developers through the entire software development lifecycleβ€”from coding to deploymentβ€”within a Kubernetes environment. Its goal is to reduce cognitive load, increase developer velocity, and ensure consistency and reliability.

2. How do Golden Paths differ from traditional documentation?

While documentation is crucial, Golden Paths go beyond static instructions. They provide executable templates, pre-built CI/CD pipelines, and curated toolchains that developers can immediately use. It’s not just “how to do it,” but “here’s the ready-to-use way to do it.”

3. Can Golden Paths limit developer flexibility?

The intent of a Golden Path is to provide a “paved road” for common use cases, not to create a rigid cage. Developers should always have the option to deviate from the Golden Path for specific, valid reasons, provided they understand the implications and extra operational burden. The path should be well-trodden, but not the only path. It’s about balancing standardization with innovation.

4. What tools are essential for building a Golden Path?

Key tools often include:

  • Version Control: Git (GitHub, GitLab, Bitbucket)
  • Containerization: Docker
  • Kubernetes Package Manager: Helm
  • Configuration Management: Kustomize
  • CI/CD: GitHub Actions, GitLab CI, Jenkins, Argo Workflows
  • Templating/Scaffolding: Custom scripts, GitHub template repositories, Backstage
  • Policy Enforcement: Kyverno, OPA Gatekeeper
  • Observability: Prometheus, Grafana, Loki, Jaeger

5. How do I maintain Golden Paths over time?

Maintaining Golden Paths requires continuous effort:

  • Dedicated Team: A

Leave a Reply

Your email address will not be published. Required fields are marked *