How the k8s-mvp repository environments are structured using Kustomize overlays and GitOps.
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
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 envEnvironment 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 tagshopify/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 | Namespace | Domain | Secrets Prefix |
|---|---|---|---|
| dev | dev |
dev.k8s.stamped.io |
dev-* |
| staging | staging |
staging.k8s.stamped.io |
staging-* |
| prod | prod |
k8s.stamped.io |
prod-* |
- Ingress hosts:
dev.k8s.stamped.iovsstaging.k8s.stamped.io - Image tags: Each env tracks its own deployed version
- SQS queues:
k8s-dev-*vsk8s-staging-* - S3 buckets:
k8s-dev-*vsk8s-staging-* - DynamoDB tables:
k8s-dev-*vsk8s-staging-* - Secrets: Separate sealed secrets per environment
- ConfigMaps: Redis hosts, service URLs
- Service repo (e.g.,
app-backend-api) builds and pushes image to ECR - CI updates
k8s-mvpwith new image tag viased - Flux detects change, reconciles to cluster
- Kubernetes pulls new image and rolls out deployment