diff --git a/API.md b/API.md
index 943ee2e..c479dcd 100644
--- a/API.md
+++ b/API.md
@@ -162,6 +162,7 @@ Any object.
| helmExtraValues
| any
| *No description.* |
| namespace
| string
| *No description.* |
| nodeRole
| aws-cdk-lib.aws_iam.Role
| *No description.* |
+| serviceAccountName
| string
| *No description.* |
| version
| string
| *No description.* |
---
@@ -218,6 +219,16 @@ public readonly nodeRole: Role;
---
+##### `serviceAccountName`Required
+
+```typescript
+public readonly serviceAccountName: string;
+```
+
+- *Type:* string
+
+---
+
##### `version`Optional
```typescript
@@ -249,6 +260,7 @@ const karpenterProps: KarpenterProps = { ... }
| helmExtraValues
| any
| Extra values to pass to the Karpenter Helm chart. |
| namespace
| string
| The Kubernetes namespace to install to. |
| nodeRole
| aws-cdk-lib.aws_iam.Role
| Custom NodeRole to pass for Karpenter Nodes. |
+| serviceAccountName
| string
| The Kubernetes ServiceAccount name to use. |
| version
| string
| The helm chart version to install. |
---
@@ -302,6 +314,19 @@ Custom NodeRole to pass for Karpenter Nodes.
---
+##### `serviceAccountName`Optional
+
+```typescript
+public readonly serviceAccountName: string;
+```
+
+- *Type:* string
+- *Default:* karpenter
+
+The Kubernetes ServiceAccount name to use.
+
+---
+
##### `version`Optional
```typescript
diff --git a/src/index.ts b/src/index.ts
index d8c5345..bafb201 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -19,6 +19,13 @@ export interface KarpenterProps {
*/
readonly namespace?: string;
+ /**
+ * The Kubernetes ServiceAccount name to use
+ *
+ * @default karpenter
+ */
+ readonly serviceAccountName?: string;
+
/**
* The helm chart version to install
*
@@ -41,6 +48,7 @@ export interface KarpenterProps {
export class Karpenter extends Construct {
public readonly cluster: Cluster;
public readonly namespace: string;
+ public readonly serviceAccountName: string;
public readonly version?: string;
public readonly nodeRole: Role;
public readonly helmExtraValues: any;
@@ -52,6 +60,7 @@ export class Karpenter extends Construct {
this.cluster = props.cluster;
this.namespace = props.namespace ?? 'karpenter';
+ this.serviceAccountName = props.serviceAccountName ?? 'karpenter';
this.version = props.version;
this.helmExtraValues = props.helmExtraValues ?? {};
@@ -61,9 +70,8 @@ export class Karpenter extends Construct {
*
* We will also create a role mapping in the `aws-auth` ConfigMap so that the nodes can authenticate
* with the Kubernetes API using IAM.
- */
-
- /* Create Node Role if nodeRole not added as prop
+ *
+ * Create Node Role if nodeRole not added as prop
* Make sure that the Role that is added does not have an Instance Profile associated to it
* since we will create it here.
*/
@@ -110,6 +118,7 @@ export class Karpenter extends Construct {
});
this.serviceAccount = this.cluster.addServiceAccount('karpenter', {
+ name: this.serviceAccountName,
namespace: this.namespace,
});
this.serviceAccount.node.addDependency(namespace);
diff --git a/test/index.test.ts b/test/index.test.ts
index 18cf89a..ef2f4e6 100644
--- a/test/index.test.ts
+++ b/test/index.test.ts
@@ -10,7 +10,7 @@ describe('Karpenter installation', () => {
const stack = new cdk.Stack(app, 'test-stack');
const cluster = new Cluster(stack, 'testcluster', {
- version: KubernetesVersion.V1_21,
+ version: KubernetesVersion.V1_27,
});
new Karpenter(stack, 'Karpenter', {
@@ -28,7 +28,7 @@ describe('Karpenter installation', () => {
const stack = new cdk.Stack(app, 'test-stack');
const cluster = new Cluster(stack, 'testcluster', {
- version: KubernetesVersion.V1_21,
+ version: KubernetesVersion.V1_27,
});
// Create Karpenter install with non-default version
@@ -49,7 +49,7 @@ describe('Karpenter installation', () => {
const stack = new cdk.Stack(app, 'test-stack');
const cluster = new Cluster(stack, 'testcluster', {
- version: KubernetesVersion.V1_21,
+ version: KubernetesVersion.V1_27,
});
// Create Karpenter install with non-default namespace
@@ -94,33 +94,12 @@ describe('Karpenter installation', () => {
expect(values['Fn::Join'][1][0]).toContain('{\"foo.key\":\"foo.value\"');
});
- it('should install from old URL if Karpenter version < v0.17.0', () => {
- const app = new cdk.App();
- const stack = new cdk.Stack(app, 'test-stack');
-
- const cluster = new Cluster(stack, 'testcluster', {
- version: KubernetesVersion.V1_23,
- });
-
- // Create Karpenter install with non-default version
- new Karpenter(stack, 'Karpenter', {
- cluster: cluster,
- version: 'v0.6.0',
- });
-
- const t = Template.fromStack(stack);
- t.hasResource('Custom::AWSCDK-EKS-Cluster', {});
- t.hasResourceProperties('Custom::AWSCDK-EKS-HelmChart', {
- Repository: Match.stringLikeRegexp('https://charts.karpenter.sh'),
- });
- });
-
it('should use existing nodeRole instead of creating a new role', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app, 'test-stack');
const cluster = new Cluster(stack, 'testcluster', {
- version: KubernetesVersion.V1_24,
+ version: KubernetesVersion.V1_27,
});
const preexistingRole = new Role(stack, 'PreExistingRole', {
@@ -151,7 +130,7 @@ describe('Karpenter installation', () => {
const stack = new cdk.Stack(app, 'test-stack');
const cluster = new Cluster(stack, 'testcluster', {
- version: KubernetesVersion.V1_24,
+ version: KubernetesVersion.V1_27,
});
// Create Karpenter install with non-default version
@@ -200,13 +179,36 @@ describe('Karpenter installation', () => {
]),
}));
});
+});
+
+describe('Karpenter Versions', () => {
+ it('should install from old URL if Karpenter version < v0.17.0', () => {
+ const app = new cdk.App();
+ const stack = new cdk.Stack(app, 'test-stack');
+
+ const cluster = new Cluster(stack, 'testcluster', {
+ version: KubernetesVersion.V1_27,
+ });
+
+ // Create Karpenter install with non-default version
+ new Karpenter(stack, 'Karpenter', {
+ cluster: cluster,
+ version: 'v0.6.0',
+ });
+
+ const t = Template.fromStack(stack);
+ t.hasResource('Custom::AWSCDK-EKS-Cluster', {});
+ t.hasResourceProperties('Custom::AWSCDK-EKS-HelmChart', {
+ Repository: Match.stringLikeRegexp('https://charts.karpenter.sh'),
+ });
+ });
it('should install from new URL if Karpenter version >= v0.17.0', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app, 'test-stack');
const cluster = new Cluster(stack, 'testcluster', {
- version: KubernetesVersion.V1_23,
+ version: KubernetesVersion.V1_27,
});
// Create Karpenter install with non-default version
@@ -227,7 +229,7 @@ describe('Karpenter installation', () => {
const stack = new cdk.Stack(app, 'test-stack');
const cluster = new Cluster(stack, 'testcluster', {
- version: KubernetesVersion.V1_23,
+ version: KubernetesVersion.V1_27,
});
// Create Karpenter install with non-default version
@@ -248,3 +250,52 @@ describe('Karpenter installation', () => {
expect(values['Fn::Join'][1]).toContain('\"}},\"settings\":{\"aws\":{\"clusterName\":\"');
});
});
+
+describe('Kubernetes ServiceAccount', () => {
+ it('should create SA named: karpenter (default)', () => {
+ const app = new cdk.App();
+ const stack = new cdk.Stack(app, 'test-stack');
+
+ const cluster = new Cluster(stack, 'testcluster', {
+ version: KubernetesVersion.V1_27,
+ });
+
+ new Karpenter(stack, 'Karpenter', {
+ cluster: cluster,
+ });
+
+ const t = Template.fromStack(stack);
+ // Test if we have created a ServiceAccount
+ const valueCapture = new Capture();
+ t.hasResourceProperties('Custom::AWSCDK-EKS-HelmChart', {
+ Values: valueCapture,
+ });
+
+ const values = valueCapture.asObject();
+ expect(values['Fn::Join'][1][0]).toContain('{\"serviceAccount\":{\"create\":false,\"name\":\"karpenter\"');
+ });
+
+ it('should create SA named: custom-sa', () => {
+ const app = new cdk.App();
+ const stack = new cdk.Stack(app, 'test-stack');
+
+ const cluster = new Cluster(stack, 'testcluster', {
+ version: KubernetesVersion.V1_27,
+ });
+
+ new Karpenter(stack, 'Karpenter', {
+ cluster: cluster,
+ serviceAccountName: 'custom-sa',
+ });
+
+ const t = Template.fromStack(stack);
+ // Test if we have created a ServiceAccount
+ const valueCapture = new Capture();
+ t.hasResourceProperties('Custom::AWSCDK-EKS-HelmChart', {
+ Values: valueCapture,
+ });
+
+ const values = valueCapture.asObject();
+ expect(values['Fn::Join'][1][0]).toContain('{\"serviceAccount\":{\"create\":false,\"name\":\"custom-sa\"');
+ });
+});