@intentius/chant-lexicon-k8s 0.0.12 → 0.0.14

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.
package/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # @intentius/chant-lexicon-k8s
2
+
3
+ Kubernetes lexicon for [chant](https://intentius.io/chant/) — declare infrastructure as typed TypeScript that serializes to Kubernetes YAML manifests.
4
+
5
+ This package provides typed constructors for all core Kubernetes resource types (Deployments, Services, ConfigMaps, Secrets, StatefulSets, and more), property types (Containers, Volumes, Probes, etc.), composites for common patterns, and K8s-specific lint rules. It also includes LSP and MCP server support for editor completions and hover.
6
+
7
+ ```bash
8
+ npm install --save-dev @intentius/chant @intentius/chant-lexicon-k8s
9
+ ```
10
+
11
+ **[Documentation →](https://intentius.io/chant/lexicons/k8s/)**
12
+
13
+ ## Related Packages
14
+
15
+ | Package | Role |
16
+ |---------|------|
17
+ | [@intentius/chant](https://www.npmjs.com/package/@intentius/chant) | Core type system, CLI, build pipeline |
18
+ | [@intentius/chant-lexicon-aws](https://www.npmjs.com/package/@intentius/chant-lexicon-aws) | AWS CloudFormation lexicon |
19
+ | [@intentius/chant-lexicon-gitlab](https://www.npmjs.com/package/@intentius/chant-lexicon-gitlab) | GitLab CI lexicon |
20
+ | [@intentius/chant-lexicon-flyway](https://www.npmjs.com/package/@intentius/chant-lexicon-flyway) | Flyway migration lexicon |
21
+
22
+ ## License
23
+
24
+ See the main project LICENSE file.
@@ -1,32 +1,34 @@
1
1
  {
2
2
  "algorithm": "xxhash64",
3
3
  "artifacts": {
4
- "manifest.json": "a9f93ff8c0a8f750",
4
+ "manifest.json": "59b066d7c2f8d709",
5
5
  "meta.json": "1ce194f36f9b5f90",
6
6
  "types/index.d.ts": "beec4cc869064186",
7
7
  "rules/hardcoded-namespace.ts": "54b216c71018e101",
8
- "rules/wk8006.ts": "6e04f754f79f076e",
9
8
  "rules/wk8201.ts": "4dbbd20e21b5fa04",
10
- "rules/wk8103.ts": "e5d6a506d966e312",
11
- "rules/k8s-helpers.ts": "53a6d3bfbedb2852",
9
+ "rules/wk8204.ts": "31c3f8eac8455795",
12
10
  "rules/wk8301.ts": "283265ab0c5b8511",
13
- "rules/wk8105.ts": "8dbcfe399f23656a",
11
+ "rules/wk8102.ts": "78d4aac387107b56",
14
12
  "rules/wk8101.ts": "f8ffcf6e5c89076b",
15
13
  "rules/wk8302.ts": "a80d1eab37c0dbe4",
14
+ "rules/wk8005.ts": "a9a1b93b80f3aa51",
15
+ "rules/wk8209.ts": "820df53f304e0a59",
16
16
  "rules/wk8203.ts": "f5bf17539c0428c5",
17
- "rules/wk8042.ts": "6064c84481ae8551",
18
- "rules/wk8202.ts": "6bd950ae2128256c",
19
- "rules/wk8207.ts": "6f2bc621d530afa2",
20
17
  "rules/wk8104.ts": "94bd75c16b8d50b7",
18
+ "rules/wk8303.ts": "c545464e2af8fbb9",
19
+ "rules/wk8103.ts": "e5d6a506d966e312",
21
20
  "rules/wk8205.ts": "d000527c6371a05",
21
+ "rules/wk8042.ts": "6064c84481ae8551",
22
+ "rules/wk8006.ts": "6e04f754f79f076e",
22
23
  "rules/wk8041.ts": "4df512c93caaef50",
23
- "rules/wk8102.ts": "78d4aac387107b56",
24
- "rules/wk8005.ts": "a9a1b93b80f3aa51",
25
- "rules/wk8303.ts": "c545464e2af8fbb9",
26
- "rules/wk8204.ts": "31c3f8eac8455795",
24
+ "rules/wk8202.ts": "6bd950ae2128256c",
27
25
  "rules/wk8208.ts": "1133f9e53c174ae9",
28
- "rules/wk8209.ts": "820df53f304e0a59",
29
- "skills/chant-k8s.md": "f1c4ed163f8fa84c"
26
+ "rules/wk8105.ts": "8dbcfe399f23656a",
27
+ "rules/k8s-helpers.ts": "53a6d3bfbedb2852",
28
+ "rules/wk8207.ts": "6f2bc621d530afa2",
29
+ "skills/chant-k8s.md": "c7db82c3ba37c78",
30
+ "skills/chant-k8s-eks.md": "f79f31f058c7f2ed",
31
+ "skills/chant-k8s-patterns.md": "c5151ed799145c4b"
30
32
  },
31
- "composite": "cfc40ee5b5214cda"
33
+ "composite": "586aea18d5400dd8"
32
34
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "k8s",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "chantVersion": ">=0.1.0",
5
5
  "namespace": "K8s",
6
6
  "intrinsics": [],
@@ -0,0 +1,156 @@
1
+ ---
2
+ skill: chant-k8s-eks
3
+ description: EKS-specific Kubernetes patterns and composites
4
+ user-invocable: true
5
+ ---
6
+
7
+ # EKS Kubernetes Patterns
8
+
9
+ ## EKS Composites Overview
10
+
11
+ These composites produce K8s YAML with EKS-specific annotations and configurations.
12
+
13
+ ### IrsaServiceAccount — ServiceAccount with IAM Role annotation
14
+
15
+ ```typescript
16
+ import { IrsaServiceAccount } from "@intentius/chant-lexicon-k8s";
17
+
18
+ const { serviceAccount, role, roleBinding } = IrsaServiceAccount({
19
+ name: "app-sa",
20
+ iamRoleArn: "arn:aws:iam::123456789012:role/my-app-role",
21
+ rbacRules: [
22
+ { apiGroups: [""], resources: ["secrets"], verbs: ["get"] },
23
+ ],
24
+ namespace: "prod",
25
+ });
26
+ ```
27
+
28
+ ### AlbIngress — Ingress with AWS ALB Controller annotations
29
+
30
+ ```typescript
31
+ import { AlbIngress } from "@intentius/chant-lexicon-k8s";
32
+
33
+ const { ingress } = AlbIngress({
34
+ name: "api-ingress",
35
+ hosts: [
36
+ {
37
+ hostname: "api.example.com",
38
+ paths: [{ path: "/", serviceName: "api", servicePort: 80 }],
39
+ },
40
+ ],
41
+ scheme: "internet-facing",
42
+ certificateArn: "arn:aws:acm:us-east-1:123456789012:certificate/abc-123",
43
+ groupName: "shared-alb",
44
+ healthCheckPath: "/healthz",
45
+ });
46
+ ```
47
+
48
+ Features:
49
+ - Auto-sets `alb.ingress.kubernetes.io/*` annotations
50
+ - SSL redirect enabled by default when `certificateArn` set
51
+ - `groupName` for shared ALB across multiple Ingresses
52
+ - `wafAclArn` for WAFv2 integration
53
+
54
+ ### EbsStorageClass — StorageClass for EBS CSI
55
+
56
+ ```typescript
57
+ import { EbsStorageClass } from "@intentius/chant-lexicon-k8s";
58
+
59
+ const { storageClass } = EbsStorageClass({
60
+ name: "gp3-encrypted",
61
+ type: "gp3",
62
+ encrypted: true,
63
+ iops: "3000",
64
+ throughput: "125",
65
+ });
66
+ ```
67
+
68
+ ### EfsStorageClass — StorageClass for EFS CSI (ReadWriteMany)
69
+
70
+ ```typescript
71
+ import { EfsStorageClass } from "@intentius/chant-lexicon-k8s";
72
+
73
+ const { storageClass } = EfsStorageClass({
74
+ name: "efs-shared",
75
+ fileSystemId: "fs-12345678",
76
+ });
77
+ ```
78
+
79
+ Use EFS when you need ReadWriteMany (shared across pods/nodes). Use EBS for ReadWriteOnce (single pod).
80
+
81
+ ### FluentBitAgent — DaemonSet for CloudWatch logging
82
+
83
+ ```typescript
84
+ import { FluentBitAgent } from "@intentius/chant-lexicon-k8s";
85
+
86
+ const result = FluentBitAgent({
87
+ logGroup: "/aws/eks/my-cluster/containers",
88
+ region: "us-east-1",
89
+ clusterName: "my-cluster",
90
+ });
91
+ ```
92
+
93
+ ### ExternalDnsAgent — ExternalDNS for Route53
94
+
95
+ ```typescript
96
+ import { ExternalDnsAgent } from "@intentius/chant-lexicon-k8s";
97
+
98
+ const result = ExternalDnsAgent({
99
+ iamRoleArn: "arn:aws:iam::123456789012:role/external-dns-role",
100
+ domainFilters: ["example.com"],
101
+ txtOwnerId: "my-cluster",
102
+ });
103
+ ```
104
+
105
+ ### AdotCollector — ADOT for CloudWatch/X-Ray
106
+
107
+ ```typescript
108
+ import { AdotCollector } from "@intentius/chant-lexicon-k8s";
109
+
110
+ const result = AdotCollector({
111
+ region: "us-east-1",
112
+ clusterName: "my-cluster",
113
+ exporters: ["cloudwatch", "xray"],
114
+ });
115
+ ```
116
+
117
+ ## Pod Identity vs IRSA
118
+
119
+ | Feature | IRSA | Pod Identity |
120
+ |---------|------|-------------|
121
+ | K8s annotation needed | Yes (`eks.amazonaws.com/role-arn`) | No |
122
+ | Composite available | **IrsaServiceAccount** | None needed |
123
+ | Setup | OIDC provider + IAM role trust policy | EKS Pod Identity Agent add-on + association |
124
+ | When to use | Existing clusters, broad compatibility | New clusters (EKS 1.28+), simpler management |
125
+
126
+ For Pod Identity, no K8s-side composite is needed — configure the association via AWS API/CloudFormation and use a plain ServiceAccount.
127
+
128
+ ## Karpenter
129
+
130
+ Karpenter replaces Cluster Autoscaler for node provisioning. Karpenter NodePool and EC2NodeClass are simple CRDs — use CRD import rather than composites:
131
+
132
+ ```bash
133
+ # Import Karpenter CRDs into your chant project
134
+ chant import --url https://raw.githubusercontent.com/aws/karpenter/main/pkg/apis/crds/karpenter.sh_nodepools.yaml
135
+ ```
136
+
137
+ ## Fargate Considerations
138
+
139
+ When running on EKS Fargate:
140
+ - **No DaemonSets** — FluentBitAgent and AdotCollector cannot run on Fargate nodes
141
+ - **No hostPath volumes** — use EFS for shared storage
142
+ - **No privileged containers** — security context restrictions apply
143
+ - For Fargate logging, use the built-in Fluent Bit log router (Fargate logging configuration)
144
+
145
+ ## EKS Add-ons
146
+
147
+ Common add-ons managed via AWS (not K8s manifests):
148
+ - **vpc-cni** — Amazon VPC CNI plugin
149
+ - **coredns** — Cluster DNS
150
+ - **kube-proxy** — Network proxy
151
+ - **aws-ebs-csi-driver** — EBS CSI driver (required for EbsStorageClass)
152
+ - **aws-efs-csi-driver** — EFS CSI driver (required for EfsStorageClass)
153
+ - **adot** — AWS Distro for OpenTelemetry (alternative to AdotCollector composite)
154
+ - **aws-guardduty-agent** — Runtime threat detection
155
+
156
+ Configure add-ons via the AWS lexicon (`@intentius/chant-lexicon-aws`) CloudFormation resources.
@@ -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.