Skip to content

Kubernetes Configuration

Generate Kubernetes manifests for multiple environments (prod/staging/dev) from a single JSSON template with environment-specific configurations.

Managing Kubernetes configs across environments means:

  • Duplicate manifests — Separate YAML/JSON files for each environment
  • Inconsistent naming — Easy to make mistakes in resource names
  • Hard to update — Changes require editing multiple files
  • Error-prone — Copy-paste errors in similar configs

One template generates configs for all environments with conditional logic!

deployments [
template { appName, env, replicas }
map (deploy) = {
apiVersion = "apps/v1"
kind = "Deployment"
name = deploy.appName + "-" + deploy.env
namespace = deploy.env
replicas = deploy.replicas
// Environment-specific image tag
image = "registry/" + deploy.appName + ":" + (deploy.env == "prod" ? "stable" : "latest")
// Environment-specific resources
memoryRequest = deploy.env == "prod" ? "512Mi" : "256Mi"
cpuRequest = deploy.env == "prod" ? "500m" : "250m"
memoryLimit = deploy.env == "prod" ? "1Gi" : "512Mi"
cpuLimit = deploy.env == "prod" ? "1000m" : "500m"
// Environment variables
environment = deploy.env
logLevel = deploy.env == "prod" ? "error" : "debug"
}
// Production: high replicas
"api", "prod", 5
"web", "prod", 3
// Staging: medium replicas
"api", "staging", 2
"web", "staging", 2
// Development: minimal replicas
"api", "dev", 1
"web", "dev", 1
]
// Different image tags per environment
image = "registry/" + deploy.appName + ":" + (deploy.env == "prod" ? "stable" : "latest")
// Different resources per environment
memoryRequest = deploy.env == "prod" ? "512Mi" : "256Mi"
// Consistent naming convention
name = deploy.appName + "-" + deploy.env
// Results in: "api-prod", "web-staging", etc.
template { appName, env, replicas }
// Define once, use for all apps and environments
"api", "prod", 5
"web", "staging", 2
services [
template { appName, env, port }
map (svc) = {
apiVersion = "v1"
kind = "Service"
name = svc.appName + "-" + svc.env
namespace = svc.env
type = svc.env == "prod" ? "LoadBalancer" : "ClusterIP"
port = svc.port
targetPort = svc.port
protocol = "TCP"
}
"api", "prod", 8080
"web", "prod", 3000
"api", "staging", 8080
"web", "staging", 3000
]
configMaps [
template { env }
map (cfg) = {
apiVersion = "v1"
kind = "ConfigMap"
name = "app-config-" + cfg.env
namespace = cfg.env
databaseHost = "postgres-" + cfg.env + ".internal"
redisHost = "redis-" + cfg.env + ".internal"
cacheTTL = cfg.env == "prod" ? "3600" : "60"
featureFlags = cfg.env == "prod" ? "stable" : "experimental"
}
"prod"
"staging"
"dev"
]

Consistency — Same naming conventions across all resources
DRY — Define once, generate for all environments
Type Safety — Templates ensure all required fields are present
Easy Updates — Change one template, update all environments
Less Error-Prone — No copy-paste mistakes

Perfect for:

  • Multi-environment Kubernetes deployments
  • Microservices with similar configs
  • Infrastructure as code
  • Helm chart alternatives
  • GitOps workflows

Not ideal for:

  • Extremely different configs per environment
  • One-off, unique resources
  • Complex Helm chart replacements
  1. Save the deployments example to k8s.jsson
  2. Run: jsson -i k8s.jsson -o k8s.json
  3. Use the JSON to generate Kubernetes manifests!

One template, all environments! ☸️