@intentius/chant-lexicon-k8s 0.0.15 → 0.0.18

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/src/plugin.ts CHANGED
@@ -18,7 +18,9 @@ export const k8sPlugin: LexiconPlugin = {
18
18
 
19
19
  lintRules(): LintRule[] {
20
20
  const { hardcodedNamespaceRule } = require("./lint/rules/hardcoded-namespace");
21
- return [hardcodedNamespaceRule];
21
+ const { latestImageTagRule } = require("./lint/rules/latest-image-tag");
22
+ const { missingResourceLimitsRule } = require("./lint/rules/missing-resource-limits");
23
+ return [hardcodedNamespaceRule, latestImageTagRule, missingResourceLimitsRule];
22
24
  },
23
25
 
24
26
  postSynthChecks(): PostSynthCheck[] {
@@ -715,213 +717,6 @@ const { job, serviceAccount, role, roleBinding } = BatchJob({
715
717
  command: ["python", "manage.py", "migrate"],
716
718
  backoffLimit: 3,
717
719
  ttlSecondsAfterFinished: 3600,
718
- });`,
719
- },
720
- ],
721
- },
722
- {
723
- name: "chant-k8s-eks",
724
- description: "EKS-specific Kubernetes composites — IRSA, ALB, EBS/EFS, Fluent Bit, ExternalDNS, ADOT",
725
- content: `---
726
- skill: chant-k8s-eks
727
- description: EKS-specific Kubernetes patterns and composites
728
- user-invocable: true
729
- ---
730
-
731
- # EKS Kubernetes Patterns
732
-
733
- ## EKS Composites Overview
734
-
735
- These composites produce K8s YAML with EKS-specific annotations and configurations.
736
-
737
- ### IrsaServiceAccount — ServiceAccount with IAM Role annotation
738
-
739
- \`\`\`typescript
740
- import { IrsaServiceAccount } from "@intentius/chant-lexicon-k8s";
741
-
742
- const { serviceAccount, role, roleBinding } = IrsaServiceAccount({
743
- name: "app-sa",
744
- iamRoleArn: "arn:aws:iam::123456789012:role/my-app-role",
745
- rbacRules: [
746
- { apiGroups: [""], resources: ["secrets"], verbs: ["get"] },
747
- ],
748
- namespace: "prod",
749
- });
750
- \`\`\`
751
-
752
- ### AlbIngress — Ingress with AWS ALB Controller annotations
753
-
754
- \`\`\`typescript
755
- import { AlbIngress } from "@intentius/chant-lexicon-k8s";
756
-
757
- const { ingress } = AlbIngress({
758
- name: "api-ingress",
759
- hosts: [
760
- {
761
- hostname: "api.example.com",
762
- paths: [{ path: "/", serviceName: "api", servicePort: 80 }],
763
- },
764
- ],
765
- scheme: "internet-facing",
766
- certificateArn: "arn:aws:acm:us-east-1:123456789012:certificate/abc-123",
767
- groupName: "shared-alb",
768
- healthCheckPath: "/healthz",
769
- });
770
- \`\`\`
771
-
772
- Features:
773
- - Auto-sets \`alb.ingress.kubernetes.io/*\` annotations
774
- - SSL redirect enabled by default when \`certificateArn\` set
775
- - \`groupName\` for shared ALB across multiple Ingresses
776
- - \`wafAclArn\` for WAFv2 integration
777
-
778
- ### EbsStorageClass — StorageClass for EBS CSI
779
-
780
- \`\`\`typescript
781
- import { EbsStorageClass } from "@intentius/chant-lexicon-k8s";
782
-
783
- const { storageClass } = EbsStorageClass({
784
- name: "gp3-encrypted",
785
- type: "gp3",
786
- encrypted: true,
787
- iops: "3000",
788
- throughput: "125",
789
- });
790
- \`\`\`
791
-
792
- ### EfsStorageClass — StorageClass for EFS CSI (ReadWriteMany)
793
-
794
- \`\`\`typescript
795
- import { EfsStorageClass } from "@intentius/chant-lexicon-k8s";
796
-
797
- const { storageClass } = EfsStorageClass({
798
- name: "efs-shared",
799
- fileSystemId: "fs-12345678",
800
- });
801
- \`\`\`
802
-
803
- Use EFS when you need ReadWriteMany (shared across pods/nodes). Use EBS for ReadWriteOnce (single pod).
804
-
805
- ### FluentBitAgent — DaemonSet for CloudWatch logging
806
-
807
- \`\`\`typescript
808
- import { FluentBitAgent } from "@intentius/chant-lexicon-k8s";
809
-
810
- const result = FluentBitAgent({
811
- logGroup: "/aws/eks/my-cluster/containers",
812
- region: "us-east-1",
813
- clusterName: "my-cluster",
814
- });
815
- \`\`\`
816
-
817
- ### ExternalDnsAgent — ExternalDNS for Route53
818
-
819
- \`\`\`typescript
820
- import { ExternalDnsAgent } from "@intentius/chant-lexicon-k8s";
821
-
822
- const result = ExternalDnsAgent({
823
- iamRoleArn: "arn:aws:iam::123456789012:role/external-dns-role",
824
- domainFilters: ["example.com"],
825
- txtOwnerId: "my-cluster",
826
- });
827
- \`\`\`
828
-
829
- ### AdotCollector — ADOT for CloudWatch/X-Ray
830
-
831
- \`\`\`typescript
832
- import { AdotCollector } from "@intentius/chant-lexicon-k8s";
833
-
834
- const result = AdotCollector({
835
- region: "us-east-1",
836
- clusterName: "my-cluster",
837
- exporters: ["cloudwatch", "xray"],
838
- });
839
- \`\`\`
840
-
841
- ## Pod Identity vs IRSA
842
-
843
- | Feature | IRSA | Pod Identity |
844
- |---------|------|-------------|
845
- | K8s annotation needed | Yes (\`eks.amazonaws.com/role-arn\`) | No |
846
- | Composite available | **IrsaServiceAccount** | None needed |
847
- | Setup | OIDC provider + IAM role trust policy | EKS Pod Identity Agent add-on + association |
848
- | When to use | Existing clusters, broad compatibility | New clusters (EKS 1.28+), simpler management |
849
-
850
- For Pod Identity, no K8s-side composite is needed — configure the association via AWS API/CloudFormation and use a plain ServiceAccount.
851
-
852
- ## Karpenter
853
-
854
- Karpenter replaces Cluster Autoscaler for node provisioning. Karpenter NodePool and EC2NodeClass are simple CRDs — use CRD import rather than composites:
855
-
856
- \`\`\`bash
857
- # Import Karpenter CRDs into your chant project
858
- chant import --url https://raw.githubusercontent.com/aws/karpenter/main/pkg/apis/crds/karpenter.sh_nodepools.yaml
859
- \`\`\`
860
-
861
- ## Fargate Considerations
862
-
863
- When running on EKS Fargate:
864
- - **No DaemonSets** — FluentBitAgent and AdotCollector cannot run on Fargate nodes
865
- - **No hostPath volumes** — use EFS for shared storage
866
- - **No privileged containers** — security context restrictions apply
867
- - For Fargate logging, use the built-in Fluent Bit log router (Fargate logging configuration)
868
-
869
- ## EKS Add-ons
870
-
871
- Common add-ons managed via AWS (not K8s manifests):
872
- - **vpc-cni** — Amazon VPC CNI plugin
873
- - **coredns** — Cluster DNS
874
- - **kube-proxy** — Network proxy
875
- - **aws-ebs-csi-driver** — EBS CSI driver (required for EbsStorageClass)
876
- - **aws-efs-csi-driver** — EFS CSI driver (required for EfsStorageClass)
877
- - **adot** — AWS Distro for OpenTelemetry (alternative to AdotCollector composite)
878
- - **aws-guardduty-agent** — Runtime threat detection
879
-
880
- Configure add-ons via the AWS lexicon (\`@intentius/chant-lexicon-aws\`) CloudFormation resources.
881
- `,
882
- triggers: [
883
- { type: "context", value: "eks" },
884
- { type: "context", value: "irsa" },
885
- { type: "context", value: "alb" },
886
- { type: "context", value: "ebs" },
887
- { type: "context", value: "efs" },
888
- { type: "context", value: "fluent-bit" },
889
- { type: "context", value: "cloudwatch" },
890
- { type: "context", value: "karpenter" },
891
- { type: "context", value: "fargate" },
892
- ],
893
- preConditions: [
894
- "chant CLI is installed (chant --version succeeds)",
895
- "EKS cluster is provisioned",
896
- "kubectl is configured for the EKS cluster",
897
- ],
898
- postConditions: [
899
- "EKS-specific resources are deployed and functional",
900
- ],
901
- parameters: [],
902
- examples: [
903
- {
904
- title: "IRSA ServiceAccount",
905
- description: "Create a ServiceAccount with IAM role for S3 access",
906
- input: "Create an IRSA ServiceAccount for my app that needs S3 access",
907
- output: `import { IrsaServiceAccount } from "@intentius/chant-lexicon-k8s";
908
-
909
- const { serviceAccount } = IrsaServiceAccount({
910
- name: "app-sa",
911
- iamRoleArn: "arn:aws:iam::123456789012:role/app-s3-role",
912
- namespace: "prod",
913
- });`,
914
- },
915
- {
916
- title: "ALB Ingress with TLS",
917
- description: "Create an ALB Ingress with ACM certificate",
918
- input: "Set up an internet-facing ALB with TLS for my API",
919
- output: `import { AlbIngress } from "@intentius/chant-lexicon-k8s";
920
-
921
- const { ingress } = AlbIngress({
922
- name: "api-ingress",
923
- hosts: [{ hostname: "api.example.com", paths: [{ path: "/", serviceName: "api", servicePort: 80 }] }],
924
- certificateArn: "arn:aws:acm:us-east-1:123456789012:certificate/abc-123",
925
720
  });`,
926
721
  },
927
722
  ],
@@ -1225,5 +1020,127 @@ const { deployment, service, serviceMonitor, prometheusRule } = MonitoredService
1225
1020
  ],
1226
1021
  },
