Skip to content

Commit f68dbc2

Browse files
feat(eks): add helm flag --skip-crds (#24213)
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 #24296 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 5aadf2a commit f68dbc2

File tree

15 files changed

+142
-14
lines changed

15 files changed

+142
-14
lines changed

Diff for: packages/@aws-cdk/aws-eks/README.md

+14
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,20 @@ cluster.addHelmChart('ExternalSecretsOperator', {
11931193
});
11941194
```
11951195

1196+
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.
1197+
1198+
```ts
1199+
declare const cluster: eks.Cluster;
1200+
// option 1: use a construct
1201+
new eks.HelmChart(this, 'NginxIngress', {
1202+
cluster,
1203+
chart: 'nginx-ingress',
1204+
repository: 'https://helm.nginx.com/stable',
1205+
namespace: 'kube-system',
1206+
skipCrds: true,
1207+
});
1208+
```
1209+
11961210
### OCI Charts
11971211

11981212
OCI charts are also supported.

Diff for: packages/@aws-cdk/aws-eks/lib/helm-chart.ts

+9
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ export interface HelmChartOptions {
7878
* @default true
7979
*/
8080
readonly createNamespace?: boolean;
81+
82+
/**
83+
* if set, no CRDs will be installed
84+
* @default - CRDs are installed if not already present
85+
*/
86+
readonly skipCrds?: boolean;
8187
}
8288

8389
/**
@@ -129,6 +135,8 @@ export class HelmChart extends Construct {
129135
const wait = props.wait ?? false;
130136
// default to create new namespace
131137
const createNamespace = props.createNamespace ?? true;
138+
// default to not skip crd installation
139+
const skipCrds = props.skipCrds ?? false;
132140

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

@@ -148,6 +156,7 @@ export class HelmChart extends Construct {
148156
Namespace: props.namespace ?? 'default',
149157
Repository: props.repository,
150158
CreateNamespace: createNamespace || undefined,
159+
SkipCrds: skipCrds || undefined,
151160
},
152161
});
153162
}

Diff for: packages/@aws-cdk/aws-eks/lib/kubectl-handler/helm/__init__.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def helm_handler(event, context):
4646
create_namespace = props.get('CreateNamespace', None)
4747
repository = props.get('Repository', None)
4848
values_text = props.get('Values', None)
49+
skip_crds = props.get('SkipCrds', False)
4950

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

148149

149-
def helm(verb, release, chart = None, repo = None, file = None, namespace = None, version = None, wait = False, timeout = None, create_namespace = None):
150+
def helm(verb, release, chart = None, repo = None, file = None, namespace = None, version = None, wait = False, timeout = None, create_namespace = None, skip_crds = False):
150151
import subprocess
151152

152153
cmnd = ['helm', verb, release]
@@ -166,6 +167,8 @@ def helm(verb, release, chart = None, repo = None, file = None, namespace = None
166167
cmnd.extend(['--namespace', namespace])
167168
if wait:
168169
cmnd.append('--wait')
170+
if skip_crds:
171+
cmnd.append('--skip-crds')
169172
if not timeout is None:
170173
cmnd.extend(['--timeout', timeout])
171174
cmnd.extend(['--kubeconfig', kubeconfig])

Diff for: packages/@aws-cdk/aws-eks/test/helm-chart.test.ts

+22
Original file line numberDiff line numberDiff line change
@@ -226,5 +226,27 @@ describe('helm chart', () => {
226226
// THEN
227227
Template.fromStack(stack).hasResourceProperties(eks.HelmChart.RESOURCE_TYPE, { Timeout: '600s' });
228228
});
229+
230+
test('should disable skip crds by default', () => {
231+
// GIVEN
232+
const { stack, cluster } = testFixtureCluster();
233+
234+
// WHEN
235+
new eks.HelmChart(stack, 'MyChart', { cluster, chart: 'chart' });
236+
237+
// THEN
238+
const charts = Template.fromStack(stack).findResources(eks.HelmChart.RESOURCE_TYPE, { SkipCrds: false });
239+
expect(Object.keys(charts).length).toEqual(0);
240+
});
241+
test('should enable atomic operations when specified', () => {
242+
// GIVEN
243+
const { stack, cluster } = testFixtureCluster();
244+
245+
// WHEN
246+
new eks.HelmChart(stack, 'MyAtomicChart', { cluster, chart: 'chart', skipCrds: true });
247+
248+
// THEN
249+
Template.fromStack(stack).hasResourceProperties(eks.HelmChart.RESOURCE_TYPE, { SkipCrds: true });
250+
});
229251
});
230252
});
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def helm_handler(event, context):
4646
create_namespace = props.get('CreateNamespace', None)
4747
repository = props.get('Repository', None)
4848
values_text = props.get('Values', None)
49+
skip_crds = props.get('SkipCrds', False)
4950

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

148149

149-
def helm(verb, release, chart = None, repo = None, file = None, namespace = None, version = None, wait = False, timeout = None, create_namespace = None):
150+
def helm(verb, release, chart = None, repo = None, file = None, namespace = None, version = None, wait = False, timeout = None, create_namespace = None, skip_crds = False):
150151
import subprocess
151152

152153
cmnd = ['helm', verb, release]
@@ -166,6 +167,8 @@ def helm(verb, release, chart = None, repo = None, file = None, namespace = None
166167
cmnd.extend(['--namespace', namespace])
167168
if wait:
168169
cmnd.append('--wait')
170+
if skip_crds:
171+
cmnd.append('--skip-crds')
169172
if not timeout is None:
170173
cmnd.extend(['--timeout', timeout])
171174
cmnd.extend(['--kubeconfig', kubeconfig])

Diff for: packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/aws-cdk-eks-helm-test.assets.json

+7-7
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,15 @@
5353
}
5454
}
5555
},
56-
"c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8": {
56+
"92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02": {
5757
"source": {
58-
"path": "asset.c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8",
58+
"path": "asset.92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02",
5959
"packaging": "zip"
6060
},
6161
"destinations": {
6262
"current_account-current_region": {
6363
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
64-
"objectKey": "c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8.zip",
64+
"objectKey": "92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02.zip",
6565
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
6666
}
6767
}
@@ -105,28 +105,28 @@
105105
}
106106
}
107107
},
108-
"75cb3907a84a56903beb94d07a13f98c8f205e4c2592eca626920d0e31119d45": {
108+
"228d4002689856d23e839fb690137b828253b51ab0ba4bd84b6ff0d65e1c23ca": {
109109
"source": {
110110
"path": "awscdkekshelmtestawscdkawseksKubectlProvider207F42E4.nested.template.json",
111111
"packaging": "file"
112112
},
113113
"destinations": {
114114
"current_account-current_region": {
115115
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
116-
"objectKey": "75cb3907a84a56903beb94d07a13f98c8f205e4c2592eca626920d0e31119d45.json",
116+
"objectKey": "228d4002689856d23e839fb690137b828253b51ab0ba4bd84b6ff0d65e1c23ca.json",
117117
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
118118
}
119119
}
120120
},
121-
"60857bca8b2d47131d19f9e53e3cfc304441787c56ab3ca35883021a9924a793": {
121+
"efe0e6bc3feeea333864740608c04489da76bd20395f877733932bad8ccc7a66": {
122122
"source": {
123123
"path": "aws-cdk-eks-helm-test.template.json",
124124
"packaging": "file"
125125
},
126126
"destinations": {
127127
"current_account-current_region": {
128128
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
129-
"objectKey": "60857bca8b2d47131d19f9e53e3cfc304441787c56ab3ca35883021a9924a793.json",
129+
"objectKey": "efe0e6bc3feeea333864740608c04489da76bd20395f877733932bad8ccc7a66.json",
130130
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
131131
}
132132
}

Diff for: packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/aws-cdk-eks-helm-test.template.json

+33-1
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,38 @@
973973
"UpdateReplacePolicy": "Delete",
974974
"DeletionPolicy": "Delete"
975975
},
976+
"ClustercharttestskipcrdinstallationB8323954": {
977+
"Type": "Custom::AWSCDK-EKS-HelmChart",
978+
"Properties": {
979+
"ServiceToken": {
980+
"Fn::GetAtt": [
981+
"awscdkawseksKubectlProviderNestedStackawscdkawseksKubectlProviderNestedStackResourceA7AEBA6B",
982+
"Outputs.awscdkekshelmtestawscdkawseksKubectlProviderframeworkonEvent9D93C644Arn"
983+
]
984+
},
985+
"ClusterName": {
986+
"Ref": "Cluster9EE0221C"
987+
},
988+
"RoleArn": {
989+
"Fn::GetAtt": [
990+
"ClusterCreationRole360249B6",
991+
"Arn"
992+
]
993+
},
994+
"Release": "lambda-chart-release",
995+
"Chart": "lambda-chart",
996+
"Version": "v0.1.4",
997+
"Namespace": "ack-system",
998+
"Repository": "oci://public.ecr.aws/aws-controllers-k8s/lambda-chart",
999+
"CreateNamespace": true,
1000+
"SkipCrds": true
1001+
},
1002+
"DependsOn": [
1003+
"ClusterKubectlReadyBarrier200052AF"
1004+
],
1005+
"UpdateReplacePolicy": "Delete",
1006+
"DeletionPolicy": "Delete"
1007+
},
9761008
"awscdkawseksClusterResourceProviderNestedStackawscdkawseksClusterResourceProviderNestedStackResource9827C454": {
9771009
"Type": "AWS::CloudFormation::Stack",
9781010
"Properties": {
@@ -1027,7 +1059,7 @@
10271059
{
10281060
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
10291061
},
1030-
"/75cb3907a84a56903beb94d07a13f98c8f205e4c2592eca626920d0e31119d45.json"
1062+
"/228d4002689856d23e839fb690137b828253b51ab0ba4bd84b6ff0d65e1c23ca.json"
10311063
]
10321064
]
10331065
},

Diff for: packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/awscdkekshelmtestawscdkawseksKubectlProvider207F42E4.nested.template.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@
145145
"S3Bucket": {
146146
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
147147
},
148-
"S3Key": "c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8.zip"
148+
"S3Key": "92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02.zip"
149149
},
150150
"Role": {
151151
"Fn::GetAtt": [

Diff for: packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/manifest.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"validateOnSynth": false,
1818
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
1919
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
20-
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/60857bca8b2d47131d19f9e53e3cfc304441787c56ab3ca35883021a9924a793.json",
20+
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/efe0e6bc3feeea333864740608c04489da76bd20395f877733932bad8ccc7a66.json",
2121
"requiresBootstrapStackVersion": 6,
2222
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
2323
"additionalDependencies": [
@@ -255,6 +255,12 @@
255255
"data": "Clustercharttestocichartdifferentreleasename6D3FD1A1"
256256
}
257257
],
258+
"/aws-cdk-eks-helm-test/Cluster/chart-test-skip-crd-installation/Resource/Default": [
259+
{
260+
"type": "aws:cdk:logicalId",
261+
"data": "ClustercharttestskipcrdinstallationB8323954"
262+
}
263+
],
258264
"/aws-cdk-eks-helm-test/@aws-cdk--aws-eks.ClusterResourceProvider/NodeProxyAgentLayer/Resource": [
259265
{
260266
"type": "aws:cdk:logicalId",

Diff for: packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/tree.json

+30-2
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,34 @@
13061306
"fqn": "@aws-cdk/aws-eks.HelmChart",
13071307
"version": "0.0.0"
13081308
}
1309+
},
1310+
"chart-test-skip-crd-installation": {
1311+
"id": "chart-test-skip-crd-installation",
1312+
"path": "aws-cdk-eks-helm-test/Cluster/chart-test-skip-crd-installation",
1313+
"children": {
1314+
"Resource": {
1315+
"id": "Resource",
1316+
"path": "aws-cdk-eks-helm-test/Cluster/chart-test-skip-crd-installation/Resource",
1317+
"children": {
1318+
"Default": {
1319+
"id": "Default",
1320+
"path": "aws-cdk-eks-helm-test/Cluster/chart-test-skip-crd-installation/Resource/Default",
1321+
"constructInfo": {
1322+
"fqn": "@aws-cdk/core.CfnResource",
1323+
"version": "0.0.0"
1324+
}
1325+
}
1326+
},
1327+
"constructInfo": {
1328+
"fqn": "@aws-cdk/core.CustomResource",
1329+
"version": "0.0.0"
1330+
}
1331+
}
1332+
},
1333+
"constructInfo": {
1334+
"fqn": "@aws-cdk/aws-eks.HelmChart",
1335+
"version": "0.0.0"
1336+
}
13091337
}
13101338
},
13111339
"constructInfo": {
@@ -2833,7 +2861,7 @@
28332861
"s3Bucket": {
28342862
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
28352863
},
2836-
"s3Key": "c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8.zip"
2864+
"s3Key": "92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02.zip"
28372865
},
28382866
"role": {
28392867
"Fn::GetAtt": [
@@ -3255,7 +3283,7 @@
32553283
{
32563284
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
32573285
},
3258-
"/75cb3907a84a56903beb94d07a13f98c8f205e4c2592eca626920d0e31119d45.json"
3286+
"/228d4002689856d23e839fb690137b828253b51ab0ba4bd84b6ff0d65e1c23ca.json"
32593287
]
32603288
]
32613289
},

Diff for: packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.ts

+11
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,17 @@ class EksClusterStack extends Stack {
7676
namespace: 'ack-system',
7777
createNamespace: true,
7878
});
79+
80+
// testing the disable mechanism of the installation of CRDs
81+
this.cluster.addHelmChart('test-skip-crd-installation', {
82+
chart: 'lambda-chart',
83+
release: 'lambda-chart-release',
84+
repository: 'oci://public.ecr.aws/aws-controllers-k8s/lambda-chart',
85+
version: 'v0.1.4',
86+
namespace: 'ack-system',
87+
createNamespace: true,
88+
skipCrds: true,
89+
});
7990
}
8091
}
8192

0 commit comments

Comments
 (0)