Skip to content

Commit

Permalink
feat(eks): add helm flag --skip-crds (aws#24213)
Browse files Browse the repository at this point in the history
When installing Helm chart sometimes it is needed to skip the installation of custom resource definitions.
This MR adds the functionality to the helm chart construct.

In fact I did the following

* Add the possibility to skip the installation of crds in a helm chart via a new property
* Add tests for skipCrds property
* Update README

Closes aws#24296 

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
alexandersperling authored and homakk committed Mar 28, 2023
1 parent b6f3d1d commit b8de9d9
Show file tree
Hide file tree
Showing 15 changed files with 142 additions and 14 deletions.
14 changes: 14 additions & 0 deletions packages/@aws-cdk/aws-eks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1193,6 +1193,20 @@ cluster.addHelmChart('ExternalSecretsOperator', {
});
```

Helm chart can come with Custom Resource Definitions (CRDs) defined that by default will be installed by helm as well. However in special cases it might be needed to skip the installation of CRDs, for that the property `skipCrds` can be used.

```ts
declare const cluster: eks.Cluster;
// option 1: use a construct
new eks.HelmChart(this, 'NginxIngress', {
cluster,
chart: 'nginx-ingress',
repository: 'https://helm.nginx.com/stable',
namespace: 'kube-system',
skipCrds: true,
});
```

### OCI Charts

OCI charts are also supported.
Expand Down
9 changes: 9 additions & 0 deletions packages/@aws-cdk/aws-eks/lib/helm-chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ export interface HelmChartOptions {
* @default true
*/
readonly createNamespace?: boolean;

/**
* if set, no CRDs will be installed
* @default - CRDs are installed if not already present
*/
readonly skipCrds?: boolean;
}

/**
Expand Down Expand Up @@ -129,6 +135,8 @@ export class HelmChart extends Construct {
const wait = props.wait ?? false;
// default to create new namespace
const createNamespace = props.createNamespace ?? true;
// default to not skip crd installation
const skipCrds = props.skipCrds ?? false;

props.chartAsset?.grantRead(provider.handlerRole);

Expand All @@ -148,6 +156,7 @@ export class HelmChart extends Construct {
Namespace: props.namespace ?? 'default',
Repository: props.repository,
CreateNamespace: createNamespace || undefined,
SkipCrds: skipCrds || undefined,
},
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def helm_handler(event, context):
create_namespace = props.get('CreateNamespace', None)
repository = props.get('Repository', None)
values_text = props.get('Values', None)
skip_crds = props.get('SkipCrds', False)

# "log in" to the cluster
subprocess.check_call([ 'aws', 'eks', 'update-kubeconfig',
Expand Down Expand Up @@ -146,7 +147,7 @@ def get_chart_from_oci(tmpdir, repository = None, version = None):
raise Exception(f'Operation failed after {maxAttempts} attempts: {output}')


def helm(verb, release, chart = None, repo = None, file = None, namespace = None, version = None, wait = False, timeout = None, create_namespace = None):
def helm(verb, release, chart = None, repo = None, file = None, namespace = None, version = None, wait = False, timeout = None, create_namespace = None, skip_crds = False):
import subprocess

cmnd = ['helm', verb, release]
Expand All @@ -166,6 +167,8 @@ def helm(verb, release, chart = None, repo = None, file = None, namespace = None
cmnd.extend(['--namespace', namespace])
if wait:
cmnd.append('--wait')
if skip_crds:
cmnd.append('--skip-crds')
if not timeout is None:
cmnd.extend(['--timeout', timeout])
cmnd.extend(['--kubeconfig', kubeconfig])
Expand Down
22 changes: 22 additions & 0 deletions packages/@aws-cdk/aws-eks/test/helm-chart.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,5 +226,27 @@ describe('helm chart', () => {
// THEN
Template.fromStack(stack).hasResourceProperties(eks.HelmChart.RESOURCE_TYPE, { Timeout: '600s' });
});

test('should disable skip crds by default', () => {
// GIVEN
const { stack, cluster } = testFixtureCluster();

// WHEN
new eks.HelmChart(stack, 'MyChart', { cluster, chart: 'chart' });

// THEN
const charts = Template.fromStack(stack).findResources(eks.HelmChart.RESOURCE_TYPE, { SkipCrds: false });
expect(Object.keys(charts).length).toEqual(0);
});
test('should enable atomic operations when specified', () => {
// GIVEN
const { stack, cluster } = testFixtureCluster();

// WHEN
new eks.HelmChart(stack, 'MyAtomicChart', { cluster, chart: 'chart', skipCrds: true });

// THEN
Template.fromStack(stack).hasResourceProperties(eks.HelmChart.RESOURCE_TYPE, { SkipCrds: true });
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def helm_handler(event, context):
create_namespace = props.get('CreateNamespace', None)
repository = props.get('Repository', None)
values_text = props.get('Values', None)
skip_crds = props.get('SkipCrds', False)

# "log in" to the cluster
subprocess.check_call([ 'aws', 'eks', 'update-kubeconfig',
Expand Down Expand Up @@ -146,7 +147,7 @@ def get_chart_from_oci(tmpdir, repository = None, version = None):
raise Exception(f'Operation failed after {maxAttempts} attempts: {output}')


def helm(verb, release, chart = None, repo = None, file = None, namespace = None, version = None, wait = False, timeout = None, create_namespace = None):
def helm(verb, release, chart = None, repo = None, file = None, namespace = None, version = None, wait = False, timeout = None, create_namespace = None, skip_crds = False):
import subprocess

cmnd = ['helm', verb, release]
Expand All @@ -166,6 +167,8 @@ def helm(verb, release, chart = None, repo = None, file = None, namespace = None
cmnd.extend(['--namespace', namespace])
if wait:
cmnd.append('--wait')
if skip_crds:
cmnd.append('--skip-crds')
if not timeout is None:
cmnd.extend(['--timeout', timeout])
cmnd.extend(['--kubeconfig', kubeconfig])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@
}
}
},
"c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8": {
"92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02": {
"source": {
"path": "asset.c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8",
"path": "asset.92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02",
"packaging": "zip"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8.zip",
"objectKey": "92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02.zip",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
Expand Down Expand Up @@ -105,28 +105,28 @@
}
}
},
"75cb3907a84a56903beb94d07a13f98c8f205e4c2592eca626920d0e31119d45": {
"228d4002689856d23e839fb690137b828253b51ab0ba4bd84b6ff0d65e1c23ca": {
"source": {
"path": "awscdkekshelmtestawscdkawseksKubectlProvider207F42E4.nested.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "75cb3907a84a56903beb94d07a13f98c8f205e4c2592eca626920d0e31119d45.json",
"objectKey": "228d4002689856d23e839fb690137b828253b51ab0ba4bd84b6ff0d65e1c23ca.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
},
"60857bca8b2d47131d19f9e53e3cfc304441787c56ab3ca35883021a9924a793": {
"efe0e6bc3feeea333864740608c04489da76bd20395f877733932bad8ccc7a66": {
"source": {
"path": "aws-cdk-eks-helm-test.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "60857bca8b2d47131d19f9e53e3cfc304441787c56ab3ca35883021a9924a793.json",
"objectKey": "efe0e6bc3feeea333864740608c04489da76bd20395f877733932bad8ccc7a66.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,38 @@
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"ClustercharttestskipcrdinstallationB8323954": {
"Type": "Custom::AWSCDK-EKS-HelmChart",
"Properties": {
"ServiceToken": {
"Fn::GetAtt": [
"awscdkawseksKubectlProviderNestedStackawscdkawseksKubectlProviderNestedStackResourceA7AEBA6B",
"Outputs.awscdkekshelmtestawscdkawseksKubectlProviderframeworkonEvent9D93C644Arn"
]
},
"ClusterName": {
"Ref": "Cluster9EE0221C"
},
"RoleArn": {
"Fn::GetAtt": [
"ClusterCreationRole360249B6",
"Arn"
]
},
"Release": "lambda-chart-release",
"Chart": "lambda-chart",
"Version": "v0.1.4",
"Namespace": "ack-system",
"Repository": "oci://public.ecr.aws/aws-controllers-k8s/lambda-chart",
"CreateNamespace": true,
"SkipCrds": true
},
"DependsOn": [
"ClusterKubectlReadyBarrier200052AF"
],
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"awscdkawseksClusterResourceProviderNestedStackawscdkawseksClusterResourceProviderNestedStackResource9827C454": {
"Type": "AWS::CloudFormation::Stack",
"Properties": {
Expand Down Expand Up @@ -1027,7 +1059,7 @@
{
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
},
"/75cb3907a84a56903beb94d07a13f98c8f205e4c2592eca626920d0e31119d45.json"
"/228d4002689856d23e839fb690137b828253b51ab0ba4bd84b6ff0d65e1c23ca.json"
]
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
},
"S3Key": "c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8.zip"
"S3Key": "92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02.zip"
},
"Role": {
"Fn::GetAtt": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"validateOnSynth": false,
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/60857bca8b2d47131d19f9e53e3cfc304441787c56ab3ca35883021a9924a793.json",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/efe0e6bc3feeea333864740608c04489da76bd20395f877733932bad8ccc7a66.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
Expand Down Expand Up @@ -255,6 +255,12 @@
"data": "Clustercharttestocichartdifferentreleasename6D3FD1A1"
}
],
"/aws-cdk-eks-helm-test/Cluster/chart-test-skip-crd-installation/Resource/Default": [
{
"type": "aws:cdk:logicalId",
"data": "ClustercharttestskipcrdinstallationB8323954"
}
],
"/aws-cdk-eks-helm-test/@aws-cdk--aws-eks.ClusterResourceProvider/NodeProxyAgentLayer/Resource": [
{
"type": "aws:cdk:logicalId",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,34 @@
"fqn": "@aws-cdk/aws-eks.HelmChart",
"version": "0.0.0"
}
},
"chart-test-skip-crd-installation": {
"id": "chart-test-skip-crd-installation",
"path": "aws-cdk-eks-helm-test/Cluster/chart-test-skip-crd-installation",
"children": {
"Resource": {
"id": "Resource",
"path": "aws-cdk-eks-helm-test/Cluster/chart-test-skip-crd-installation/Resource",
"children": {
"Default": {
"id": "Default",
"path": "aws-cdk-eks-helm-test/Cluster/chart-test-skip-crd-installation/Resource/Default",
"constructInfo": {
"fqn": "@aws-cdk/core.CfnResource",
"version": "0.0.0"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/core.CustomResource",
"version": "0.0.0"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/aws-eks.HelmChart",
"version": "0.0.0"
}
}
},
"constructInfo": {
Expand Down Expand Up @@ -2833,7 +2861,7 @@
"s3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
},
"s3Key": "c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8.zip"
"s3Key": "92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02.zip"
},
"role": {
"Fn::GetAtt": [
Expand Down Expand Up @@ -3255,7 +3283,7 @@
{
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
},
"/75cb3907a84a56903beb94d07a13f98c8f205e4c2592eca626920d0e31119d45.json"
"/228d4002689856d23e839fb690137b828253b51ab0ba4bd84b6ff0d65e1c23ca.json"
]
]
},
Expand Down
11 changes: 11 additions & 0 deletions packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,17 @@ class EksClusterStack extends Stack {
namespace: 'ack-system',
createNamespace: true,
});

// testing the disable mechanism of the installation of CRDs
this.cluster.addHelmChart('test-skip-crd-installation', {
chart: 'lambda-chart',
release: 'lambda-chart-release',
repository: 'oci://public.ecr.aws/aws-controllers-k8s/lambda-chart',
version: 'v0.1.4',
namespace: 'ack-system',
createNamespace: true,
skipCrds: true,
});
}
}

Expand Down

0 comments on commit b8de9d9

Please sign in to comment.