1227
1022
  ];
1023
+
1024
+ // Load file-based skills from src/skills/
1025
+ const { readFileSync } = require("fs");
1026
+ const { join, dirname } = require("path");
1027
+ const { fileURLToPath } = require("url");
1028
+ const dir = dirname(fileURLToPath(import.meta.url));
1029
+
1030
+ const skillFiles = [
1031
+ {
1032
+ file: "kubernetes-patterns.md",
1033
+ name: "kubernetes-patterns",
1034
+ description: "Kubernetes deployment strategies, stateful workloads, RBAC, and networking patterns",
1035
+ triggers: [
1036
+ { type: "context" as const, value: "deployment strategy" },
1037
+ { type: "context" as const, value: "statefulset" },
1038
+ { type: "context" as const, value: "rbac" },
1039
+ { type: "context" as const, value: "network policy" },
1040
+ { type: "context" as const, value: "rolling update" },
1041
+ { type: "context" as const, value: "blue green" },
1042
+ ],
1043
+ parameters: [],
1044
+ examples: [
1045
+ {
1046
+ title: "Blue/Green Deployment",
1047
+ input: "Set up a blue/green deployment for my app",
1048
+ output: "import { WebApp } from \"@intentius/chant-lexicon-k8s\";\n\nconst blue = WebApp({ name: \"app-blue\", image: \"app:1.0\" });\nconst green = WebApp({ name: \"app-green\", image: \"app:2.0\" });",
1049
+ },
1050
+ ],
1051
+ },
1052
+ {
1053
+ file: "kubernetes-security.md",
1054
+ name: "kubernetes-security",
1055
+ description: "Kubernetes pod security, image scanning, network policies, and secrets management",
1056
+ triggers: [
1057
+ { type: "context" as const, value: "k8s security" },
1058
+ { type: "context" as const, value: "pod security" },
1059
+ { type: "context" as const, value: "image security" },
1060
+ { type: "context" as const, value: "k8s secrets" },
1061
+ { type: "context" as const, value: "security context" },
1062
+ ],
1063
+ parameters: [],
1064
+ examples: [
1065
+ {
1066
+ title: "Hardened Container",
1067
+ input: "Create a hardened container with security context",
1068
+ output: "WebApp({ name: \"api\", image: \"api:1.0\", securityContext: { runAsNonRoot: true, readOnlyRootFilesystem: true, capabilities: { drop: [\"ALL\"] } } })",
1069
+ },
1070
+ ],
1071
+ },
1072
+ {
1073
+ file: "chant-k8s-eks.md",
1074
+ name: "chant-k8s-eks",
1075
+ description: "EKS-specific Kubernetes composites — IRSA, ALB, EBS/EFS, Fluent Bit, ExternalDNS, ADOT",
1076
+ triggers: [
1077
+ { type: "context" as const, value: "eks composites" },
1078
+ { type: "context" as const, value: "irsa" },
1079
+ { type: "context" as const, value: "alb ingress" },
1080
+ { type: "context" as const, value: "ebs storage" },
1081
+ { type: "context" as const, value: "karpenter" },
1082
+ ],
1083
+ parameters: [],
1084
+ examples: [
1085
+ {
1086
+ title: "IRSA ServiceAccount",
1087
+ input: "Create an IRSA ServiceAccount for my app",
1088
+ output: "import { IrsaServiceAccount } from \"@intentius/chant-lexicon-k8s\";\n\nconst { serviceAccount } = IrsaServiceAccount({ name: \"app-sa\", iamRoleArn: \"arn:aws:iam::123456789012:role/app-role\" });",
1089
+ },
1090
+ ],
1091
+ },
1092
+ {
1093
+ file: "chant-k8s-gke.md",
1094
+ name: "chant-k8s-gke",
1095
+ description: "GKE-specific Kubernetes composites — Workload Identity, GCE PD, Filestore, FluentBit, OTel, ExternalDNS, Gateway",
1096
+ triggers: [
1097
+ { type: "context" as const, value: "gke composites" },
1098
+ { type: "context" as const, value: "workload identity gke" },
1099
+ { type: "context" as const, value: "config connector k8s" },
1100
+ ],
1101
+ parameters: [],
1102
+ examples: [
1103
+ {
1104
+ title: "GKE Workload Identity",
1105
+ input: "Create a ServiceAccount with GKE Workload Identity",
1106
+ output: "import { WorkloadIdentityServiceAccount } from \"@intentius/chant-lexicon-k8s\";\n\nconst { serviceAccount } = WorkloadIdentityServiceAccount({ name: \"app-sa\", gcpServiceAccountEmail: \"app@project.iam.gserviceaccount.com\" });",
1107
+ },
1108
+ ],
1109
+ },
1110
+ {
1111
+ file: "chant-k8s-aks.md",
1112
+ name: "chant-k8s-aks",
1113
+ description: "AKS-specific Kubernetes composites — Workload Identity, AGIC, Azure Disk/File, ExternalDNS, Azure Monitor",
1114
+ triggers: [
1115
+ { type: "context" as const, value: "aks composites" },
1116
+ { type: "context" as const, value: "workload identity aks" },
1117
+ { type: "context" as const, value: "agic ingress" },
1118
+ ],
1119
+ parameters: [],
1120
+ examples: [
1121
+ {
1122
+ title: "AKS Workload Identity",
1123
+ input: "Create a ServiceAccount with AKS Workload Identity",
1124
+ output: "import { AksWorkloadIdentityServiceAccount } from \"@intentius/chant-lexicon-k8s\";\n\nconst { serviceAccount } = AksWorkloadIdentityServiceAccount({ name: \"app-sa\", clientId: \"12345678-abcd-1234-abcd-123456789012\" });",
1125
+ },
1126
+ ],
1127
+ },
1128
+ ];
1129
+
1130
+ for (const skill of skillFiles) {
1131
+ try {
1132
+ const content = readFileSync(join(dir, "skills", skill.file), "utf-8");
1133
+ skills.push({
1134
+ name: skill.name,
1135
+ description: skill.description,
1136
+ content,
1137
+ triggers: skill.triggers,
1138
+ parameters: skill.parameters,
1139
+ examples: skill.examples,
1140
+ });
1141
+ } catch { /* skip missing skills */ }
1142
+ }
1143
+
1144
+ return skills;
1228
1145
  },
