home / skills / dexploarer / claudius-skills / kubernetes-manifest-generator

This skill generates production-ready Kubernetes manifests (deployments, services, ingresses, configmaps, secrets) with best practices for security and

npx playbooks add skill dexploarer/claudius-skills --skill kubernetes-manifest-generator

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
12.5 KB
---
name: kubernetes-manifest-generator
description: Generates Kubernetes manifests (Deployments, Services, Ingress, ConfigMaps, Secrets) with best practices for production workloads. Use when user asks to "create k8s manifest", "generate Kubernetes deployment", "setup k8s service", or "create Kubernetes resources".
allowed-tools: [Write, Read, Bash]
---

# Kubernetes Manifest Generator

Generates production-ready Kubernetes manifests with best practices for security, resource management, and high availability.

## When to Use

- "Create Kubernetes deployment"
- "Generate k8s manifests"
- "Setup Kubernetes service"
- "Create Ingress configuration"
- "Generate ConfigMap and Secrets"

## Instructions

### 1. Gather Requirements

Ask for:
- Application name
- Container image and tag
- Number of replicas
- Resource requirements (CPU, memory)
- Environment variables
- Ports exposed
- Ingress/Service type needed
- Storage requirements

### 2. Generate Deployment

**Basic Deployment:**
```yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  namespace: production
  labels:
    app: myapp
    version: v1.0.0
    environment: production
spec:
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: myapp
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: myapp
        version: v1.0.0
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8080"
        prometheus.io/path: "/metrics"
    spec:
      serviceAccountName: myapp
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 1000
      containers:
      - name: myapp
        image: myapp:v1.0.0
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        env:
        - name: NODE_ENV
          value: "production"
        - name: PORT
          value: "8080"
        envFrom:
        - configMapRef:
            name: myapp-config
        - secretRef:
            name: myapp-secrets
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 512Mi
        livenessProbe:
          httpGet:
            path: /health
            port: http
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /ready
            port: http
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 3
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          capabilities:
            drop:
            - ALL
        volumeMounts:
        - name: tmp
          mountPath: /tmp
        - name: cache
          mountPath: /app/cache
      volumes:
      - name: tmp
        emptyDir: {}
      - name: cache
        emptyDir: {}
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - myapp
              topologyKey: kubernetes.io/hostname
```

### 3. Generate Service

**ClusterIP Service:**
```yaml
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: production
  labels:
    app: myapp
spec:
  type: ClusterIP
  selector:
    app: myapp
  ports:
  - name: http
    port: 80
    targetPort: http
    protocol: TCP
  sessionAffinity: None
```

**LoadBalancer Service:**
```yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-lb
  namespace: production
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
  type: LoadBalancer
  selector:
    app: myapp
  ports:
  - name: http
    port: 80
    targetPort: 8080
  - name: https
    port: 443
    targetPort: 8080
```

**Headless Service (for StatefulSets):**
```yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-headless
  namespace: production
spec:
  clusterIP: None
  selector:
    app: myapp
  ports:
  - name: http
    port: 8080
```

### 4. Generate Ingress

**NGINX Ingress:**
```yaml
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp
  namespace: production
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rate-limit: "100"
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
spec:
  tls:
  - hosts:
    - myapp.example.com
    secretName: myapp-tls
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp
            port:
              name: http
```

**Traefik Ingress:**
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp
  namespace: production
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.tls: "true"
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp
            port:
              number: 80
```

### 5. Generate ConfigMap

```yaml
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: myapp-config
  namespace: production
data:
  # Simple values
  LOG_LEVEL: "info"
  FEATURE_FLAGS: "feature1,feature2"

  # File content
  app.conf: |
    server {
      listen 8080;
      location / {
        root /app;
      }
    }

  config.json: |
    {
      "database": {
        "pool": {
          "min": 2,
          "max": 10
        }
      },
      "cache": {
        "ttl": 3600
      }
    }
```

### 6. Generate Secrets

```yaml
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: myapp-secrets
  namespace: production
type: Opaque
stringData:
  DATABASE_URL: "postgresql://user:password@postgres:5432/myapp"
  API_KEY: "your-api-key-here"
  JWT_SECRET: "your-jwt-secret"
---
# TLS Secret (for custom certificates)
apiVersion: v1
kind: Secret
metadata:
  name: myapp-tls
  namespace: production
type: kubernetes.io/tls
data:
  tls.crt: LS0tLS1CRUdJTi... # base64 encoded
  tls.key: LS0tLS1CRUdJTi... # base64 encoded
```

**Create secret from file:**
```bash
kubectl create secret generic myapp-secrets \
  --from-file=.env \
  --namespace=production \
  --dry-run=client -o yaml > secret.yaml
```

### 7. Generate StatefulSet

```yaml
# statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongodb
  namespace: production
spec:
  serviceName: mongodb-headless
  replicas: 3
  selector:
    matchLabels:
      app: mongodb
  template:
    metadata:
      labels:
        app: mongodb
    spec:
      containers:
      - name: mongodb
        image: mongo:6.0
        ports:
        - containerPort: 27017
          name: mongodb
        env:
        - name: MONGO_INITDB_ROOT_USERNAME
          valueFrom:
            secretKeyRef:
              name: mongodb-secrets
              key: username
        - name: MONGO_INITDB_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mongodb-secrets
              key: password
        volumeMounts:
        - name: data
          mountPath: /data/db
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
          limits:
            cpu: 2
            memory: 4Gi
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: fast-ssd
      resources:
        requests:
          storage: 100Gi
```

### 8. Generate PersistentVolumeClaim

```yaml
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myapp-data
  namespace: production
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: standard
  resources:
    requests:
      storage: 10Gi
