@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.
@@ -0,0 +1,215 @@
1
+ /**
2
+ * FluentBitAgent composite — DaemonSet + RBAC + ConfigMap for Fluent Bit.
3
+ *
4
+ * @eks Thin wrapper around the NodeAgent pattern with Fluent Bit defaults
5
+ * (image, RBAC, CloudWatch output config).
6
+ */
7
+
8
+ export interface FluentBitAgentProps {
9
+ /** Agent name (default: "fluent-bit"). */
10
+ name?: string;
11
+ /** Fluent Bit image (default: "public.ecr.aws/aws-observability/aws-for-fluent-bit:stable"). */
12
+ image?: string;
13
+ /** CloudWatch log group name. */
14
+ logGroup: string;
15
+ /** AWS region. */
16
+ region: string;
17
+ /** Cluster name — used as log stream prefix. */
18
+ clusterName: string;
19
+ /** Namespace (default: "amazon-cloudwatch"). */
20
+ namespace?: string;
21
+ /** Additional labels. */
22
+ labels?: Record<string, string>;
23
+ /** CPU request (default: "50m"). */
24
+ cpuRequest?: string;
25
+ /** Memory request (default: "64Mi"). */
26
+ memoryRequest?: string;
27
+ /** CPU limit (default: "200m"). */
28
+ cpuLimit?: string;
29
+ /** Memory limit (default: "128Mi"). */
30
+ memoryLimit?: string;
31
+ /** IAM Role ARN for IRSA (adds eks.amazonaws.com/role-arn annotation to ServiceAccount). */
32
+ iamRoleArn?: string;
33
+ }
34
+
35
+ export interface FluentBitAgentResult {
36
+ daemonSet: Record<string, unknown>;
37
+ serviceAccount: Record<string, unknown>;
38
+ clusterRole: Record<string, unknown>;
39
+ clusterRoleBinding: Record<string, unknown>;
40
+ configMap: Record<string, unknown>;
41
+ }
42
+
43
+ /**
44
+ * Create a FluentBitAgent composite — returns prop objects for
45
+ * a DaemonSet, ServiceAccount, ClusterRole, ClusterRoleBinding, and ConfigMap.
46
+ *
47
+ * @eks
48
+ * @example
49
+ * ```ts
50
+ * import { FluentBitAgent } from "@intentius/chant-lexicon-k8s";
51
+ *
52
+ * const { daemonSet, serviceAccount, clusterRole, clusterRoleBinding, configMap } = FluentBitAgent({
53
+ * logGroup: "/aws/eks/my-cluster/containers",
54
+ * region: "us-east-1",
55
+ * clusterName: "my-cluster",
56
+ * });
57
+ * ```
58
+ */
59
+ export function FluentBitAgent(props: FluentBitAgentProps): FluentBitAgentResult {
60
+ const {
61
+ name = "fluent-bit",
62
+ image = "public.ecr.aws/aws-observability/aws-for-fluent-bit:stable",
63
+ logGroup,
64
+ region,
65
+ clusterName,
66
+ namespace = "amazon-cloudwatch",
67
+ labels: extraLabels = {},
68
+ cpuRequest = "50m",
69
+ memoryRequest = "64Mi",
70
+ cpuLimit = "200m",
71
+ memoryLimit = "128Mi",
72
+ iamRoleArn,
73
+ } = props;
74
+
75
+ const saName = `${name}-sa`;
76
+ const clusterRoleName = `${name}-role`;
77
+ const bindingName = `${name}-binding`;
78
+ const configMapName = `${name}-config`;
79
+
80
+ const commonLabels: Record<string, string> = {
81
+ "app.kubernetes.io/name": name,
82
+ "app.kubernetes.io/managed-by": "chant",
83
+ ...extraLabels,
84
+ };
85
+
86
+ const fluentBitConfig = `[SERVICE]
87
+ Flush 5
88
+ Log_Level info
89
+ Daemon off
90
+ Parsers_File parsers.conf
91
+
92
+ [INPUT]
93
+ Name tail
94
+ Tag kube.*
95
+ Path /var/log/containers/*.log
96
+ Parser docker
97
+ DB /var/fluent-bit/state/flb_container.db
98
+ Mem_Buf_Limit 5MB
99
+ Skip_Long_Lines On
100
+ Refresh_Interval 10
101
+
102
+ [FILTER]
103
+ Name kubernetes
104
+ Match kube.*
105
+ Kube_URL https://kubernetes.default.svc:443
106
+ Kube_CA_File /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
107
+ Kube_Token_File /var/run/secrets/kubernetes.io/serviceaccount/token
108
+ Merge_Log On
109
+ K8S-Logging.Parser On
110
+ K8S-Logging.Exclude Off
111
+
112
+ [OUTPUT]
113
+ Name cloudwatch_logs
114
+ Match *
115
+ region ${region}
116
+ log_group_name ${logGroup}
117
+ log_stream_prefix ${clusterName}/
118
+ auto_create_group true
119
+ `;
120
+
121
+ const container: Record<string, unknown> = {
122
+ name,
123
+ image,
124
+ resources: {
125
+ requests: { cpu: cpuRequest, memory: memoryRequest },
126
+ limits: { cpu: cpuLimit, memory: memoryLimit },
127
+ },
128
+ volumeMounts: [
129
+ { name: "varlog", mountPath: "/var/log", readOnly: true },
130
+ { name: "config", mountPath: `/etc/${name}`, readOnly: true },
131
+ { name: "state", mountPath: "/var/fluent-bit/state" },
132
+ ],
133
+ };
134
+
135
+ const daemonSetProps: Record<string, unknown> = {
136
+ metadata: {
137
+ name,
138
+ namespace,
139
+ labels: { ...commonLabels, "app.kubernetes.io/component": "agent" },
140
+ },
141
+ spec: {
142
+ selector: { matchLabels: { "app.kubernetes.io/name": name } },
143
+ template: {
144
+ metadata: { labels: { "app.kubernetes.io/name": name, ...extraLabels } },
145
+ spec: {
146
+ serviceAccountName: saName,
147
+ containers: [container],
148
+ volumes: [
149
+ { name: "varlog", hostPath: { path: "/var/log" } },
150
+ { name: "config", configMap: { name: configMapName } },
151
+ { name: "state", hostPath: { path: `/var/fluent-bit/state/${name}` } },
152
+ ],
153
+ tolerations: [{ operator: "Exists" }],
154
+ },
155
+ },
156
+ },
157
+ };
158
+
159
+ const serviceAccountProps: Record<string, unknown> = {
160
+ metadata: {
161
+ name: saName,
162
+ namespace,
163
+ labels: { ...commonLabels, "app.kubernetes.io/component": "agent" },
164
+ ...(iamRoleArn ? { annotations: { "eks.amazonaws.com/role-arn": iamRoleArn } } : {}),
165
+ },
166
+ };
167
+
168
+ const clusterRoleProps: Record<string, unknown> = {
169
+ metadata: {
170
+ name: clusterRoleName,
171
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
172
+ },
173
+ rules: [
174
+ { apiGroups: [""], resources: ["namespaces", "pods"], verbs: ["get", "list", "watch"] },
175
+ ],
176
+ };
177
+
178
+ const clusterRoleBindingProps: Record<string, unknown> = {
179
+ metadata: {
180
+ name: bindingName,
181
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
182
+ },
183
+ roleRef: {
184
+ apiGroup: "rbac.authorization.k8s.io",
185
+ kind: "ClusterRole",
186
+ name: clusterRoleName,
187
+ },
188
+ subjects: [
189
+ {
190
+ kind: "ServiceAccount",
191
+ name: saName,
192
+ namespace,
193
+ },
194
+ ],
195
+ };
196
+
197
+ const configMapProps: Record<string, unknown> = {
198
+ metadata: {
199
+ name: configMapName,
200
+ namespace,
201
+ labels: { ...commonLabels, "app.kubernetes.io/component": "config" },
202
+ },
203
+ data: {
204
+ "fluent-bit.conf": fluentBitConfig,
205
+ },
206
+ };
207
+
208
+ return {
209
+ daemonSet: daemonSetProps,
210
+ serviceAccount: serviceAccountProps,
211
+ clusterRole: clusterRoleProps,
212
+ clusterRoleBinding: clusterRoleBindingProps,
213
+ configMap: configMapProps,
214
+ };
215
+ }
@@ -12,3 +12,31 @@ export { NamespaceEnv } from "./namespace-env";
12
12
  export type { NamespaceEnvProps, NamespaceEnvResult } from "./namespace-env";