1229
1146
  };
@@ -0,0 +1,146 @@
1
+ ---
2
+ skill: chant-k8s-aks
3
+ description: AKS-specific Kubernetes patterns and composites
4
+ user-invocable: true
5
+ ---
6
+
7
+ # AKS Kubernetes Patterns
8
+
9
+ ## AKS Composites Overview
10
+
11
+ These composites produce K8s YAML with AKS-specific annotations and configurations.
12
+
13
+ ### AksWorkloadIdentityServiceAccount — ServiceAccount with Azure client ID annotation
14
+
15
+ ```typescript
16
+ import { AksWorkloadIdentityServiceAccount } from "@intentius/chant-lexicon-k8s";
17
+
18
+ const { serviceAccount, role, roleBinding } = AksWorkloadIdentityServiceAccount({
19
+ name: "app-sa",
20
+ clientId: "12345678-abcd-1234-abcd-123456789012",
21
+ rbacRules: [
22
+ { apiGroups: [""], resources: ["secrets"], verbs: ["get"] },
23
+ ],
24
+ namespace: "prod",
25
+ });
26
+ ```
27
+
28
+ Annotates the ServiceAccount with `azure.workload.identity/client-id` for AKS Workload Identity.
29
+
30
+ ### AgicIngress — Ingress with Application Gateway annotations
31
+
32
+ ```typescript
33
+ import { AgicIngress } from "@intentius/chant-lexicon-k8s";
34
+
35
+ const { ingress } = AgicIngress({
36
+ name: "api-ingress",
37
+ hosts: [
38
+ {
39
+ hostname: "api.example.com",
40
+ paths: [{ path: "/", serviceName: "api", servicePort: 80 }],
41
+ },
42
+ ],
43
+ certificateArn: "keyvault-cert-name",
44
+ healthCheckPath: "/healthz",
45
+ wafPolicyId: "/subscriptions/.../applicationGatewayWebApplicationFirewallPolicies/my-waf",
46
+ cookieAffinity: false,
47
+ });
48
+ ```
49
+
50
+ Features:
51
+ - Auto-sets `appgw.ingress.kubernetes.io/*` annotations
52
+ - SSL redirect enabled by default when `certificateArn` set
53
+ - `wafPolicyId` for WAFv2 integration
54
+ - `healthCheckPath` for backend health probes
55
+ - `cookieAffinity` for session persistence
56
+
57
+ ### AzureDiskStorageClass — StorageClass for Azure Disk CSI
58
+
59
+ ```typescript
60
+ import { AzureDiskStorageClass } from "@intentius/chant-lexicon-k8s";
61
+
62
+ const { storageClass } = AzureDiskStorageClass({
63
+ name: "premium-lrs",
64
+ skuName: "Premium_LRS",
65
+ cachingMode: "ReadOnly",
66
+ allowVolumeExpansion: true,
67
+ });
68
+ ```
69
+
70
+ SKU options: `Premium_LRS`, `StandardSSD_LRS`, `Standard_LRS`, `UltraSSD_LRS`.
71
+
72
+ ### AzureFileStorageClass — StorageClass for Azure Files CSI (ReadWriteMany)
73
+
74
+ ```typescript
75
+ import { AzureFileStorageClass } from "@intentius/chant-lexicon-k8s";
76
+
77
+ const { storageClass } = AzureFileStorageClass({
78
+ name: "azure-files-premium",
79
+ skuName: "Premium_LRS",
80
+ protocol: "smb",
81
+ });
82
+ ```
83
+
84
+ Protocol options: `smb` (default), `nfs`. Use Azure Files when you need ReadWriteMany (shared across pods/nodes). Use Azure Disk for ReadWriteOnce (single pod).
85
+
86
+ ### AksExternalDnsAgent — ExternalDNS for Azure DNS
87
+
88
+ ```typescript
89
+ import { AksExternalDnsAgent } from "@intentius/chant-lexicon-k8s";
90
+
91
+ const result = AksExternalDnsAgent({
92
+ clientId: "12345678-abcd-1234-abcd-123456789012",
93
+ resourceGroup: "my-rg",
94
+ subscriptionId: "sub-id",
95
+ tenantId: "tenant-id",
96
+ domainFilters: ["example.com"],
97
+ txtOwnerId: "my-cluster",
98
+ });
99
+ ```
100
+
101
+ ### AzureMonitorCollector — Azure Monitor + OTel for Log Analytics
102
+
103
+ ```typescript
104
+ import { AzureMonitorCollector } from "@intentius/chant-lexicon-k8s";
105
+
106
+ const result = AzureMonitorCollector({
107
+ workspaceId: "/subscriptions/.../workspaces/my-workspace",
108
+ clusterName: "my-cluster",
109
+ clientId: "12345678-abcd-1234-abcd-123456789012",
110
+ });
111
+ ```
112
+
113
+ ## AKS Workload Identity vs Pod-Managed Identity
114
+
115
+ | Feature | Workload Identity | Pod-Managed Identity (deprecated) |
116
+ |---------|------------------|----------------------------------|
117
+ | K8s annotation needed | Yes (`azure.workload.identity/client-id`) | Yes (`aadpodidbinding` label) |
118
+ | Composite available | **AksWorkloadIdentityServiceAccount** | None (deprecated) |
119
+ | Setup | OIDC issuer + federated credential | AzureIdentity + AzureIdentityBinding CRDs |
120
+ | Security | OIDC token exchange, no NMI pod | NMI DaemonSet intercepts IMDS calls |
121
+ | When to use | Always (recommended) | Legacy only, migrate to Workload Identity |
122
+
123
+ Pod-managed identity (AAD Pod Identity v1) is deprecated. Always use AKS Workload Identity for new workloads.
124
+
125
+ ## AGIC Considerations
126
+
127
+ Application Gateway Ingress Controller (AGIC) manages an Azure Application Gateway:
128
+ - **Application Gateway provisioned in ARM** — the gateway itself is an Azure resource created by the ARM template
129
+ - **AGIC addon** — runs as a pod in the cluster, watches Ingress resources and configures the gateway
130
+ - **Backend pools** — AGIC automatically adds pod IPs to the Application Gateway backend pool
131
+ - **Health probes** — set `healthCheckPath` for proper backend health checking
132
+ - **WAF integration** — attach a WAF policy via `wafPolicyId` for L7 protection
133
+ - **TLS termination** — reference Key Vault certificates via `certificateArn` (the certificate URI or secret name)
134
+
135
+ ## AKS Add-ons
136
+
137
+ Common add-ons managed via AKS (not K8s manifests):
138
+ - **AGIC** — Application Gateway Ingress Controller (required for AgicIngress)
139
+ - **Azure Monitor (Container Insights)** — alternative to AzureMonitorCollector for managed monitoring
140
+ - **AKS Workload Identity** — OIDC-based identity federation (required for AksWorkloadIdentityServiceAccount)
141
+ - **Azure Disk CSI driver** — enabled by default, required for AzureDiskStorageClass
142
+ - **Azure Files CSI driver** — enabled by default, required for AzureFileStorageClass
143
+ - **Azure Key Vault Secrets Provider** — sync Key Vault secrets to K8s Secrets
144
+ - **Azure Policy** — enforce governance policies on cluster resources
145
+
146
+ Configure add-ons via the Azure lexicon (`@intentius/chant-lexicon-azure`) ARM resources.
@@ -0,0 +1,191 @@
1
+ ---
2
+ skill: chant-k8s-gke
3
+ description: GKE-specific Kubernetes patterns and composites
4
+ user-invocable: true
5
+ ---
6
+
7
+ # GKE Kubernetes Patterns
8
+
9
+ ## GKE Composites Overview
10
+
11
+ These composites produce K8s YAML with GKE-specific annotations and configurations.
12
+
13
+ ### WorkloadIdentityServiceAccount — ServiceAccount with GCP SA annotation
14
+
15
+ ```typescript
16
+ import { WorkloadIdentityServiceAccount } from "@intentius/chant-lexicon-k8s";
17
+
18
+ const { serviceAccount, role, roleBinding } = WorkloadIdentityServiceAccount({
19
+ name: "app-sa",
20
+ gcpServiceAccountEmail: "app@my-project.iam.gserviceaccount.com",
21
+ rbacRules: [
22
+ { apiGroups: [""], resources: ["secrets"], verbs: ["get"] },
23
+ ],
24
+ namespace: "prod",
25
+ });
26
+ ```
27
+
28
+ Annotates the ServiceAccount with `iam.gke.io/gcp-service-account` for GKE Workload Identity.
29
+
30
+ ### GceIngress — Ingress with GCE ingress class annotations
31
+
32
+ ```typescript
33
+ import { GceIngress } from "@intentius/chant-lexicon-k8s";
34
+
35
+ const { ingress } = GceIngress({
36
+ name: "api-ingress",
37
+ hosts: [
38
+ {
39
+ hostname: "api.example.com",
40
+ paths: [{ path: "/", serviceName: "api", servicePort: 80 }],
41
+ },
42
+ ],
43
+ staticIpName: "api-ip",
44
+ managedCertificate: "api-cert",
45
+ namespace: "prod",
46
+ });
47
+ ```
48
+
49
+ Features:
50
+ - Sets `kubernetes.io/ingress.class: "gce"` annotation
51
+ - `staticIpName` binds a reserved global static IP via `kubernetes.io/ingress.global-static-ip-name`
52
+ - `managedCertificate` attaches a GKE-managed SSL certificate via `networking.gke.io/managed-certificates`
53
+ - Auto-generates FrontendConfig for SSL redirect when `managedCertificate` is set (override with `sslRedirect: false`)
54
+ - Pairs naturally with Config Connector `ComputeAddress` resources for static IPs
55
+
56
+ ### GkeGateway — Gateway API with GKE gateway classes
57
+
58
+ ```typescript
59
+ import { GkeGateway } from "@intentius/chant-lexicon-k8s";
60
+
61
+ const { gateway, httpRoute } = GkeGateway({
62
+ name: "api-gateway",
63
+ gatewayClassName: "gke-l7-global-external-managed",
64
+ hosts: [
65
+ {
66
+ hostname: "api.example.com",
67
+ paths: [{ path: "/", serviceName: "api", servicePort: 80 }],
68
+ },
69
+ ],
70
+ certificateName: "api-cert",
71
+ namespace: "prod",
72
+ });
73
+ ```
74
+
75
+ Gateway class options:
76
+ - `gke-l7-global-external-managed` — Global external (default)
77
+ - `gke-l7-regional-external-managed` — Regional external
78
+ - `gke-l7-rilb` — Regional internal
79
+
80
+ ### GcePdStorageClass — StorageClass for GCE Persistent Disk CSI
81
+
82
+ ```typescript
83
+ import { GcePdStorageClass } from "@intentius/chant-lexicon-k8s";
84
+
85
+ const { storageClass } = GcePdStorageClass({
86
+ name: "pd-balanced",
87
+ type: "pd-balanced",
88
+ replicationType: "none",
89
+ allowVolumeExpansion: true,
90
+ });
91
+ ```
92
+
93
+ Disk types: `pd-standard`, `pd-ssd`, `pd-balanced` (default), `pd-extreme`.
94
+
95
+ ### FilestoreStorageClass — StorageClass for Filestore CSI (ReadWriteMany)
96
+
97
+ ```typescript
98
+ import { FilestoreStorageClass } from "@intentius/chant-lexicon-k8s";
99
+
100
+ const { storageClass } = FilestoreStorageClass({
101
+ name: "filestore-shared",
102
+ tier: "standard",
103
+ network: "my-vpc",
104
+ });
105
+ ```
106
+
107
+ Use Filestore when you need ReadWriteMany (shared across pods/nodes). Use GCE PD for ReadWriteOnce (single pod).
108
+
109
+ ### GkeExternalDnsAgent — ExternalDNS for Cloud DNS
110
+
111
+ ```typescript
112
+ import { GkeExternalDnsAgent } from "@intentius/chant-lexicon-k8s";
113
+
114
+ const result = GkeExternalDnsAgent({
115
+ gcpServiceAccountEmail: "dns@my-project.iam.gserviceaccount.com",
116
+ gcpProjectId: "my-project",
117
+ domainFilters: ["example.com"],
118
+ txtOwnerId: "my-cluster",
119
+ });
120
+ ```
121
+
122
+ ### GkeFluentBitAgent — DaemonSet for Cloud Logging
123
+
124
+ ```typescript
125
+ import { GkeFluentBitAgent } from "@intentius/chant-lexicon-k8s";
126
+
127
+ const result = GkeFluentBitAgent({
128
+ clusterName: "my-cluster",
129
+ projectId: "my-project",
130
+ gcpServiceAccountEmail: "logging@my-project.iam.gserviceaccount.com",
131
+ });
132
+ ```
133
+
134
+ ### GkeOtelCollector — OTel for Cloud Trace + Cloud Monitoring
135
+
136
+ ```typescript
137
+ import { GkeOtelCollector } from "@intentius/chant-lexicon-k8s";
138
+
139
+ const result = GkeOtelCollector({
140
+ clusterName: "my-cluster",
141
+ projectId: "my-project",
142
+ gcpServiceAccountEmail: "monitoring@my-project.iam.gserviceaccount.com",
143
+ });
144
+ ```
145
+
146
+ ### ConfigConnectorContext — Config Connector namespace bootstrap
147
+
148
+ ```typescript
149
+ import { ConfigConnectorContext } from "@intentius/chant-lexicon-k8s";
150
+
151
+ const { context } = ConfigConnectorContext({
152
+ googleServiceAccountEmail: "cc-sa@my-project.iam.gserviceaccount.com",
153
+ namespace: "config-connector",
154
+ stateIntoSpec: "absent",
155
+ });
156
+ ```
157
+
158
+ Required when using Config Connector to manage GCP resources from within the cluster.
159
+
160
+ ## Workload Identity vs Key-Based Auth
161
+
162
+ | Feature | Workload Identity | Key-based (JSON key file) |
163
+ |---------|------------------|--------------------------|
164
+ | K8s annotation needed | Yes (`iam.gke.io/gcp-service-account`) | No |
165
+ | Composite available | **WorkloadIdentityServiceAccount** | None needed (mount key as Secret) |
166
+ | Setup | GKE cluster WI enabled + IAM binding | Create key → K8s Secret → volume mount |
167
+ | Security | No long-lived credentials, auto-rotated | Static key, must rotate manually |
168
+ | When to use | Always (recommended) | Legacy workloads, non-GKE clusters |
169
+
170
+ Workload Identity is the recommended approach for all GKE workloads. Key-based auth requires no K8s-side composite — create a Secret from the JSON key and mount it.
171
+
172
+ ## Config Connector Considerations
173
+
174
+ Config Connector (CC) runs as a GKE add-on and manages GCP resources declaratively via K8s CRDs:
175
+ - **Bootstrap cluster required** — CC needs an existing GKE cluster to run in; use `npm run bootstrap` to create one
176
+ - **CC service account** — a GCP SA with editor/IAM roles, bound to the CC controller pod via Workload Identity
177
+ - **Reconciliation** — CC continuously reconciles; deleting a CC resource deletes the underlying GCP resource
178
+ - **ConfigConnectorContext** — use the composite to configure CC per-namespace (SA email, stateIntoSpec policy)
179
+
180
+ ## GKE Add-ons
181
+
182
+ Common add-ons managed via GKE (not K8s manifests):
183
+ - **Config Connector** — manage GCP resources as K8s CRDs
184
+ - **Workload Identity** — pod-to-GCP-SA identity federation (required for WorkloadIdentityServiceAccount)
185
+ - **GKE Gateway Controller** — Gateway API implementation (required for GkeGateway)
186
+ - **GKE managed Prometheus** — alternative to GkeOtelCollector for metrics
187
+ - **GKE Dataplane V2** — eBPF-based networking with built-in NetworkPolicy enforcement
188
+ - **Filestore CSI driver** — required for FilestoreStorageClass
189
+ - **Compute Engine persistent disk CSI driver** — enabled by default, required for GcePdStorageClass
190
+
191
+ Configure add-ons via the GCP lexicon (`@intentius/chant-lexicon-gcp`) Config Connector resources.