@intentius/chant-lexicon-k8s 0.0.13 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/integrity.json +20 -15
  2. package/dist/manifest.json +1 -1
  3. package/dist/rules/wk8204.ts +33 -1
  4. package/dist/rules/wk8304.ts +70 -0
  5. package/dist/rules/wk8305.ts +115 -0
  6. package/dist/rules/wk8306.ts +50 -0
  7. package/dist/skills/chant-k8s-eks.md +156 -0
  8. package/dist/skills/chant-k8s-patterns.md +245 -0
  9. package/dist/skills/chant-k8s.md +36 -227
  10. package/package.json +27 -24
  11. package/src/codegen/docs.ts +5 -5
  12. package/src/composites/adot-collector.ts +245 -0
  13. package/src/composites/agic-ingress.ts +149 -0
  14. package/src/composites/alb-ingress.ts +152 -0
  15. package/src/composites/autoscaled-service.ts +51 -0
  16. package/src/composites/azure-disk-storage-class.ts +82 -0
  17. package/src/composites/azure-file-storage-class.ts +77 -0
  18. package/src/composites/azure-monitor-collector.ts +232 -0
  19. package/src/composites/batch-job.ts +221 -0
  20. package/src/composites/composites.test.ts +1584 -0
  21. package/src/composites/config-connector-context.ts +62 -0
  22. package/src/composites/configured-app.ts +224 -0
  23. package/src/composites/cron-workload.ts +6 -0
  24. package/src/composites/ebs-storage-class.ts +96 -0
  25. package/src/composites/efs-storage-class.ts +77 -0
  26. package/src/composites/external-dns-agent.ts +174 -0
  27. package/src/composites/filestore-storage-class.ts +79 -0
  28. package/src/composites/fluent-bit-agent.ts +220 -0
  29. package/src/composites/gce-pd-storage-class.ts +85 -0
  30. package/src/composites/gke-gateway.ts +143 -0
  31. package/src/composites/index.ts +47 -0
  32. package/src/composites/irsa-service-account.ts +114 -0
  33. package/src/composites/metrics-server.ts +224 -0
  34. package/src/composites/monitored-service.ts +221 -0
  35. package/src/composites/network-isolated-app.ts +202 -0
  36. package/src/composites/node-agent.ts +6 -0
  37. package/src/composites/secure-ingress.ts +149 -0
  38. package/src/composites/security-context.ts +10 -0
  39. package/src/composites/sidecar-app.ts +207 -0
  40. package/src/composites/stateful-app.ts +67 -15
  41. package/src/composites/web-app.ts +104 -35
  42. package/src/composites/worker-pool.ts +38 -4
  43. package/src/composites/workload-identity-sa.ts +118 -0
  44. package/src/composites/workload-identity-service-account.ts +116 -0
  45. package/src/index.ts +24 -2
  46. package/src/lint/post-synth/post-synth.test.ts +362 -1
  47. package/src/lint/post-synth/wk8204.ts +33 -1
  48. package/src/lint/post-synth/wk8304.ts +70 -0
  49. package/src/lint/post-synth/wk8305.ts +115 -0
  50. package/src/lint/post-synth/wk8306.ts +50 -0
  51. package/src/plugin.test.ts +2 -2
  52. package/src/plugin.ts +556 -242
  53. package/src/serializer.test.ts +120 -0
  54. package/src/serializer.ts +16 -4
