Skip to content

Commit

Permalink
Merge pull request #138 from andskli/fix/serviceAccountName
Browse files Browse the repository at this point in the history
fix: Change ServiceAccount name behavior
  • Loading branch information
andskli authored Oct 24, 2023
2 parents 944df4b + a879973 commit db69cad
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 31 deletions.
25 changes: 25 additions & 0 deletions API.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 12 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand All @@ -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;
Expand All @@ -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 ?? {};

Expand All @@ -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.
*/
Expand Down Expand Up @@ -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);
Expand Down
107 changes: 79 additions & 28 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', {
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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', {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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\"');
});
});

0 comments on commit db69cad

Please sign in to comment.