```

### 9. Generate HorizontalPodAutoscaler

```yaml
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 3
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 50
        periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
      - type: Percent
        value: 100
        periodSeconds: 15
      - type: Pods
        value: 4
        periodSeconds: 15
      selectPolicy: Max
```

### 10. Generate NetworkPolicy

```yaml
# networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: myapp
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: myapp
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: postgres
    ports:
    - protocol: TCP
      port: 5432
  - to:
    - namespaceSelector: {}
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
```

### 11. Generate ServiceAccount & RBAC

```yaml
# rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: myapp
  namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: myapp
  namespace: production
rules:
- apiGroups: [""]
  resources: ["configmaps", "secrets"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: myapp
  namespace: production
subjects:
- kind: ServiceAccount
  name: myapp
  namespace: production
roleRef:
  kind: Role
  name: myapp
  apiGroup: rbac.authorization.k8s.io
```

### 12. Generate Kustomization

**kustomization.yaml:**
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: production

resources:
- deployment.yaml
- service.yaml
- ingress.yaml
- configmap.yaml
- secret.yaml
- hpa.yaml
- networkpolicy.yaml
- rbac.yaml

commonLabels:
  app: myapp
  managed-by: kustomize

images:
- name: myapp
  newName: registry.example.com/myapp
  newTag: v1.2.3

configMapGenerator:
- name: myapp-env
  literals:
  - NODE_ENV=production
  - LOG_LEVEL=info

secretGenerator:
- name: myapp-api
  literals:
  - API_KEY=secret-value
```

### 13. Generate All Resources Script

```bash
#!/bin/bash
# generate-k8s-manifests.sh

APP_NAME=${1:-myapp}
NAMESPACE=${2:-production}
IMAGE=${3:-$APP_NAME:latest}

mkdir -p k8s

cat > k8s/namespace.yaml <<EOF
apiVersion: v1
kind: Namespace
metadata:
  name: $NAMESPACE
EOF

cat > k8s/deployment.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: $APP_NAME
  namespace: $NAMESPACE
spec:
  replicas: 3
  selector:
    matchLabels:
      app: $APP_NAME
  template:
    metadata:
      labels:
        app: $APP_NAME
    spec:
      containers:
      - name: $APP_NAME
        image: $IMAGE
        ports:
        - containerPort: 8080
EOF

echo "Kubernetes manifests generated in k8s/"
```

### Best Practices

**DO:**
- Use resource requests and limits
- Implement health checks
- Use non-root users
- Enable pod security contexts
- Use secrets for sensitive data
- Implement network policies
- Use HPA for autoscaling
- Add pod anti-affinity
- Use readOnly root filesystem

**DON'T:**
- Run as root
- Hardcode secrets
- Skip resource limits
- Use :latest tag
- Ignore security contexts
- Allow privilege escalation
- Skip health checks
- Use default service account

## Checklist

- [ ] Deployment configured
- [ ] Service created
- [ ] Ingress setup (if needed)
- [ ] ConfigMap and Secrets created
- [ ] Resource limits set
- [ ] Health checks configured
- [ ] Security contexts applied
- [ ] RBAC configured
- [ ] HPA setup (if needed)
- [ ] Network policies defined

Overview

This skill generates production-ready Kubernetes manifests (Deployments, Services, Ingress, ConfigMaps, Secrets, StatefulSets, PVCs, HPA, NetworkPolicies, RBAC and kustomize files) tailored to your application. It applies common production best practices for security, resource management, health checks, and high availability. Use it to produce consistent YAML that’s ready to review and apply to clusters.

How this skill works

I ask for basic deployment requirements (app name, image, replicas, resources, env vars, ports, ingress/service type, storage) and produce manifests matching those inputs. Generated manifests include securityContext, non-root user settings, resource requests/limits, liveness/readiness probes, pod anti-affinity, and optional autoscaling and network policies. I can output ClusterIP/LoadBalancer/Headless services, NGINX or Traefik ingress, ConfigMaps, Secrets, StatefulSets, PVCs, HPA, RBAC and a kustomization.yaml to manage overlays.

When to use it

  • You need a repeatable, production-ready Deployment and Service YAML for an app
  • You want secure defaults (non-root, readOnlyRootFilesystem, dropped capabilities)
  • You need Ingress and TLS configuration (NGINX or Traefik) for a domain
  • You want ConfigMap/Secret templates and guidance for sensitive data
  • You need StatefulSet + PVCs for stateful workloads (databases)
  • You want kustomize-ready manifests and a script to bootstrap resources

Best practices

  • Always set resource requests and limits to avoid noisy-neighbor issues
  • Implement liveness and readiness probes with sensible delays and timeouts
  • Run containers as non-root, disable privilege escalation, and use readOnlyRootFilesystem
  • Use Secrets for credentials and avoid :latest image tags; pin image digests when possible
  • Define podAntiAffinity to improve availability across nodes
  • Add NetworkPolicy and minimal RBAC rules to limit access

Example use cases

  • Generate a Deployment + ClusterIP Service + ConfigMap/Secrets for a web service
  • Create a LoadBalancer Service and NGINX Ingress with TLS for a public app
  • Produce a StatefulSet with PVC templates for a 3-node database cluster
  • Add HPA and resource-based scaling for a CPU- or memory-bound service
  • Create network policy and RBAC resources for stricter security posture

FAQ

Can I customize probes, resources, and replica count?

Yes — provide probe endpoints, CPU/memory requests and limits, and desired replicas; manifests will reflect those values.

How are secrets handled?

Secrets are generated as Opaque or TLS types; sensitive values should come from secure inputs or be managed with sealed-secrets/vault in production.