@@ -0,0 +1,245 @@
1
+ ---
2
+ skill: chant-k8s-patterns
3
+ description: Advanced Kubernetes deployment patterns and composites
4
+ user-invocable: true
5
+ ---
6
+
7
+ # Advanced Kubernetes Patterns
8
+
9
+ ## Sidecar Patterns
10
+
11
+ ### SidecarApp — multi-container Deployment
12
+
13
+ ```typescript
14
+ import { SidecarApp } from "@intentius/chant-lexicon-k8s";
15
+
16
+ // Envoy sidecar proxy
17
+ const { deployment, service } = SidecarApp({
18
+ name: "api",
19
+ image: "api:1.0",
20
+ port: 8080,
21
+ sidecars: [
22
+ {
23
+ name: "envoy",
24
+ image: "envoyproxy/envoy:v1.28",
25
+ ports: [{ containerPort: 9901, name: "admin" }],
26
+ resources: { requests: { cpu: "100m", memory: "128Mi" }, limits: { cpu: "200m", memory: "256Mi" } },
27
+ },
28
+ ],
29
+ initContainers: [
30
+ { name: "migrate", image: "api:1.0", command: ["python", "manage.py", "migrate"] },
31
+ ],
32
+ sharedVolumes: [{ name: "tmp", emptyDir: {} }],
33
+ });
34
+ ```
35
+
36
+ Common sidecar use cases:
37
+ - **Envoy proxy** — service mesh, mTLS, traffic management
38
+ - **Log forwarder** — Fluent Bit sidecar for app-specific log routing
39
+ - **Auth proxy** — OAuth2 Proxy for authentication
40
+ - **Config watcher** — reload config on ConfigMap changes
41
+
42
+ ## Config and Secret Mounting
43
+
44
+ ### ConfiguredApp — automatic volume wiring
45
+
46
+ ```typescript
47
+ import { ConfiguredApp } from "@intentius/chant-lexicon-k8s";
48
+
49
+ const { deployment, service, configMap } = ConfiguredApp({
50
+ name: "api",
51
+ image: "api:1.0",
52
+ port: 8080,
53
+ // Mount ConfigMap as volume
54
+ configData: { "app.conf": "key=value\nother=setting" },
55
+ configMountPath: "/etc/api",
56
+ // Mount existing Secret as volume
57
+ secretName: "api-creds",
58
+ secretMountPath: "/secrets",
59
+ // Inject as environment variables
60
+ envFrom: { secretRef: "api-env-secret", configMapRef: "api-env-config" },
61
+ // Run migrations before the app starts
62
+ initContainers: [
63
+ { name: "migrate", image: "api:1.0", command: ["./migrate.sh"] },
64
+ ],
65
+ });
66
+ ```
67
+
68
+ ### Volume patterns
69
+
70
+ | Pattern | Use Case | ConfiguredApp Props |
71
+ |---------|----------|---------------------|
72
+ | ConfigMap as file | Config files, templates | `configData` + `configMountPath` |
73
+ | Secret as file | TLS certs, credentials | `secretName` + `secretMountPath` |
74
+ | ConfigMap as env | Simple key-value config | `envFrom.configMapRef` |
75
+ | Secret as env | Database URLs, API keys | `envFrom.secretRef` |
76
+
77
+ ## TLS / cert-manager
78
+
79
+ ### SecureIngress — multi-host TLS with cert-manager
80
+
81
+ ```typescript
82
+ import { SecureIngress } from "@intentius/chant-lexicon-k8s";
83
+
84
+ const { ingress, certificate } = SecureIngress({
85
+ name: "app-ingress",
86
+ hosts: [
87
+ {
88
+ hostname: "api.example.com",
89
+ paths: [
90
+ { path: "/v1", serviceName: "api-v1", servicePort: 80 },
91
+ { path: "/v2", serviceName: "api-v2", servicePort: 80 },
92
+ ],
93
+ },
94
+ {
95
+ hostname: "admin.example.com",
96
+ paths: [{ path: "/", serviceName: "admin", servicePort: 80 }],
97
+ },
98
+ ],
99
+ clusterIssuer: "letsencrypt-prod",
100
+ ingressClassName: "nginx",
101
+ });
102
+ ```
103
+
104
+ Features:
105
+ - Multiple hosts and paths per Ingress
106
+ - Automatic cert-manager Certificate when `clusterIssuer` set
107
+ - TLS secret auto-provisioned by cert-manager
108
+
109
+ ### cert-manager setup (prerequisite)
110
+
111
+ ```bash
112
+ # Install cert-manager
113
+ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml
114
+
115
+ # Create ClusterIssuer for Let's Encrypt
116
+ kubectl apply -f - <<EOF
117
+ apiVersion: cert-manager.io/v1
118
+ kind: ClusterIssuer
119
+ metadata:
120
+ name: letsencrypt-prod
121
+ spec:
122
+ acme:
123
+ server: https://acme-v02.api.letsencrypt.org/directory
124
+ email: admin@example.com
125
+ privateKeySecretRef:
126
+ name: letsencrypt-prod-key
127
+ solvers:
128
+ - http01:
129
+ ingress:
130
+ class: nginx
131
+ EOF
132
+ ```
133
+
134
+ ## Observability
135
+
136
+ ### MonitoredService — Prometheus monitoring
137
+
138
+ ```typescript
139
+ import { MonitoredService } from "@intentius/chant-lexicon-k8s";
140
+
141
+ const { deployment, service, serviceMonitor, prometheusRule } = MonitoredService({
142
+ name: "api",
143
+ image: "api:1.0",
144
+ port: 8080,
145
+ metricsPort: 9090,
146
+ metricsPath: "/metrics",
147
+ scrapeInterval: "15s",
148
+ alertRules: [
149
+ {
150
+ name: "HighErrorRate",
151
+ expr: 'rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) > 0.05',
152
+ for: "5m",
153
+ severity: "critical",
154
+ annotations: { summary: "High error rate on {{ $labels.instance }}" },
155
+ },
156
+ {
157
+ name: "HighLatency",
158
+ expr: 'histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) > 1',
159
+ for: "10m",
160
+ severity: "warning",
161
+ },
162
+ ],
163
+ });
164
+ ```
165
+
166
+ ### Prerequisites
167
+
168
+ - Prometheus Operator installed (for ServiceMonitor/PrometheusRule CRDs)
169
+ - Prometheus configured to discover ServiceMonitors
170
+
171
+ ## Network Isolation
172
+
173
+ ### NetworkIsolatedApp — per-app firewall rules
174
+
175
+ ```typescript
176
+ import { NetworkIsolatedApp } from "@intentius/chant-lexicon-k8s";
177
+
178
+ const { deployment, service, networkPolicy } = NetworkIsolatedApp({
179
+ name: "api",
180
+ image: "api:1.0",
181
+ port: 8080,
182
+ allowIngressFrom: [
183
+ { podSelector: { "app.kubernetes.io/name": "frontend" } },
184
+ { namespaceSelector: { "kubernetes.io/metadata.name": "monitoring" } },
185
+ ],
186
+ allowEgressTo: [
187
+ { podSelector: { "app.kubernetes.io/name": "postgres" }, ports: [{ port: 5432 }] },
188
+ { podSelector: { "app.kubernetes.io/name": "redis" }, ports: [{ port: 6379 }] },
189
+ ],
190
+ });
191
+ ```
192
+
193
+ ### Combining with NamespaceEnv
194
+
195
+ Use NamespaceEnv for namespace-level default-deny, then NetworkIsolatedApp for per-app allow rules:
196
+
197
+ ```typescript
198
+ // Namespace: deny all by default
199
+ const ns = NamespaceEnv({ name: "prod", defaultDenyIngress: true, defaultDenyEgress: true });
200
+
201
+ // App: allow specific traffic
202
+ const app = NetworkIsolatedApp({
203
+ name: "api",
204
+ image: "api:1.0",
205
+ namespace: "prod",
206
+ allowIngressFrom: [{ podSelector: { "app.kubernetes.io/name": "gateway" } }],
207
+ allowEgressTo: [{ podSelector: { "app.kubernetes.io/name": "db" }, ports: [{ port: 5432 }] }],
208
+ });
209
+ ```
210
+
211
+ ## Blue/Green and Canary
212
+
213
+ These patterns use standard K8s resources — no special composite needed.
214
+
215
+ ### Blue/Green
216
+
217
+ ```typescript
218
+ // Two Deployments with different versions
219
+ const blue = WebApp({ name: "app-blue", image: "app:1.0", labels: { version: "blue" } });
220
+ const green = WebApp({ name: "app-green", image: "app:2.0", labels: { version: "green" } });
221
+
222
+ // Service points to active version — switch by changing selector
223
+ // Active: blue → green (update the Service selector)
224
+ ```
225
+
226
+ ### Canary
227
+
228
+ ```typescript
229
+ // Main deployment (90% traffic)
230
+ const main = AutoscaledService({ name: "app", image: "app:1.0", minReplicas: 9, maxReplicas: 20, ... });
231
+
232
+ // Canary deployment (10% traffic) — same app label, fewer replicas
233
+ const canary = WebApp({ name: "app-canary", image: "app:2.0", replicas: 1, labels: { track: "canary" } });
234
+ // Both share the same Service selector ("app.kubernetes.io/name": "app") for traffic splitting
235
+ ```
236
+
237
+ ## Gateway API (future direction)
238
+
239
+ Gateway API is the successor to Ingress. Key differences:
240
+ - **HTTPRoute** replaces Ingress rules
241
+ - **Gateway** replaces IngressClass
242
+ - Built-in traffic splitting, header matching, URL rewriting
243
+ - Currently in beta — use Ingress/SecureIngress/AlbIngress for production today
244
+
245
+ When Gateway API reaches GA, new composites will be added. For now, use CRD import if you need Gateway API resources.
@@ -126,20 +126,6 @@ kubectl port-forward pod/<pod-name> 8080:8080
126
126
  | CreateContainerError | Container config issue | `kubectl describe pod` → Events | Check volume mounts, configmap/secret refs, security context |
