k8s
Generates and validates production-ready Pulumi K8s TypeScript resources following deploy.ts patterns, and diagnoses runtime cluster issues. Use when creating Deployments, Services, Ingress, Gateway A
Files5
View on GitHubSKILL.md.claude/skills/k8s/SKILL.md
GitHub[H1][K8S]
<br>Dictum: Infrastructure code follows deploy.ts canonical patterns; validation and debugging are integral.
Generate, validate, and debug Pulumi K8s resources in TypeScript: _CONFIG + _Ops + dispatch table.
Provider: current stable @pulumi/kubernetes (Server-Side Apply default) | K8s: 1.32-1.35 | Canonical: infrastructure/src/deploy.ts (207 LOC)
Tasks:
- Gather requirements (table below)
- Lookup API docs via
context7-toolsfor@pulumi/kubernetestarget kind; fallback: WebSearch"@pulumi/kubernetes" "<kind>" TypeScript API 2025 - Read
references/pulumi_k8s_patterns.md-- naming, labels, security, mode dispatch - Read
references/resource_templates.md-- templates, factories, ComponentResource, advanced patterns - Read
infrastructure/src/deploy.ts-- canonical implementation - Generate resources per architecture and standards below
- Validate against
references/validation.md-- security, reliability, cross-resource checks - For runtime issues, read
references/debug.md-- decision tree, kubectl workflows, EKS diagnostics - Deliver summary table with
pulumi preview/pulumi upnext steps
[1][REQUIREMENTS]
<br>Dictum: Gather all inputs before generation.
| Field | Required | Default | deploy.ts Reference |
|---|---|---|---|
| Deployment mode | YES | -- | _Ops.mode() (line 64) |
| Resource kind(s) | YES | -- | -- |
| Container image | YES | -- | input.api.image (line 163) |
| Port | YES | 4000 |
_CONFIG.ports.api (line 22) |
| Health paths | YES | /api/health/liveness, /api/health/readiness |
_CONFIG.k8s.probes (line 19) |
| CPU/memory | NO | small preset |
input.api.cpu (line 168) |
| HPA min/max/target | NO | env-driven | input.hpa.* (line 174) |
| PVC size | NO | 10Gi |
_k8sObserve (line 120) |
| Namespace | NO | parametric |
_CONFIG.k8s.namespace |
Mode: cloud (K8s+AWS) or selfhosted (Docker). Kind: Deployment, Service, Ingress, Gateway, HTTPRoute, GRPCRoute, HPA, ConfigMap, Secret, PVC, DaemonSet, NetworkPolicy, PDB, ValidatingAdmissionPolicy, ComponentResource.
[2][ARCHITECTURE]
<br>Dictum: deploy.ts layers structure all generated code.
| Layer | Purpose | Lines |
|---|---|---|
_CONFIG |
Immutable as const -- ports, labels, probes, images |
11-24 |
_Ops |
Pure factories -- meta(), k8sUrl(), secret(), fail() |
28-119 |
_k8sObserve |
Array-driven factory: PVC+ConfigMap+Deployment+Service | 120-126 |
_DEPLOY |
Dispatch table { cloud, selfhosted } as const |
130-195 |
deploy |
Entry point: resolves mode, delegates to dispatch | 199-202 |
Guidance:
Mode dispatch- Cloud uses ClusterIP + nginx ingress. Selfhosted uses@pulumi/dockerexclusively.Output tracking- Usenamespace.metadata.name(Output) for implicit dependency ordering.Secrets-pulumi.secret()wraps sensitive values;pulumi.interpolateforOutput<T>strings.Factories- Array-driven_k8sObservepattern for repetitive resource groups.
Best-Practices:
- Resources require
requests+limits(env-driven, deploy.ts:168). Guaranteed QoS whenlimits == requests. - All workloads require liveness + readiness + startup probes (deploy.ts:19).
- New workloads require
_SECURITYpod/container contexts (see resource_templates.md). terminationGracePeriodSeconds: 30on all pod specs (deploy.ts:171).as const satisfiesfor config objects;pulumi.interpolateonly when mixingOutput<T>.- PodDisruptionBudget required for
replicas >= 2. NetworkPolicy required for production namespaces. topologySpreadConstraintsfor zone distribution; pod anti-affinity for node distribution.
[3][MODE_RULES]
<br>Dictum: Mode dispatch prevents cross-concern resource creation.
| Concern | cloud (K8s + AWS) |
selfhosted (Docker) |
|---|---|---|
| Compute | Deployment + Service (ClusterIP) | docker.Container + Traefik labels |
| Ingress | Ingress (nginx class) or Gateway API | Traefik reverse proxy |
| Scaling | HPA (CPU + memory targets) | None |
| Config | ConfigMap + Secret | docker.Container.envs |
| Data | AWS RDS + ElastiCache + S3 | Docker containers (pg, redis, minio) |
| TLS | Ingress TLS + ssl-redirect annotation | Let's Encrypt via Traefik |
| Observe | DaemonSet (Alloy) + _k8sObserve factory |
Docker containers with uploads |
[CRITICAL] Cloud: ClusterIP + nginx ingress (NOT LoadBalancer + ALB). Selfhosted: @pulumi/docker only (NOT Kubernetes).
[4][TROUBLESHOOTING]
<br>Dictum: Common failures have deterministic fixes.
| Issue | Cause | Fix |
|---|---|---|
| Type errors on k8s resources | API shape changed in provider | Verify against current stable API via context7 |
| Preview fails on namespace | Namespace not yet created | Use namespace.metadata.name Output for implicit dep |
| Cross-stack reference errors | Wrong format or different backend | Format: <org>/<project>/<stack>, same backend required |
| Selfhosted creating k8s | Mode violation | Selfhosted uses @pulumi/docker only |
already exists in preview |
Resource in cluster not in state | pulumi import <type> <name> <id> |
| Replace instead of update | Immutable field changed | See references/validation.md immutable fields table |
| Server-Side Apply conflicts | Field manager ownership conflict | pulumi refresh or set field manager explicitly |
| Gateway API not found | CRDs not installed | Install gateway controller before Gateway/HTTPRoute/GRPCRoute |
| Sidecar not recognized | K8s <1.33 or feature gate off | Verify cluster 1.33+; check SidecarContainers gate |
| In-place resize rejected | K8s <1.35 or feature gate off | Verify cluster 1.35+; check InPlacePodVerticalScaling gate |
| DRA ResourceClaim not bound | DRA driver not installed | Verify ResourceClass and device plugin running |
| Topology routing not working | Missing annotation | Add service.kubernetes.io/topology-mode: auto |