Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .projen/deps.json

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

4 changes: 2 additions & 2 deletions .projenrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ const project = new awscdk.AwsCdkConstructLibrary({
autoApproveProjenUpgrades: true,
projenTokenSecret: 'PROJEN_GITHUB_TOKEN',
autoApproveUpgrades: true,
deps: ['aws-cdk-lib', '@aws-cdk/lambda-layer-kubectl-v23', '@aws-cdk/lambda-layer-kubectl-v24'],
devDeps: ['aws-cdk-lib', '@aws-cdk/lambda-layer-kubectl-v23', '@aws-cdk/lambda-layer-kubectl-v24'],
deps: ['aws-cdk-lib', '@aws-cdk/lambda-layer-kubectl-v23', '@aws-cdk/lambda-layer-kubectl-v24', 'lodash@^4'],
devDeps: ['aws-cdk-lib', '@aws-cdk/lambda-layer-kubectl-v23', '@aws-cdk/lambda-layer-kubectl-v24', '@types/lodash@^4'],
// deps: [], /* Runtime dependencies of this module. */
// devDeps: [], /* Build dependencies for this module. */
// packageName: undefined, /* The "name" in package.json. */
Expand Down
4 changes: 3 additions & 1 deletion package.json

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

60 changes: 45 additions & 15 deletions src/karpenter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import { SqsQueue } from 'aws-cdk-lib/aws-events-targets';
import { CfnInstanceProfile, ManagedPolicy, OpenIdConnectPrincipal, PolicyStatement, Role, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
import { Queue } from 'aws-cdk-lib/aws-sqs';
import { Construct } from 'constructs';
import { merge } from 'lodash';
import { TagSubnetsCustomResource } from './custom-resource';


export interface KarpenterProps {
/**
* The EKS cluster on which Karpenter is going to be installed on.
Expand All @@ -24,6 +26,14 @@ export interface KarpenterProps {
* If left blank, private VPC subnets will be used and tagged by default.
*/
readonly subnets?: ISubnet[];

/**
* Optional map of values to pass to the Karpenter helm chart.
* This will be merged into the default values that setup AWS related values.
*/
readonly helmValues?: {
[key: string]: any;
};
}

export interface ProvisionerSpecs {
Expand Down Expand Up @@ -81,8 +91,14 @@ export interface ProvisionerSpecs {
* AWS cloud provider configuration.
*/
readonly provider?: ProviderProps;

/**
* Optional callback to perform final modifications on the Provisoner resource definition.
*/
readonly finalizeProvisioner?: {(r:Record<string, any>): void};
}


export interface ProvisionerReqs {
/**
* Instance types to be used by the Karpenter Provider.
Expand Down Expand Up @@ -129,6 +145,11 @@ export interface ProviderProps {
* and Karpenter will use the latest EKS-optimized AMIs if an amiSelector is not specified.
*/
readonly amiSelector?: {[key: string]: string};

/**
* Optionall callback to perform final modifications on the node template resource definition.
*/
readonly finalizeProvider?: {(r:Record<string, any>): void};
}

export interface Limits {
Expand Down Expand Up @@ -469,17 +490,8 @@ export class Karpenter extends Construct {

this.karpenterControllerRole.addManagedPolicy(this.karpenterControllerPolicy);

this.karpenterHelmChart = new HelmChart(this, 'KarpenterHelmChart', {
chart: 'karpenter',
createNamespace: true,
version: 'v0.23.0',
cluster: this.cluster,
namespace: 'karpenter',
release: 'karpenter',
repository: 'oci://public.ecr.aws/karpenter/karpenter',
timeout: Duration.minutes(15),
wait: true,
values: {
const helm_values: {[key: string]: any} = merge(
{
serviceAccount: {
annotations: {
'eks.amazonaws.com/role-arn': this.karpenterControllerRole.roleArn,
Expand All @@ -496,6 +508,20 @@ export class Karpenter extends Construct {
},
},
},
props?.helmValues ?? {},
);

this.karpenterHelmChart = new HelmChart(this, 'KarpenterHelmChart', {
chart: 'karpenter',
createNamespace: true,
version: 'v0.23.0',
cluster: this.cluster,
namespace: 'karpenter',
release: 'karpenter',
repository: 'oci://public.ecr.aws/karpenter/karpenter',
timeout: Duration.minutes(15),
wait: true,
values: helm_values,
});

new CfnOutput(this, 'clusterName', { value: this.cluster.clusterName });
Expand All @@ -515,7 +541,7 @@ export class Karpenter extends Construct {
// see: https://karpenter.sh/v0.23.0/concepts/provisioners/
// see: https://karpenter.sh/v0.23.0/concepts/node-templates/
const awsNodeTemplateId = `${id}-awsNodeTemplate`.toLowerCase();
const awsNodeTemplate = this.cluster.addManifest(awsNodeTemplateId, {
const aws_node_template_resource: Record<string, any> = {
apiVersion: 'karpenter.k8s.aws/v1alpha1',
kind: 'AWSNodeTemplate',
metadata: {
Expand Down Expand Up @@ -545,13 +571,15 @@ export class Karpenter extends Construct {
// TODO: add userData https://karpenter.sh/v0.23.0/aws/provisioning/#userdata
// TODO: add metadataOptions https://karpenter.sh/v0.23.0/aws/provisioning/#metadata-options
},
});
};
provisionerSpecs?.provider?.finalizeProvider?.(aws_node_template_resource);
const awsNodeTemplate = this.cluster.addManifest(awsNodeTemplateId, aws_node_template_resource);

// see: https://karpenter.sh/v0.23.0/concepts/provisioners/#specrequirements
const requirements = this.setRequirements(provisionerSpecs?.requirements);

// see: https://karpenter.sh/v0.23.0/concepts/provisioners/
const provisioner = this.cluster.addManifest(id, {
const provisioner_resource: Record<string, any> = {
apiVersion: 'karpenter.sh/v1alpha5',
kind: 'Provisioner',
metadata: {
Expand Down Expand Up @@ -592,7 +620,9 @@ export class Karpenter extends Construct {
// see: https://karpenter.sh/v0.23.0/concepts/provisioners/#specproviderref

},
});
};
provisionerSpecs?.finalizeProvisioner?.(provisioner_resource);
const provisioner = this.cluster.addManifest(id, provisioner_resource);

provisioner.node.addDependency(awsNodeTemplate);
awsNodeTemplate.node.addDependency(this.karpenterHelmChart);
Expand Down
8 changes: 8 additions & 0 deletions test/karpenter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ const { stack, vpc, cluster } = testFixtureCluster();
const karpenter = new Karpenter(stack, 'karpenter', {
cluster,
vpc,
helmValues: {
replicas: 1,
},
});

karpenter.addProvisioner('default');
Expand Down Expand Up @@ -66,6 +69,11 @@ karpenter.addProvisioner('custom', {
},
],
},
/*
finalizeProvisioner: (r) => {
r.spec.weight = 10;
},
*/
});

test('has karpenter controller policy', () => {
Expand Down
33 changes: 19 additions & 14 deletions yarn.lock

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