127
127
  | Init:CrashLoopBackOff | Init container failing | `kubectl logs -c <init-container>` | Fix init container command, check dependencies |
128
128
 
129
- ### Resource inspection
130
-
131
- ```bash
132
- # Get all resources in namespace
133
- kubectl get all -n <namespace>
134
-
135
- # YAML output for debugging
136
- kubectl get deployment/my-app -o yaml
137
-
138
- # Check resource usage
139
- kubectl top pods -l app.kubernetes.io/name=my-app
140
- kubectl top nodes
141
- ```
142
-
143
129
  ## Production safety
144
130
 
145
131
  ### Pre-apply validation
@@ -155,22 +141,6 @@ kubectl apply -f manifests.yaml --dry-run=server
155
141
  kubectl apply -f manifests.yaml --dry-run=client
156
142
  ```
157
143
 
158
- ### Rollback
159
-
160
- ```bash
161
- # Check rollout history
162
- kubectl rollout history deployment/my-app
163
-
164
- # Undo last rollout
165
- kubectl rollout undo deployment/my-app
166
-
167
- # Roll back to a specific revision
168
- kubectl rollout undo deployment/my-app --to-revision=2
169
-
170
- # Watch rollout progress
171
- kubectl rollout status deployment/my-app --timeout=300s
172
- ```
173
-
174
144
  ### Deployment strategies
175
145
 
176
146
  - **RollingUpdate** (default): Gradually replaces pods. Set `maxSurge` and `maxUnavailable`.
@@ -178,157 +148,42 @@ kubectl rollout status deployment/my-app --timeout=300s
178
148
  - **Canary**: Deploy a second Deployment with 1 replica + same selector labels. Route percentage via Ingress annotations or service mesh.
179
149
  - **Blue/Green**: Two full Deployments (blue/green), switch Service selector between them.
180
150
 
181
- ## Composites
182
-
183
- Composites are higher-level functions that produce multiple coordinated K8s resources from a single call. They return plain prop objects — not class instances — that you pass to generated constructors or serialize directly.
184
-
185
- ### WebApp — Deployment + Service + optional Ingress
186
-
187
- ```typescript
188
- import { WebApp } from "@intentius/chant-lexicon-k8s";
189
-
190
- const { deployment, service, ingress } = WebApp({
191
- name: "frontend",
192
- image: "frontend:1.0",
193
- port: 3000,
194
- replicas: 3,
195
- ingressHost: "frontend.example.com",
196
- ingressTlsSecret: "frontend-tls",
197
- });
198
- ```
199
-
200
- ### StatefulApp StatefulSet + headless Service + PVC
201
-
202
- ```typescript
203
- import { StatefulApp } from "@intentius/chant-lexicon-k8s";
204
-
205
- const { statefulSet, service } = StatefulApp({
206
- name: "postgres",
207
- image: "postgres:16",
208
- storageSize: "20Gi",
209
- env: [{ name: "POSTGRES_DB", value: "mydb" }],
210
- });
211
- ```
212
-
213
- ### CronWorkloadCronJob + ServiceAccount + Role + RoleBinding
214
-
215
- ```typescript
216
- import { CronWorkload } from "@intentius/chant-lexicon-k8s";
217
-
218
- const { cronJob, serviceAccount, role, roleBinding } = CronWorkload({
219
- name: "db-backup",
220
- image: "postgres:16",
221
- schedule: "0 2 * * *",
222
- command: ["pg_dump", "-h", "postgres", "mydb"],
223
- rbacRules: [{ apiGroups: [""], resources: ["secrets"], verbs: ["get"] }],
224
- });
225
- ```
226
-
227
- ### AutoscaledService — Deployment + Service + HPA + PDB
228
-
229
- Production HTTP service with autoscaling, health probes, and optional topology spreading.
230
-
231
- ```typescript
232
- import { AutoscaledService } from "@intentius/chant-lexicon-k8s";
233
-
234
- const { deployment, service, hpa, pdb } = AutoscaledService({
235
- name: "api",
236
- image: "api:2.0",
237
- port: 8080,
238
- maxReplicas: 10,
239
- minReplicas: 3,
240
- cpuRequest: "200m",
241
- memoryRequest: "256Mi",
242
- cpuLimit: "1",
243
- memoryLimit: "1Gi",
244
- // Probe paths — defaults: /healthz and /readyz
245
- livenessPath: "/healthz",
246
- readinessPath: "/readyz",
247
- // Zone-aware topology spreading (default: false)
248
- topologySpread: true,
249
- // Custom: topologySpread: { maxSkew: 2, topologyKey: "kubernetes.io/hostname" }
250
- });
251
- ```
252
-
253
- Key features:
254
- - **Probe paths**: `livenessPath` (default `/healthz`) and `readinessPath` (default `/readyz`) — override for apps that don't serve those routes
255
- - **Topology spread**: `topologySpread: true` adds zone-aware spreading (maxSkew=1, DoNotSchedule); pass an object for custom key/skew
256
- - **PDB minAvailable**: accepts number or string percentage (e.g., `"50%"`)
257
-
258
- ### WorkerPool — Deployment + RBAC + optional ConfigMap + optional HPA
259
-
260
- Background queue workers with optional RBAC and autoscaling.
261
-
262
- ```typescript
263
- import { WorkerPool } from "@intentius/chant-lexicon-k8s";
264
-
265
- const { deployment, serviceAccount, role, roleBinding, configMap, hpa } = WorkerPool({
266
- name: "email-worker",
267
- image: "worker:1.0",
268
- command: ["bundle", "exec", "sidekiq"],
269
- config: { REDIS_URL: "redis://redis:6379", QUEUE: "emails" },
270
- autoscaling: { minReplicas: 2, maxReplicas: 20, targetCPUPercent: 60 },
271
- });
272
- ```
273
-
274
- Key features:
275
- - **RBAC opt-out**: Pass `rbacRules: []` to skip ServiceAccount/Role/RoleBinding creation entirely. Omitting `rbacRules` (undefined) creates default rules for secrets/configmaps.
276
- - `serviceAccount`, `role`, `roleBinding` are optional in the result — check before use
277
-
278
- ### NamespaceEnv — Namespace + ResourceQuota + LimitRange + NetworkPolicy
279
-
280
- Multi-tenant namespace provisioning with resource guardrails and network isolation.
281
-
282
- ```typescript
283
- import { NamespaceEnv } from "@intentius/chant-lexicon-k8s";
284
-
285
- const { namespace, resourceQuota, limitRange, networkPolicy } = NamespaceEnv({
286
- name: "team-alpha",
287
- cpuQuota: "8",
288
- memoryQuota: "16Gi",
289
- maxPods: 50,
290
- defaultCpuRequest: "100m",
291
- defaultMemoryRequest: "128Mi",
292
- defaultCpuLimit: "500m",
293
- defaultMemoryLimit: "512Mi",
294
- defaultDenyIngress: true,
295
- defaultDenyEgress: true,
296
- });
297
- ```
298
-
299
- Key features:
300
- - **Quota-without-limits warning**: Setting ResourceQuota without LimitRange defaults emits a warning — pods without explicit resource requests will fail to schedule
301
- - **Network policies**: `defaultDenyIngress` (default true), `defaultDenyEgress` (default false) — can be combined or used individually
302
-
303
- ### NodeAgent — DaemonSet + ServiceAccount + ClusterRole + ClusterRoleBinding + optional ConfigMap
304
-
305
- Per-node agents (log collectors, security scanners, monitoring exporters).
306
-
307
- ```typescript
308
- import { NodeAgent } from "@intentius/chant-lexicon-k8s";
309
-
310
- const { daemonSet, serviceAccount, clusterRole, clusterRoleBinding, configMap } = NodeAgent({
311
- name: "log-collector",
312
- image: "fluentd:v1.16",
313
- port: 24224,
314
- hostPaths: [
315
- { name: "varlog", hostPath: "/var/log", mountPath: "/var/log" },
316
- ],
317
- config: { "fluent.conf": "..." },
318
- rbacRules: [{ apiGroups: [""], resources: ["pods", "namespaces"], verbs: ["get", "list", "watch"] }],
319
- cpuRequest: "50m", // default: 50m
320
- memoryRequest: "64Mi", // default: 64Mi
321
- cpuLimit: "200m", // default: 200m
322
- memoryLimit: "128Mi", // default: 128Mi
323
- namespace: "monitoring",
324
- });
325
- ```
326
-
327
- Key features:
328
- - **Container resources**: Always set with sensible defaults (50m/64Mi requests, 200m/128Mi limits) — override per-agent
329
- - **Host paths**: Mounted read-only by default; set `readOnly: false` to enable writes
330
- - **Tolerations**: `tolerateAllTaints: true` (default) ensures agent runs on every node
331
- - Uses **ClusterRole/ClusterRoleBinding** (cluster-scoped) for node-level access
151
+ ## Choosing the Right Composite
152
+
153
+ Composites are higher-level functions that produce multiple coordinated K8s resources from a single call. They return plain prop objects — not class instances.
154
+
155
+ ### Decision Tree
156
+
157
+ | Need | Composite | Resources |
158
+ |------|-----------|-----------|
159
+ | Stateless web app | **WebApp** | Deployment + Service + optional Ingress + optional PDB |
160
+ | Stateful database/cache | **StatefulApp** | StatefulSet + headless Service + PVC + optional PDB |
161
+ | Production HTTP service with autoscaling | **AutoscaledService** | Deployment + Service + HPA + PDB |
162
+ | Background queue workers | **WorkerPool** | Deployment + RBAC + optional ConfigMap + optional HPA + optional PDB |
163
+ | Scheduled jobs | **CronWorkload** | CronJob + RBAC |
164
+ | One-shot batch jobs | **BatchJob** | Job + optional RBAC |
165
+ | App with ConfigMap/Secret mounts | **ConfiguredApp** | Deployment + Service + optional ConfigMap |
166
+ | Multi-container sidecar patterns | **SidecarApp** | Deployment + Service |
167
+ | App with Prometheus monitoring | **MonitoredService** | Deployment + Service + ServiceMonitor + optional PrometheusRule |
168
+ | App with fine-grained network policies | **NetworkIsolatedApp** | Deployment + Service + NetworkPolicy |
169
+ | Namespace with quotas and isolation | **NamespaceEnv** | Namespace + ResourceQuota + LimitRange + NetworkPolicy |
170
+ | Per-node agent (custom) | **NodeAgent** | DaemonSet + RBAC + optional ConfigMap |
171
+ | Multi-host TLS Ingress (cert-manager) | **SecureIngress** | Ingress + optional Certificate |
172
+ | EKS IRSA ServiceAccount | **IrsaServiceAccount** | ServiceAccount + optional RBAC |
173
+ | AWS ALB Ingress | **AlbIngress** | Ingress with ALB annotations |
174
+ | EBS StorageClass | **EbsStorageClass** | StorageClass (ebs.csi.aws.com) |
175
+ | EFS StorageClass | **EfsStorageClass** | StorageClass (efs.csi.aws.com) |
176
+ | Fluent Bit for CloudWatch | **FluentBitAgent** | DaemonSet + RBAC + ConfigMap |
177
+ | ExternalDNS for Route53 | **ExternalDnsAgent** | Deployment + IRSA SA + ClusterRole |
178
+ | ADOT for CloudWatch/X-Ray | **AdotCollector** | DaemonSet + RBAC + ConfigMap |
179
+
180
+ ### Hardening options (available on Deployment-based composites)
181
+
182
+ - `minAvailable` — creates a PodDisruptionBudget (WebApp, StatefulApp, WorkerPool; AutoscaledService always has one)
183
+ - `initContainers`run before main containers (WebApp, StatefulApp, AutoscaledService, ConfiguredApp, SidecarApp)
184
+ - `securityContext` — container security settings (WebApp, StatefulApp, AutoscaledService, WorkerPool)
185
+ - `terminationGracePeriodSeconds` — graceful shutdown (WebApp, StatefulApp, AutoscaledService, WorkerPool)
186
+ - `priorityClassName` pod scheduling priority (WebApp, StatefulApp, AutoscaledService, WorkerPool)
332
187
 
333
188
  ### Common patterns across all composites
334
189
 
@@ -337,49 +192,6 @@ Key features:
337
192
  - Pass `namespace: "prod"` to set namespace on all namespaced resources
338
193
  - Pass `env: [{ name: "KEY", value: "val" }]` for container environment variables
339
194
 
340
- ## Namespace management
341
-
342
- Use the **NamespaceEnv** composite (above) to manage namespaces declaratively. For manual kubectl management:
343
-
344
- ```bash
345
- # Create namespace
346
- kubectl create namespace my-project
347
-
348
- # Set default resource quotas
349
- kubectl apply -f - <<EOF
350
- apiVersion: v1
351
- kind: ResourceQuota
352
- metadata:
353
- name: default-quota
354
- namespace: my-project
355
- spec:
356
- hard:
357
- requests.cpu: "4"
358
- requests.memory: 8Gi
359
- limits.cpu: "8"
360
- limits.memory: 16Gi
361
- pods: "20"
362
- EOF
363
-
364
- # Set default container limits via LimitRange
365
- kubectl apply -f - <<EOF
366
- apiVersion: v1
367
- kind: LimitRange
368
- metadata:
369
- name: default-limits
370
- namespace: my-project
371
- spec:
372
- limits:
373
- - default:
374
- cpu: 500m
375
- memory: 256Mi
376
- defaultRequest:
377
- cpu: 100m
378
- memory: 128Mi
379
- type: Container
380
- EOF
381
- ```
382
-
383
195
  ## Troubleshooting reference table
384
196
 
385
197
  | Symptom | Likely cause | Resolution |
@@ -388,11 +200,8 @@ EOF
388
200
  | Pod stuck in Pending | PVC not bound | Check StorageClass exists, PV available |
389
201
  | Pod stuck in Pending | Node selector/affinity mismatch | Verify node labels match selectors |
390
202
  | Pod stuck in ContainerCreating | ConfigMap/Secret not found | Ensure referenced ConfigMaps/Secrets exist |
391
- | Pod stuck in ContainerCreating | Volume mount failure | Check PVC status, CSI driver health |
392
203
  | Service returns 503 | No ready endpoints | Check pod readiness probes, selector match |
393
- | Service returns 503 | Wrong port configuration | Verify targetPort matches containerPort |
394
204
  | Ingress returns 404 | Backend service not found | Check Ingress rules, service name/port |
395
- | Ingress returns 404 | Wrong path matching | Check pathType (Prefix vs Exact) |
396
205
  | HPA not scaling | Metrics server not installed | Install metrics-server |
397
206
  | HPA not scaling | Resource requests not set | Add CPU/memory requests to containers |
398
207
  | CronJob not running | Invalid cron expression | Validate cron syntax (5-field format) |
package/package.json CHANGED
@@ -1,30 +1,33 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-k8s",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
- "files": ["src/", "dist/"],
6
+ "files": [
7
+ "src/",
8
+ "dist/"
9
+ ],
7
10
  "publishConfig": {
8
- "access": "public"
9
- },
10
- "exports": {
11
- ".": "./src/index.ts",
12
- "./*": "./src/*",
13
- "./manifest": "./dist/manifest.json",
14
- "./meta": "./dist/meta.json",
15
- "./types": "./dist/types/index.d.ts"
16
- },
17
- "scripts": {
18
- "generate": "bun run src/codegen/generate-cli.ts",
19
- "bundle": "bun run src/package-cli.ts",
20
- "validate": "bun run src/validate-cli.ts",
21
- "docs": "bun run src/codegen/docs-cli.ts",
22
- "prepack": "bun run generate && bun run bundle && bun run validate"
23
- },
24
- "dependencies": {
25
- "@intentius/chant": "0.0.12"
26
- },
27
- "devDependencies": {
28
- "typescript": "^5.9.3"
29
- }
11
+ "access": "public"
12
+ },
13
+ "exports": {
14
+ ".": "./src/index.ts",
15
+ "./*": "./src/*.ts",
16
+ "./manifest": "./dist/manifest.json",
17
+ "./meta": "./dist/meta.json",
18
+ "./types": "./dist/types/index.d.ts"
19
+ },
20
+ "scripts": {
21
+ "generate": "bun run src/codegen/generate-cli.ts",
22
+ "bundle": "bun run src/package-cli.ts",
23
+ "validate": "bun run src/validate-cli.ts",
24
+ "docs": "bun run src/codegen/docs-cli.ts",
25
+ "prepack": "bun run generate && bun run bundle && bun run validate"
26
+ },
27
+ "dependencies": {
28
+ "@intentius/chant": "0.0.15"
29
+ },
30
+ "devDependencies": {
31
+ "typescript": "^5.9.3"
32
+ }
30
33
  }
@@ -18,7 +18,7 @@ function serviceFromType(resourceType: string): string {
18
18
 
19
19
  const overview = `The **Kubernetes** lexicon provides typed constructors for Kubernetes resource