13
13
  export { NodeAgent } from "./node-agent";
14
14
  export type { NodeAgentProps, NodeAgentResult } from "./node-agent";
15
+ export { BatchJob } from "./batch-job";
16
+ export type { BatchJobProps, BatchJobResult } from "./batch-job";
17
+ export { SecureIngress } from "./secure-ingress";
18
+ export type { SecureIngressProps, SecureIngressResult } from "./secure-ingress";
19
+ export { ConfiguredApp } from "./configured-app";
20
+ export type { ConfiguredAppProps, ConfiguredAppResult } from "./configured-app";
21
+ export { SidecarApp } from "./sidecar-app";
22
+ export type { SidecarAppProps, SidecarAppResult } from "./sidecar-app";
23
+ export { MonitoredService } from "./monitored-service";
24
+ export type { MonitoredServiceProps, MonitoredServiceResult } from "./monitored-service";
25
+ export { NetworkIsolatedApp } from "./network-isolated-app";
26
+ export type { NetworkIsolatedAppProps, NetworkIsolatedAppResult } from "./network-isolated-app";
27
+ export { IrsaServiceAccount } from "./irsa-service-account";
28
+ export type { IrsaServiceAccountProps, IrsaServiceAccountResult } from "./irsa-service-account";
29
+ export { AlbIngress } from "./alb-ingress";
30
+ export type { AlbIngressProps, AlbIngressResult } from "./alb-ingress";
31
+ export { EbsStorageClass } from "./ebs-storage-class";
32
+ export type { EbsStorageClassProps, EbsStorageClassResult } from "./ebs-storage-class";
33
+ export { EfsStorageClass } from "./efs-storage-class";
34
+ export type { EfsStorageClassProps, EfsStorageClassResult } from "./efs-storage-class";
35
+ export { FluentBitAgent } from "./fluent-bit-agent";
36
+ export type { FluentBitAgentProps, FluentBitAgentResult } from "./fluent-bit-agent";
37
+ export { ExternalDnsAgent } from "./external-dns-agent";
38
+ export type { ExternalDnsAgentProps, ExternalDnsAgentResult } from "./external-dns-agent";
39
+ export { AdotCollector } from "./adot-collector";
40
+ export type { AdotCollectorProps, AdotCollectorResult } from "./adot-collector";
41
+ export { MetricsServer } from "./metrics-server";
42
+ export type { MetricsServerProps, MetricsServerResult } from "./metrics-server";
@@ -0,0 +1,114 @@
1
+ /**
2
+ * IrsaServiceAccount composite — ServiceAccount + IAM annotation + optional RBAC.
3
+ *
4
+ * @eks Creates a ServiceAccount with the `eks.amazonaws.com/role-arn`
5
+ * annotation for IAM Roles for Service Accounts (IRSA).
6
+ */
7
+
8
+ export interface IrsaServiceAccountProps {
9
+ /** ServiceAccount name — used in metadata and labels. */
10
+ name: string;
11
+ /** IAM Role ARN for IRSA annotation. */
12
+ iamRoleArn: string;
13
+ /** Optional RBAC rules — if provided, creates Role + RoleBinding. */
14
+ rbacRules?: Array<{
15
+ apiGroups: string[];
16
+ resources: string[];
17
+ verbs: string[];
18
+ }>;
19
+ /** Additional labels to apply to all resources. */
20
+ labels?: Record<string, string>;
21
+ /** Namespace for all resources. */
22
+ namespace?: string;
23
+ }
24
+
25
+ export interface IrsaServiceAccountResult {
26
+ serviceAccount: Record<string, unknown>;
27
+ role?: Record<string, unknown>;
28
+ roleBinding?: Record<string, unknown>;
29
+ }
30
+
31
+ /**
32
+ * Create an IrsaServiceAccount composite — returns prop objects for
33
+ * a ServiceAccount with IRSA annotation, and optional Role + RoleBinding.
34
+ *
35
+ * @eks
36
+ * @example
37
+ * ```ts
38
+ * import { IrsaServiceAccount } from "@intentius/chant-lexicon-k8s";
39
+ *
40
+ * const { serviceAccount, role, roleBinding } = IrsaServiceAccount({
41
+ * name: "app-sa",
42
+ * iamRoleArn: "arn:aws:iam::123456789012:role/my-app-role",
43
+ * rbacRules: [
44
+ * { apiGroups: [""], resources: ["secrets"], verbs: ["get"] },
45
+ * ],
46
+ * });
47
+ * ```
48
+ */
49
+ export function IrsaServiceAccount(props: IrsaServiceAccountProps): IrsaServiceAccountResult {
50
+ const {
51
+ name,
52
+ iamRoleArn,
53
+ rbacRules,
54
+ labels: extraLabels = {},
55
+ namespace,
56
+ } = props;
57
+
58
+ const roleName = `${name}-role`;
59
+ const bindingName = `${name}-binding`;
60
+
61
+ const commonLabels: Record<string, string> = {
62
+ "app.kubernetes.io/name": name,
63
+ "app.kubernetes.io/managed-by": "chant",
64
+ ...extraLabels,
65
+ };
66
+
67
+ const serviceAccountProps: Record<string, unknown> = {
68
+ metadata: {
69
+ name,
70
+ ...(namespace && { namespace }),
71
+ labels: { ...commonLabels, "app.kubernetes.io/component": "service-account" },
72
+ annotations: {
73
+ "eks.amazonaws.com/role-arn": iamRoleArn,
74
+ },
75
+ },
76
+ };
77
+
78
+ const result: IrsaServiceAccountResult = {
79
+ serviceAccount: serviceAccountProps,
80
+ };
81
+
82
+ if (rbacRules && rbacRules.length > 0) {
83
+ result.role = {
84
+ metadata: {
85
+ name: roleName,
86
+ ...(namespace && { namespace }),
87
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
88
+ },
89
+ rules: rbacRules,
90
+ };
91
+
92
+ result.roleBinding = {
93
+ metadata: {
94
+ name: bindingName,
95
+ ...(namespace && { namespace }),
96
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
97
+ },
98
+ roleRef: {
99
+ apiGroup: "rbac.authorization.k8s.io",
100
+ kind: "Role",
101
+ name: roleName,
102
+ },
103
+ subjects: [
104
+ {
105
+ kind: "ServiceAccount",
106
+ name,
107
+ ...(namespace && { namespace }),
108
+ },
109
+ ],
110
+ };
111
+ }
112
+
113
+ return result;
114
+ }
@@ -0,0 +1,224 @@
1
+ /**
2
+ * MetricsServer composite — Deployment + Service + ServiceAccount + RBAC + APIService.
3
+ *
4
+ * Deploys metrics-server for HPA pod CPU/memory metrics. metrics-server is not an
5
+ * EKS managed addon — it needs K8s workloads. Uses in-cluster RBAC only (no IRSA).
6
+ */
7
+
8
+ export interface MetricsServerProps {
9
+ /** Agent name (default: "metrics-server"). */
10
+ name?: string;
11
+ /** Container image (default: "registry.k8s.io/metrics-server/metrics-server:v0.7.2"). */
12
+ image?: string;
13
+ /** Replicas (default: 1). */
14
+ replicas?: number;
15
+ /** Namespace (default: "kube-system"). */
16
+ namespace?: string;
17
+ /** Additional labels. */
18
+ labels?: Record<string, string>;
19
+ }
20
+
21
+ export interface MetricsServerResult {
22
+ deployment: Record<string, unknown>;
23
+ service: Record<string, unknown>;
24
+ serviceAccount: Record<string, unknown>;
25
+ clusterRole: Record<string, unknown>;
26
+ clusterRoleBinding: Record<string, unknown>;
27
+ /** ClusterRole for aggregated API access. */
28
+ aggregatedClusterRole: Record<string, unknown>;
29
+ /** Binding for aggregated API auth-delegator. */
30
+ authDelegatorBinding: Record<string, unknown>;
31
+ /** APIService registration for v1beta1.metrics.k8s.io. */
32
+ apiService: Record<string, unknown>;
33
+ }
34
+
35
+ /**
36
+ * Create a MetricsServer composite — returns prop objects for a Deployment,
37
+ * Service, ServiceAccount, ClusterRoles, ClusterRoleBindings, and APIService.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import { MetricsServer } from "@intentius/chant-lexicon-k8s";
42
+ *
43
+ * const ms = MetricsServer({});
44
+ * ```
45
+ */
46
+ export function MetricsServer(props: MetricsServerProps): MetricsServerResult {
47
+ const {
48
+ name = "metrics-server",
49
+ image = "registry.k8s.io/metrics-server/metrics-server:v0.7.2",
50
+ replicas = 1,
51
+ namespace = "kube-system",
52
+ labels: extraLabels = {},
53
+ } = props;
54
+
55
+ const saName = `${name}-sa`;
56
+
57
+ const commonLabels: Record<string, string> = {
58
+ "app.kubernetes.io/name": name,
59
+ "app.kubernetes.io/managed-by": "chant",
60
+ ...extraLabels,
61
+ };
62
+
63
+ const deployment: Record<string, unknown> = {
64
+ metadata: {
65
+ name,
66
+ namespace,
67
+ labels: { ...commonLabels, "app.kubernetes.io/component": "metrics" },
68
+ },
69
+ spec: {
70
+ replicas,
71
+ selector: { matchLabels: { "app.kubernetes.io/name": name } },
72
+ template: {
73
+ metadata: { labels: { "app.kubernetes.io/name": name, ...extraLabels } },
74
+ spec: {
75
+ serviceAccountName: saName,
76
+ containers: [
77
+ {
78
+ name,
79
+ image,
80
+ args: [
81
+ "--cert-dir=/tmp",
82
+ "--secure-port=10250",
83
+ "--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
84
+ "--kubelet-use-node-status-port",
85
+ "--metric-resolution=15s",
86
+ ],
87
+ ports: [{ containerPort: 10250, name: "https", protocol: "TCP" }],
88
+ resources: {
89
+ requests: { cpu: "100m", memory: "200Mi" },
90
+ limits: { cpu: "100m", memory: "200Mi" },
91
+ },
92
+ livenessProbe: {
93
+ httpGet: { path: "/livez", port: 10250, scheme: "HTTPS" },
94
+ initialDelaySeconds: 0,
95
+ periodSeconds: 10,
96
+ failureThreshold: 3,
97
+ },
98
+ readinessProbe: {
99
+ httpGet: { path: "/readyz", port: 10250, scheme: "HTTPS" },
100
+ initialDelaySeconds: 20,
101
+ periodSeconds: 10,
102
+ failureThreshold: 3,
103
+ },
104
+ securityContext: {
105
+ runAsNonRoot: true,
106
+ readOnlyRootFilesystem: true,
107
+ allowPrivilegeEscalation: false,
108
+ },
109
+ volumeMounts: [{ name: "tmp-dir", mountPath: "/tmp" }],
110
+ },
111
+ ],
112
+ volumes: [{ name: "tmp-dir", emptyDir: {} }],
113
+ priorityClassName: "system-cluster-critical",
114
+ },
115
+ },
116
+ },
117
+ };
118
+
119
+ const service: Record<string, unknown> = {
120
+ metadata: {
121
+ name,
122
+ namespace,
123
+ labels: {
124
+ ...commonLabels,
125
+ "app.kubernetes.io/component": "metrics",
126
+ "kubernetes.io/cluster-service": "true",
127
+ "kubernetes.io/name": "Metrics-server",
128
+ },
129
+ },
130
+ spec: {
131
+ selector: { "app.kubernetes.io/name": name },
132
+ ports: [{ port: 443, targetPort: 10250, protocol: "TCP", name: "https" }],
133
+ },
134
+ };
135
+
136
+ const serviceAccount: Record<string, unknown> = {
137
+ metadata: {
138
+ name: saName,
139
+ namespace,
140
+ labels: { ...commonLabels, "app.kubernetes.io/component": "metrics" },
141
+ },
142
+ };
143
+
144
+ const clusterRole: Record<string, unknown> = {
145
+ metadata: {
146
+ name: `system:${name}`,
147
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
148
+ },
149
+ rules: [
150
+ { apiGroups: [""], resources: ["pods", "nodes", "namespaces"], verbs: ["get", "list", "watch"] },
151
+ { apiGroups: [""], resources: ["nodes/metrics", "nodes/stats"], verbs: ["get"] },
152
+ ],
153
+ };
154
+
155
+ const clusterRoleBinding: Record<string, unknown> = {
156
+ metadata: {
157
+ name: `system:${name}`,
158
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
159
+ },
160
+ roleRef: {
161
+ apiGroup: "rbac.authorization.k8s.io",
162
+ kind: "ClusterRole",
163
+ name: `system:${name}`,
164
+ },
165
+ subjects: [{ kind: "ServiceAccount", name: saName, namespace }],
166
+ };
167
+
168
+ const aggregatedClusterRole: Record<string, unknown> = {
169
+ metadata: {
170
+ name: `system:${name}-aggregated-reader`,
171
+ labels: {
172
+ ...commonLabels,
173
+ "app.kubernetes.io/component": "rbac",
174
+ "rbac.authorization.k8s.io/aggregate-to-admin": "true",
175
+ "rbac.authorization.k8s.io/aggregate-to-edit": "true",
176
+ "rbac.authorization.k8s.io/aggregate-to-view": "true",
177
+ },
178
+ },
179
+ rules: [
180
+ { apiGroups: ["metrics.k8s.io"], resources: ["pods", "nodes"], verbs: ["get", "list", "watch"] },
181
+ ],
182
+ };
183
+
184
+ const authDelegatorBinding: Record<string, unknown> = {
185
+ metadata: {
186
+ name: `${name}:system:auth-delegator`,
187
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
188
+ },
189
+ roleRef: {
190
+ apiGroup: "rbac.authorization.k8s.io",
191
+ kind: "ClusterRole",
192
+ name: "system:auth-delegator",
193
+ },
194
+ subjects: [{ kind: "ServiceAccount", name: saName, namespace }],
195
+ };
196
+
197
+ const apiService: Record<string, unknown> = {
198
+ apiVersion: "apiregistration.k8s.io/v1",
199
+ kind: "APIService",
200
+ metadata: {
201
+ name: "v1beta1.metrics.k8s.io",
202
+ labels: { ...commonLabels, "app.kubernetes.io/component": "metrics" },
203
+ },
204
+ spec: {
205
+ service: { name, namespace },
206
+ group: "metrics.k8s.io",
207
+ version: "v1beta1",
208
+ insecureSkipTLSVerify: true,
209
+ groupPriorityMinimum: 100,
210
+ versionPriority: 100,
211
+ },
212
+ };
213
+
214
+ return {
215
+ deployment,
216
+ service,
217
+ serviceAccount,
218
+ clusterRole,
219
+ clusterRoleBinding,
220
+ aggregatedClusterRole,
221
+ authDelegatorBinding,
222
+ apiService,
223
+ };
224
+ }