diff --git a/packages/@aws-cdk/aws-eks/README.md b/packages/@aws-cdk/aws-eks/README.md index e10cba101ec14..4b146e1d50d9c 100644 --- a/packages/@aws-cdk/aws-eks/README.md +++ b/packages/@aws-cdk/aws-eks/README.md @@ -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. diff --git a/packages/@aws-cdk/aws-eks/lib/helm-chart.ts b/packages/@aws-cdk/aws-eks/lib/helm-chart.ts index 9dfebd5ac0715..40e062ff157bd 100644 --- a/packages/@aws-cdk/aws-eks/lib/helm-chart.ts +++ b/packages/@aws-cdk/aws-eks/lib/helm-chart.ts @@ -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; } /** @@ -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); @@ -148,6 +156,7 @@ export class HelmChart extends Construct { Namespace: props.namespace ?? 'default', Repository: props.repository, CreateNamespace: createNamespace || undefined, + SkipCrds: skipCrds || undefined, }, }); } diff --git a/packages/@aws-cdk/aws-eks/lib/kubectl-handler/helm/__init__.py b/packages/@aws-cdk/aws-eks/lib/kubectl-handler/helm/__init__.py index 286976ced219a..34481f86a81d7 100644 --- a/packages/@aws-cdk/aws-eks/lib/kubectl-handler/helm/__init__.py +++ b/packages/@aws-cdk/aws-eks/lib/kubectl-handler/helm/__init__.py @@ -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', @@ -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] @@ -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]) diff --git a/packages/@aws-cdk/aws-eks/test/helm-chart.test.ts b/packages/@aws-cdk/aws-eks/test/helm-chart.test.ts index 6da8b851174eb..3587d4071bb2d 100644 --- a/packages/@aws-cdk/aws-eks/test/helm-chart.test.ts +++ b/packages/@aws-cdk/aws-eks/test/helm-chart.test.ts @@ -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 }); + }); }); }); diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8/apply/__init__.py b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02/apply/__init__.py similarity index 100% rename from packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8/apply/__init__.py rename to packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02/apply/__init__.py diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8/get/__init__.py b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02/get/__init__.py similarity index 100% rename from packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8/get/__init__.py rename to packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02/get/__init__.py diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8/helm/__init__.py b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02/helm/__init__.py similarity index 98% rename from packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8/helm/__init__.py rename to packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02/helm/__init__.py index 286976ced219a..34481f86a81d7 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8/helm/__init__.py +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02/helm/__init__.py @@ -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', @@ -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] @@ -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]) diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8/index.py b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02/index.py similarity index 100% rename from packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8/index.py rename to packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02/index.py diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8/patch/__init__.py b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02/patch/__init__.py similarity index 100% rename from packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8/patch/__init__.py rename to packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/asset.92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02/patch/__init__.py diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/aws-cdk-eks-helm-test.assets.json b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/aws-cdk-eks-helm-test.assets.json index 11e0e1b19d794..7264badd715f4 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/aws-cdk-eks-helm-test.assets.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/aws-cdk-eks-helm-test.assets.json @@ -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}" } } @@ -105,7 +105,7 @@ } } }, - "75cb3907a84a56903beb94d07a13f98c8f205e4c2592eca626920d0e31119d45": { + "228d4002689856d23e839fb690137b828253b51ab0ba4bd84b6ff0d65e1c23ca": { "source": { "path": "awscdkekshelmtestawscdkawseksKubectlProvider207F42E4.nested.template.json", "packaging": "file" @@ -113,12 +113,12 @@ "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" @@ -126,7 +126,7 @@ "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}" } } diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/aws-cdk-eks-helm-test.template.json b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/aws-cdk-eks-helm-test.template.json index faba886e3e890..29e21c9df3b32 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/aws-cdk-eks-helm-test.template.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/aws-cdk-eks-helm-test.template.json @@ -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": { @@ -1027,7 +1059,7 @@ { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "/75cb3907a84a56903beb94d07a13f98c8f205e4c2592eca626920d0e31119d45.json" + "/228d4002689856d23e839fb690137b828253b51ab0ba4bd84b6ff0d65e1c23ca.json" ] ] }, diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/awscdkekshelmtestawscdkawseksKubectlProvider207F42E4.nested.template.json b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/awscdkekshelmtestawscdkawseksKubectlProvider207F42E4.nested.template.json index 933401166ba6a..1d645caa5c219 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/awscdkekshelmtestawscdkawseksKubectlProvider207F42E4.nested.template.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/awscdkekshelmtestawscdkawseksKubectlProvider207F42E4.nested.template.json @@ -145,7 +145,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8.zip" + "S3Key": "92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02.zip" }, "Role": { "Fn::GetAtt": [ diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/manifest.json b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/manifest.json index 6e2dc2a0a68c6..1d20823d73040 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/manifest.json @@ -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": [ @@ -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", diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/tree.json b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/tree.json index 8091d68af0fde..3fb0075876cea 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.js.snapshot/tree.json @@ -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": { @@ -2833,7 +2861,7 @@ "s3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "s3Key": "c17e6c5822dd39738b3ba669bef4bb7c8fceaea76b51477bf94d6745d0c201c8.zip" + "s3Key": "92ea03f8b2e779503519f7781d06c03f95b46863db85f5c50a4e7debfd04be02.zip" }, "role": { "Fn::GetAtt": [ @@ -3255,7 +3283,7 @@ { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "/75cb3907a84a56903beb94d07a13f98c8f205e4c2592eca626920d0e31119d45.json" + "/228d4002689856d23e839fb690137b828253b51ab0ba4bd84b6ff0d65e1c23ca.json" ] ] }, diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.ts b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.ts index afda984814487..f266123a6c6c8 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.ts +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-helm-asset.ts @@ -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, + }); } }