20
20
  manifests. It covers Deployments, Services, ConfigMaps, StatefulSets, Jobs,
21
- Ingress, RBAC, and 50+ additional resource and property types.
21
+ Ingress, RBAC, and 147 resources and 50 property types.
22
22
 
23
23
  New? Start with the [Getting Started](/chant/lexicons/k8s/getting-started/) guide.
24
24
 
@@ -64,7 +64,7 @@ export const service = new Service({
64
64
  });
65
65
  \`\`\`
66
66
 
67
- The lexicon provides **50+ resource types** (Deployment, Service, ConfigMap, StatefulSet, and more), **35+ property types** (Container, Probe, Volume, SecurityContext, etc.), and composites (WebApp, StatefulApp, CronWorkload, AutoscaledService, WorkerPool, NamespaceEnv, NodeAgent) for common patterns.
67
+ The lexicon provides **147 resource types** (Deployment, Service, ConfigMap, StatefulSet, and more), **50 property types** (Container, Probe, Volume, SecurityContext, etc.), and composites (WebApp, StatefulApp, CronWorkload, AutoscaledService, WorkerPool, NamespaceEnv, NodeAgent) for common patterns.
68
68
  `;
69
69
 
70
70
  const outputFormat = `The Kubernetes lexicon serializes resources into **multi-document YAML** with
@@ -76,7 +76,7 @@ structure: \`apiVersion\`, \`kind\`, \`metadata\`, and \`spec\`.
76
76
  Run \`chant build\` to produce Kubernetes manifests from your declarations:
77
77
 
78
78
  \`\`\`bash
79
- chant build
79
+ chant build src/ --output dist/manifests.yaml
80
80
  # Writes dist/manifests.yaml
81
81
  \`\`\`
82
82
 
@@ -134,7 +134,7 @@ export async function generateDocs(opts?: { verbose?: boolean }): Promise<void>
134
134
  overview,
135
135
  outputFormat,
136
136
  serviceFromType,
137
- suppressPages: ["pseudo-parameters"],
137
+ suppressPages: ["pseudo-parameters", "rules"],
138
138
  extraPages: [
139
139
  {
140
140
  slug: "getting-started",
@@ -1102,7 +1102,7 @@ Skills are structured markdown documents bundled with a lexicon. When an AI agen
1102
1102
 
1103
1103
  ## Installation
1104
1104
 
1105
- When you scaffold a new project with \`chant init --lexicon k8s\`, the skill is installed to \`.claude/skills/chant-k8s/SKILL.md\` for automatic discovery by Claude Code.
1105
+ When you scaffold a new project with \`chant init --lexicon k8s\`, the skill is installed to \`skills/chant-k8s/SKILL.md\` for automatic discovery by Claude Code.
1106
1106
 
1107
1107
  ## Skill: chant-k8s
1108
1108