Skip to content

Instantly share code, notes, and snippets.

@diegoeche
Created February 4, 2026 20:54
Show Gist options
  • Select an option

  • Save diegoeche/97c24bd23411baacdd101c3d5b3b2a93 to your computer and use it in GitHub Desktop.

Select an option

Save diegoeche/97c24bd23411baacdd101c3d5b3b2a93 to your computer and use it in GitHub Desktop.
k8s-mvp environment structure and GitOps flow

k8s-mvp Environment Structure

How the k8s-mvp repository environments are structured using Kustomize overlays and GitOps.

Directory Layout

clusters/platform/
├── base/                          # Shared service definitions
│   ├── app-backend-api/
│   │   ├── deployment.yaml        # Generic deployment (no env-specific values)
│   │   ├── service.yaml
│   │   ├── ingress.yaml
│   │   └── kustomization.yaml
│   └── ... (other services)
│
├── environments/
│   ├── dev/
│   │   ├── kustomization.yaml     # Patches base with dev-specific values
│   │   ├── namespace.yaml
│   │   ├── secrets.yaml           # app-backend-api-secrets (sealed)
│   │   ├── shared-secrets.yaml    # dev-platform-secrets, dev-database-secrets
│   │   ├── shopify-secrets.yaml   # shopify-app-secrets
│   │   ├── k8s-service-hosts.yaml # Service discovery ConfigMap
│   │   └── configmaps/            # Redis, SQS queues, etc.
│   │
│   ├── staging/
│   │   └── ... (same structure, staging-specific values)
│   │
│   └── prod/
│       └── ... (same structure, prod-specific values)
│
├── infrastructure/                # Cluster-wide (ingress-nginx, sealed-secrets)
└── flux-system/                   # GitOps controller

How Kustomize Overlays Work

Base defines the service template:

# base/app-backend-api/deployment.yaml
image: 894283592737.dkr.ecr.us-west-2.amazonaws.com/app-backend-api:latest
env:
  - name: ASPNETCORE_ENVIRONMENT
    value: "Development"  # Default, overridden per env

Environment patches it:

# environments/dev/kustomization.yaml
resources:
  - ../../base/app-backend-api
  - secrets.yaml
  - shopify-secrets.yaml

patches:
  - target:
      kind: Ingress
      name: app-backend-api
    patch: |-
      - op: replace
        path: /spec/rules/0/host
        value: dev.k8s.stamped.io   # Dev-specific host

images:
  - name: 894283592737.dkr.ecr.us-west-2.amazonaws.com/app-backend-api
    newTag: "3471d9e"              # Dev-specific image tag

Secrets Flow

shopify/dev/.env (gitignored)     shopify/staging/.env (gitignored)
        ↓ kubeseal                         ↓ kubeseal
environments/dev/shopify-secrets.yaml    environments/staging/shopify-secrets.yaml
        ↓ Flux reconcile                   ↓ Flux reconcile
k8s Secret: shopify-app-secrets          k8s Secret: shopify-app-secrets
(namespace: dev)                         (namespace: staging)

Environment Mapping

Environment Namespace Domain Secrets Prefix
dev dev dev.k8s.stamped.io dev-*
staging staging staging.k8s.stamped.io staging-*
prod prod k8s.stamped.io prod-*

What Gets Patched Per Environment

  • Ingress hosts: dev.k8s.stamped.io vs staging.k8s.stamped.io
  • Image tags: Each env tracks its own deployed version
  • SQS queues: k8s-dev-* vs k8s-staging-*
  • S3 buckets: k8s-dev-* vs k8s-staging-*
  • DynamoDB tables: k8s-dev-* vs k8s-staging-*
  • Secrets: Separate sealed secrets per environment
  • ConfigMaps: Redis hosts, service URLs

GitOps Flow

  1. Service repo (e.g., app-backend-api) builds and pushes image to ECR
  2. CI updates k8s-mvp with new image tag via sed
  3. Flux detects change, reconciles to cluster
  4. Kubernetes pulls new image and rolls out deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment