From 63bc98f0d4a85b1c544d78420fd44579ce46a806 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 24 Dec 2020 11:06:56 +0200 Subject: [PATCH] feat(eks): bundle kubectl, helm and awscli instead of SAR app (#12129) The EKS module uses the AWS CLI, `kubectl` and `helm` in order to interact with the Kubernetes cluster. These tools were consumed from a SAR app maintained by @pahud as an AWS Sample (see [repo](https://github.com/aws-samples/aws-lambda-layer-kubectl)). This dependency on sample code introduces an operational and maintenance risk and as part of productizing the EKS module, we need to break it. The dependency on SAR is not required, and adds a few unnecessary layers (a nested stack, SAR regional availability, etc). To that end, this change bundles the AWS CLI and the Kubernetes tools (`kubectl` and `helm`) into the AWS CDK. These layers are maintained in two new CDK modules called `@aws-cdk/lambda-layer-awscli` and `@aws-cdk/lambda-layer-kubectl` respectively. These are normal CDK modules that export a `lambda.LayerVersion` resource that can be mounted to any AWS Lambda function. Since the s3-deployment module also needs the AWS CLI (and bundles it), we now reuse the AWS CLI layer in there as well. Module sizes: - lambda-layer-awscli: 10MiB - lambda-layer-kubectl: 24MiB This change increases the total module size of the MonoCDK by 24MiB (10MiB are reused with s3-deployment which was already bundled). In the future we are planning to remove these bundles from the library and publish them externally so they can be consumed at deploy-time but this is out of scope for this PR (see https://github.com/aws/aws-cdk-rfcs/issues/39). Resolves #11874 BREAKING CHANGE: the `@aws-cdk/eks.KubectlLayer` layer class has been moved to `@aws-cdk/lambda-layer-kubectl.KubectlLayer`. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../integ.app-mesh-proxy-config.expected.json | 14 +- .../test/ec2/integ.clb-host-nw.expected.json | 14 +- .../ec2/integ.environment-file.expected.json | 79 ++- .../integ.firelens-s3-config.expected.json | 12 +- .../test/ec2/integ.lb-awsvpc-nw.expected.json | 12 +- .../test/ec2/integ.lb-bridge-nw.expected.json | 12 +- .../test/ec2/integ.sd-awsvpc-nw.expected.json | 12 +- .../test/ec2/integ.sd-bridge-nw.expected.json | 12 +- .../ec2/integ.secret-json-field.expected.json | 2 +- .../test/ec2/integ.spot-drain.expected.json | 24 +- packages/@aws-cdk/aws-eks/README.md | 35 +- packages/@aws-cdk/aws-eks/lib/cluster.ts | 30 +- packages/@aws-cdk/aws-eks/lib/index.ts | 1 - .../@aws-cdk/aws-eks/lib/kubectl-layer.ts | 90 ---- .../@aws-cdk/aws-eks/lib/kubectl-provider.ts | 31 +- packages/@aws-cdk/aws-eks/package.json | 6 +- ...teg.eks-cluster-handlers-vpc.expected.json | 74 ++- ...eks-cluster-private-endpoint.expected.json | 74 ++- .../test/integ.eks-cluster.expected.json | 54 +- .../integ.eks-oidc-provider.expected.json | 8 +- .../test/integ.fargate-cluster.expected.json | 74 ++- .../@aws-cdk/aws-eks/test/test.cluster.ts | 73 --- .../aws-s3-deployment/lambda/build.sh | 39 -- .../@aws-cdk/aws-s3-deployment/lambda/src/aws | 27 - .../lambda/src/requirements.txt | 2 - .../aws-s3-deployment/lambda/src/setup.cfg | 2 - .../@aws-cdk/aws-s3-deployment/lambda/test.sh | 23 - .../aws-s3-deployment/lambda/test/aws | 27 - .../aws-s3-deployment/lambda/test/test.py | 483 ------------------ .../aws-s3-deployment/lambda/test/test.zip | Bin 179 -> 0 bytes .../lib/bucket-deployment.ts | 30 +- .../{lambda/src => lib/lambda}/index.py | 4 +- .../@aws-cdk/aws-s3-deployment/package.json | 9 +- ...bucket-deployment-cloudfront.expected.json | 79 ++- .../integ.bucket-deployment.expected.json | 211 +++++++- .../@aws-cdk/lambda-layer-awscli/.eslintrc.js | 3 + .../@aws-cdk/lambda-layer-awscli/.gitignore | 20 + .../@aws-cdk/lambda-layer-awscli/.npmignore | 30 ++ packages/@aws-cdk/lambda-layer-awscli/LICENSE | 201 ++++++++ packages/@aws-cdk/lambda-layer-awscli/NOTICE | 2 + .../@aws-cdk/lambda-layer-awscli/README.md | 28 + .../lambda-layer-awscli/jest.config.js | 2 + .../lambda-layer-awscli/layer/.dockerignore | 1 + .../lambda-layer-awscli/layer/Dockerfile | 51 ++ .../lambda-layer-awscli/layer/build.sh | 18 + .../lambda-layer-awscli/lib/awscli-layer.ts | 27 + .../@aws-cdk/lambda-layer-awscli/lib/index.ts | 1 + .../@aws-cdk/lambda-layer-awscli/package.json | 106 ++++ .../test/awscli-layer.test.ts | 16 + .../lambda-layer-kubectl/.eslintrc.js | 3 + .../@aws-cdk/lambda-layer-kubectl/.gitignore | 20 + .../@aws-cdk/lambda-layer-kubectl/.npmignore | 30 ++ .../@aws-cdk/lambda-layer-kubectl/LICENSE | 201 ++++++++ packages/@aws-cdk/lambda-layer-kubectl/NOTICE | 37 ++ .../@aws-cdk/lambda-layer-kubectl/README.md | 28 + .../lambda-layer-kubectl/jest.config.js | 2 + .../lambda-layer-kubectl/layer/.dockerignore | 1 + .../lambda-layer-kubectl/layer/Dockerfile | 47 ++ .../lambda-layer-kubectl/layer/build.sh | 18 + .../lambda-layer-kubectl/lib/index.ts | 1 + .../lambda-layer-kubectl/lib/kubectl-layer.ts | 27 + .../lambda-layer-kubectl/package.json | 112 ++++ .../test/kubectl-layer.test.ts | 16 + packages/aws-cdk-lib/package.json | 2 + packages/decdk/package.json | 2 + packages/monocdk/package.json | 4 + tools/pkglint/lib/rules.ts | 5 +- 67 files changed, 1723 insertions(+), 1018 deletions(-) delete mode 100644 packages/@aws-cdk/aws-eks/lib/kubectl-layer.ts delete mode 100755 packages/@aws-cdk/aws-s3-deployment/lambda/build.sh delete mode 100644 packages/@aws-cdk/aws-s3-deployment/lambda/src/aws delete mode 100644 packages/@aws-cdk/aws-s3-deployment/lambda/src/requirements.txt delete mode 100644 packages/@aws-cdk/aws-s3-deployment/lambda/src/setup.cfg delete mode 100755 packages/@aws-cdk/aws-s3-deployment/lambda/test.sh delete mode 100644 packages/@aws-cdk/aws-s3-deployment/lambda/test/aws delete mode 100644 packages/@aws-cdk/aws-s3-deployment/lambda/test/test.py delete mode 100644 packages/@aws-cdk/aws-s3-deployment/lambda/test/test.zip rename packages/@aws-cdk/aws-s3-deployment/{lambda/src => lib/lambda}/index.py (98%) create mode 100644 packages/@aws-cdk/lambda-layer-awscli/.eslintrc.js create mode 100644 packages/@aws-cdk/lambda-layer-awscli/.gitignore create mode 100644 packages/@aws-cdk/lambda-layer-awscli/.npmignore create mode 100644 packages/@aws-cdk/lambda-layer-awscli/LICENSE create mode 100644 packages/@aws-cdk/lambda-layer-awscli/NOTICE create mode 100644 packages/@aws-cdk/lambda-layer-awscli/README.md create mode 100644 packages/@aws-cdk/lambda-layer-awscli/jest.config.js create mode 100644 packages/@aws-cdk/lambda-layer-awscli/layer/.dockerignore create mode 100644 packages/@aws-cdk/lambda-layer-awscli/layer/Dockerfile create mode 100755 packages/@aws-cdk/lambda-layer-awscli/layer/build.sh create mode 100644 packages/@aws-cdk/lambda-layer-awscli/lib/awscli-layer.ts create mode 100644 packages/@aws-cdk/lambda-layer-awscli/lib/index.ts create mode 100644 packages/@aws-cdk/lambda-layer-awscli/package.json create mode 100644 packages/@aws-cdk/lambda-layer-awscli/test/awscli-layer.test.ts create mode 100644 packages/@aws-cdk/lambda-layer-kubectl/.eslintrc.js create mode 100644 packages/@aws-cdk/lambda-layer-kubectl/.gitignore create mode 100644 packages/@aws-cdk/lambda-layer-kubectl/.npmignore create mode 100644 packages/@aws-cdk/lambda-layer-kubectl/LICENSE create mode 100644 packages/@aws-cdk/lambda-layer-kubectl/NOTICE create mode 100644 packages/@aws-cdk/lambda-layer-kubectl/README.md create mode 100644 packages/@aws-cdk/lambda-layer-kubectl/jest.config.js create mode 100644 packages/@aws-cdk/lambda-layer-kubectl/layer/.dockerignore create mode 100644 packages/@aws-cdk/lambda-layer-kubectl/layer/Dockerfile create mode 100755 packages/@aws-cdk/lambda-layer-kubectl/layer/build.sh create mode 100644 packages/@aws-cdk/lambda-layer-kubectl/lib/index.ts create mode 100644 packages/@aws-cdk/lambda-layer-kubectl/lib/kubectl-layer.ts create mode 100644 packages/@aws-cdk/lambda-layer-kubectl/package.json create mode 100644 packages/@aws-cdk/lambda-layer-kubectl/test/kubectl-layer.test.ts diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.app-mesh-proxy-config.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.app-mesh-proxy-config.expected.json index 24784b1521a45..0c64ae63155b9 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.app-mesh-proxy-config.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.app-mesh-proxy-config.expected.json @@ -437,8 +437,6 @@ "ecs:Poll", "ecs:StartTelemetrySession" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -448,7 +446,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ @@ -636,8 +636,6 @@ "ecs:DescribeContainerInstances", "ecs:DescribeTasks" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -647,7 +645,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ @@ -874,8 +874,8 @@ ], "Family": "awsecsintegTaskDef6FDFB69A", "IpcMode": "host", - "PidMode": "task", "NetworkMode": "awsvpc", + "PidMode": "task", "ProxyConfiguration": { "ContainerName": "envoy", "ProxyConfigurationProperties": [ diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.clb-host-nw.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.clb-host-nw.expected.json index 80111c4451470..62d48e3bced1e 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.clb-host-nw.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.clb-host-nw.expected.json @@ -458,8 +458,6 @@ "ecs:Poll", "ecs:StartTelemetrySession" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -469,7 +467,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ @@ -657,8 +657,6 @@ "ecs:DescribeContainerInstances", "ecs:DescribeTasks" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -668,7 +666,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ @@ -895,8 +895,8 @@ ], "Family": "awsecsintegTaskDef6FDFB69A", "IpcMode": "host", - "PidMode": "task", "NetworkMode": "host", + "PidMode": "task", "RequiresCompatibilities": [ "EC2" ], diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.environment-file.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.environment-file.expected.json index 0c611b4879869..c2a555e9c9a71 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.environment-file.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.environment-file.expected.json @@ -991,6 +991,50 @@ } } }, + "EnvFileDeploymentAwsCliLayerA8FC897D": { + "Type": "AWS::Lambda::LayerVersion", + "Properties": { + "Content": { + "S3Bucket": { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3BucketAEADE8C7" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" + } + ] + } + ] + } + ] + ] + } + }, + "Description": "/opt/awscli/aws" + } + }, "EnvFileDeploymentCustomResourceDBE78DE4": { "Type": "Custom::CDKBucketDeployment", "Properties": { @@ -1175,7 +1219,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3Bucket77147E20" + "Ref": "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3Bucket28CE5152" }, "S3Key": { "Fn::Join": [ @@ -1188,7 +1232,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3VersionKey4253216F" + "Ref": "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3VersionKeyAF6E05ED" } ] } @@ -1201,7 +1245,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3VersionKey4253216F" + "Ref": "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3VersionKeyAF6E05ED" } ] } @@ -1219,6 +1263,11 @@ ] }, "Runtime": "python3.6", + "Layers": [ + { + "Ref": "EnvFileDeploymentAwsCliLayerA8FC897D" + } + ], "Timeout": 900 }, "DependsOn": [ @@ -1288,17 +1337,29 @@ "Type": "AWS::SSM::Parameter::Value", "Default": "/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id" }, - "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3Bucket77147E20": { + "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3BucketAEADE8C7": { + "Type": "String", + "Description": "S3 bucket for asset \"e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68\"" + }, + "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F": { + "Type": "String", + "Description": "S3 key for asset version \"e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68\"" + }, + "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68ArtifactHashD9A515C3": { + "Type": "String", + "Description": "Artifact hash for asset \"e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68\"" + }, + "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3Bucket28CE5152": { "Type": "String", - "Description": "S3 bucket for asset \"c9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176\"" + "Description": "S3 bucket for asset \"3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7\"" }, - "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3VersionKey4253216F": { + "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3VersionKeyAF6E05ED": { "Type": "String", - "Description": "S3 key for asset version \"c9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176\"" + "Description": "S3 key for asset version \"3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7\"" }, - "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176ArtifactHash4E343C6C": { + "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7ArtifactHash8926088E": { "Type": "String", - "Description": "Artifact hash for asset \"c9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176\"" + "Description": "Artifact hash for asset \"3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7\"" }, "AssetParameters972240f9dd6e036a93d5f081af9a24315b2053828ac049b3b19b2fa12d7ae64aS3Bucket1F1A8472": { "Type": "String", diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.firelens-s3-config.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.firelens-s3-config.expected.json index ba3354e59a7ef..bd368de2a0f11 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.firelens-s3-config.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.firelens-s3-config.expected.json @@ -437,8 +437,6 @@ "ecs:Poll", "ecs:StartTelemetrySession" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -448,7 +446,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ @@ -636,8 +636,6 @@ "ecs:DescribeContainerInstances", "ecs:DescribeTasks" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -647,7 +645,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.expected.json index 743c08d9f537a..0d3144db3f8f1 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.expected.json @@ -437,8 +437,6 @@ "ecs:Poll", "ecs:StartTelemetrySession" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -448,7 +446,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ @@ -636,8 +636,6 @@ "ecs:DescribeContainerInstances", "ecs:DescribeTasks" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -647,7 +645,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.expected.json index 3cfe5df21405a..a66e3674dd919 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.expected.json @@ -458,8 +458,6 @@ "ecs:Poll", "ecs:StartTelemetrySession" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -469,7 +467,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ @@ -657,8 +657,6 @@ "ecs:DescribeContainerInstances", "ecs:DescribeTasks" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -668,7 +666,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-awsvpc-nw.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-awsvpc-nw.expected.json index 66d961bceb04b..e8638efad5f38 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-awsvpc-nw.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-awsvpc-nw.expected.json @@ -437,8 +437,6 @@ "ecs:Poll", "ecs:StartTelemetrySession" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -448,7 +446,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ @@ -636,8 +636,6 @@ "ecs:DescribeContainerInstances", "ecs:DescribeTasks" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -647,7 +645,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-bridge-nw.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-bridge-nw.expected.json index 2214c69632d98..7d0f3770d69ce 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-bridge-nw.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-bridge-nw.expected.json @@ -437,8 +437,6 @@ "ecs:Poll", "ecs:StartTelemetrySession" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -448,7 +446,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ @@ -636,8 +636,6 @@ "ecs:DescribeContainerInstances", "ecs:DescribeTasks" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -647,7 +645,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.secret-json-field.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.secret-json-field.expected.json index f214a22fea2cb..6fe13e7abc27e 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.secret-json-field.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.secret-json-field.expected.json @@ -116,4 +116,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.spot-drain.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.spot-drain.expected.json index 3c78f85f86425..aaa968ada846f 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.spot-drain.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.spot-drain.expected.json @@ -437,8 +437,6 @@ "ecs:Poll", "ecs:StartTelemetrySession" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -448,7 +446,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ @@ -638,8 +638,6 @@ "ecs:DescribeContainerInstances", "ecs:DescribeTasks" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -649,7 +647,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ @@ -919,8 +919,6 @@ "ecs:Poll", "ecs:StartTelemetrySession" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -930,7 +928,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ @@ -1119,8 +1119,6 @@ "ecs:DescribeContainerInstances", "ecs:DescribeTasks" ], - "Effect": "Allow", - "Resource": "*", "Condition": { "ArnEquals": { "ecs:cluster": { @@ -1130,7 +1128,9 @@ ] } } - } + }, + "Effect": "Allow", + "Resource": "*" }, { "Action": [ diff --git a/packages/@aws-cdk/aws-eks/README.md b/packages/@aws-cdk/aws-eks/README.md index 75f943307f8e5..0b92c183fb786 100644 --- a/packages/@aws-cdk/aws-eks/README.md +++ b/packages/@aws-cdk/aws-eks/README.md @@ -515,26 +515,32 @@ const cluster = new eks.Cluster(this, 'hello-eks', { #### Runtime -By default, the `kubectl`, `helm` and `aws` commands used to operate the cluster are provided by an AWS Lambda Layer from the AWS Serverless Application in [aws-lambda-layer-kubectl](https://github.com/aws-samples/aws-lambda-layer-kubectl). In most cases this should be sufficient. +The kubectl handler uses `kubectl`, `helm` and the `aws` CLI in order to +interact with the cluster. These are bundled into AWS Lambda layers included in +the `@aws-cdk/lambda-layer-awscli` and `@aws-cdk/lambda-layer-kubectl` modules. -You can provide a custom layer in case the default layer does not meet your -needs or if the SAR app is not available in your region. +You can specify a custom `lambda.LayerVersion` if you wish to use a different +version of these tools. The handler expects the layer to include the following +three executables: + +```text +helm/helm +kubectl/kubectl +awscli/aws +``` + +See more information in the +[Dockerfile](https://github.com/aws/aws-cdk/tree/master/packages/%40aws-cdk/lambda-layer-awscli/layer) for @aws-cdk/lambda-layer-awscli +and the +[Dockerfile](https://github.com/aws/aws-cdk/tree/master/packages/%40aws-cdk/lambda-layer-kubectl/layer) for @aws-cdk/lambda-layer-kubectl. ```ts -// custom build: const layer = new lambda.LayerVersion(this, 'KubectlLayer', { - code: lambda.Code.fromAsset(`${__dirname}/layer.zip`)), - compatibleRuntimes: [lambda.Runtime.PROVIDED] -}); - -// or, a specific version or appid of aws-lambda-layer-kubectl: -const layer = new eks.KubectlLayer(this, 'KubectlLayer', { - version: '2.0.0', // optional - applicationId: '...' // optional + code: lambda.Code.fromAsset('layer.zip'), }); ``` -Pass it to `kubectlLayer` when you create or import a cluster: +Now specify when the cluster is defined: ```ts const cluster = new eks.Cluster(this, 'MyCluster', { @@ -547,9 +553,6 @@ const cluster = eks.Cluster.fromClusterAttributes(this, 'MyCluster', { }); ``` -> Instructions on how to build `layer.zip` can be found -> [here](https://github.com/aws-samples/aws-lambda-layer-kubectl/blob/master/cdk/README.md). - #### Memory By default, the kubectl provider is configured with 1024MiB of memory. You can use the `kubectlMemory` option to specify the memory size for the AWS Lambda function: diff --git a/packages/@aws-cdk/aws-eks/lib/cluster.ts b/packages/@aws-cdk/aws-eks/lib/cluster.ts index 1985f893ca048..849d0a50c5d5f 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster.ts @@ -261,32 +261,16 @@ export interface ClusterAttributes { readonly openIdConnectProvider?: iam.IOpenIdConnectProvider; /** - * An AWS Lambda Layer which includes `kubectl`, Helm and the AWS CLI. + * An AWS Lambda Layer which includes `kubectl`, Helm and the AWS CLI. This layer + * is used by the kubectl handler to apply manifests and install helm charts. * - * By default, the provider will use the layer included in the - * "aws-lambda-layer-kubectl" SAR application which is available in all - * commercial regions. + * The handler expects the layer to include the following executables: * - * To deploy the layer locally, visit - * https://github.com/aws-samples/aws-lambda-layer-kubectl/blob/master/cdk/README.md - * for instructions on how to prepare the .zip file and then define it in your - * app as follows: + * helm/helm + * kubectl/kubectl + * awscli/aws * - * ```ts - * const layer = new lambda.LayerVersion(this, 'kubectl-layer', { - * code: lambda.Code.fromAsset(`${__dirname}/layer.zip`)), - * compatibleRuntimes: [lambda.Runtime.PROVIDED] - * }); - * - * Or you can use the standard layer like this (with options - * to customize the version and SAR application ID): - * - * ```ts - * const layer = new eks.KubectlLayer(this, 'KubectlLayer'); - * ``` - * - * @default - the layer provided by the `aws-lambda-layer-kubectl` SAR app. - * @see https://github.com/aws-samples/aws-lambda-layer-kubectl + * @default - a layer bundled with this module. */ readonly kubectlLayer?: lambda.ILayerVersion; diff --git a/packages/@aws-cdk/aws-eks/lib/index.ts b/packages/@aws-cdk/aws-eks/lib/index.ts index eac2aa14eebc2..454242cf5259f 100644 --- a/packages/@aws-cdk/aws-eks/lib/index.ts +++ b/packages/@aws-cdk/aws-eks/lib/index.ts @@ -10,5 +10,4 @@ export * from './k8s-object-value'; export * from './fargate-cluster'; export * from './service-account'; export * from './managed-nodegroup'; -export * from './kubectl-layer'; export * from './oidc-provider'; diff --git a/packages/@aws-cdk/aws-eks/lib/kubectl-layer.ts b/packages/@aws-cdk/aws-eks/lib/kubectl-layer.ts deleted file mode 100644 index cf57b3189b1e5..0000000000000 --- a/packages/@aws-cdk/aws-eks/lib/kubectl-layer.ts +++ /dev/null @@ -1,90 +0,0 @@ -import * as crypto from 'crypto'; -import * as lambda from '@aws-cdk/aws-lambda'; -import { CfnResource, Token, Stack, ResourceEnvironment } from '@aws-cdk/core'; -import { Construct } from 'constructs'; - -const KUBECTL_APP_ARN = 'arn:aws:serverlessrepo:us-east-1:903779448426:applications/lambda-layer-kubectl'; -const KUBECTL_APP_CN_ARN = 'arn:aws-cn:serverlessrepo:cn-north-1:487369736442:applications/lambda-layer-kubectl'; -const KUBECTL_APP_VERSION = '2.0.0'; - -// v2 - keep this import as a separate section to reduce merge conflict when forward merging with the v2 branch. -// eslint-disable-next-line -import { Construct as CoreConstruct } from '@aws-cdk/core'; - -/** - * Properties for KubectlLayer. - */ -export interface KubectlLayerProps { - /** - * The semantic version of the kubectl AWS Lambda Layer SAR app to use. - * - * @default '2.0.0' - */ - readonly version?: string; - - /** - * The Serverless Application Repository application ID which contains the kubectl layer. - * @default - The ARN for the `lambda-layer-kubectl` SAR app. - * @see https://github.com/aws-samples/aws-lambda-layer-kubectl - */ - readonly applicationId?: string; -} - -/** - * An AWS Lambda layer that includes kubectl and the AWS CLI. - * - * @see https://github.com/aws-samples/aws-lambda-layer-kubectl - */ -export class KubectlLayer extends CoreConstruct implements lambda.ILayerVersion { - /** - * The ARN of the AWS Lambda layer version. - */ - public readonly layerVersionArn: string; - - public readonly stack: Stack; - public readonly env: ResourceEnvironment; - - /** - * All runtimes are compatible. - */ - public readonly compatibleRuntimes?: lambda.Runtime[] = undefined; - - constructor(scope: Construct, id: string, props: KubectlLayerProps = {}) { - super(scope, id); - - this.stack = Stack.of(this); - this.env = { - account: this.stack.account, - region: this.stack.region, - }; - - const uniqueId = crypto.createHash('md5').update(this.node.path).digest('hex'); - const version = props.version ?? KUBECTL_APP_VERSION; - const applictionId = props.applicationId ?? (this.isChina() ? KUBECTL_APP_CN_ARN : KUBECTL_APP_ARN); - - this.stack.templateOptions.transforms = ['AWS::Serverless-2016-10-31']; // required for AWS::Serverless - const resource = new CfnResource(this, 'Resource', { - type: 'AWS::Serverless::Application', - properties: { - Location: { - ApplicationId: applictionId, - SemanticVersion: version, - }, - Parameters: { - LayerName: `kubectl-${uniqueId}`, - }, - }, - }); - - this.layerVersionArn = Token.asString(resource.getAtt('Outputs.LayerVersionArn')); - } - - public addPermission(_id: string, _permission: lambda.LayerVersionPermission): void { - return; - } - - private isChina(): boolean { - const region = this.stack.region; - return !Token.isUnresolved(region) && region.startsWith('cn-'); - } -} diff --git a/packages/@aws-cdk/aws-eks/lib/kubectl-provider.ts b/packages/@aws-cdk/aws-eks/lib/kubectl-provider.ts index 359eb79b970a5..e4c71cfda381c 100644 --- a/packages/@aws-cdk/aws-eks/lib/kubectl-provider.ts +++ b/packages/@aws-cdk/aws-eks/lib/kubectl-provider.ts @@ -3,9 +3,10 @@ import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; import { Duration, Stack, NestedStack, Names } from '@aws-cdk/core'; import * as cr from '@aws-cdk/custom-resources'; +import { AwsCliLayer } from '@aws-cdk/lambda-layer-awscli'; +import { KubectlLayer } from '@aws-cdk/lambda-layer-kubectl'; import { Construct } from 'constructs'; import { ICluster, Cluster } from './cluster'; -import { KubectlLayer, KubectlLayerProps } from './kubectl-layer'; // v2 - keep this import as a separate section to reduce merge conflict when forward merging with the v2 branch. // eslint-disable-next-line @@ -66,7 +67,6 @@ export class KubectlProvider extends NestedStack { throw new Error('"kubectlSecurityGroup" is required if "kubectlSubnets" is specified'); } - const layer = cluster.kubectlLayer ?? getOrCreateKubectlLayer(this); const memorySize = cluster.kubectlMemory ? cluster.kubectlMemory.toMebibytes() : 1024; const handler = new lambda.Function(this, 'Handler', { @@ -75,7 +75,6 @@ export class KubectlProvider extends NestedStack { handler: 'index.handler', timeout: Duration.minutes(15), description: 'onEvent handler for EKS kubectl resource provider', - layers: [layer], memorySize, environment: cluster.kubectlEnvironment, @@ -85,9 +84,17 @@ export class KubectlProvider extends NestedStack { vpcSubnets: cluster.kubectlPrivateSubnets ? { subnets: cluster.kubectlPrivateSubnets } : undefined, }); + // allow user to customize the layer + if (!props.cluster.kubectlLayer) { + handler.addLayers(new AwsCliLayer(this, 'AwsCliLayer')); + handler.addLayers(new KubectlLayer(this, 'KubectlLayer')); + } else { + handler.addLayers(props.cluster.kubectlLayer); + } + this.handlerRole = handler.role!; - this.handlerRole.addToPolicy(new iam.PolicyStatement({ + this.handlerRole.addToPrincipalPolicy(new iam.PolicyStatement({ actions: ['eks:DescribeCluster'], resources: [cluster.clusterArn], })); @@ -106,19 +113,3 @@ export class KubectlProvider extends NestedStack { } } - -/** - * Gets or create a singleton instance of KubectlLayer. - * - * (exported for unit tests). - */ -export function getOrCreateKubectlLayer(scope: Construct, props: KubectlLayerProps = {}): KubectlLayer { - const stack = Stack.of(scope); - const id = 'kubectl-layer-' + (props.version ? props.version : '8C2542BC-BF2B-4DFE-B765-E181FD30A9A0'); - const exists = stack.node.tryFindChild(id) as KubectlLayer; - if (exists) { - return exists; - } - - return new KubectlLayer(stack, id, props); -} diff --git a/packages/@aws-cdk/aws-eks/package.json b/packages/@aws-cdk/aws-eks/package.json index a57aaa253db2f..658a302f3d697 100644 --- a/packages/@aws-cdk/aws-eks/package.json +++ b/packages/@aws-cdk/aws-eks/package.json @@ -94,6 +94,8 @@ "@aws-cdk/aws-ssm": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/custom-resources": "0.0.0", + "@aws-cdk/lambda-layer-awscli": "0.0.0", + "@aws-cdk/lambda-layer-kubectl": "0.0.0", "constructs": "^3.2.0", "yaml": "1.10.0" }, @@ -110,7 +112,9 @@ "@aws-cdk/aws-ssm": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/custom-resources": "0.0.0", - "constructs": "^3.2.0" + "constructs": "^3.2.0", + "@aws-cdk/lambda-layer-awscli": "0.0.0", + "@aws-cdk/lambda-layer-kubectl": "0.0.0" }, "engines": { "node": ">= 10.13.0 <13 || >=13.7.0" diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-handlers-vpc.expected.json b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-handlers-vpc.expected.json index 64485db691f5b..82488919bedb9 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-handlers-vpc.expected.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-handlers-vpc.expected.json @@ -1208,7 +1208,7 @@ }, "/", { - "Ref": "AssetParameters6d292454aff7fb0ebe25e490b924c9c6b388e55e40b8969d458dc14694f8e195S3BucketED10A01F" + "Ref": "AssetParameters11ba420a0c99f0c77f563fb974e76d6110b4445114137af1fe1b69b0d366d2d7S3BucketE510C342" }, "/", { @@ -1218,7 +1218,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters6d292454aff7fb0ebe25e490b924c9c6b388e55e40b8969d458dc14694f8e195S3VersionKey4F604E85" + "Ref": "AssetParameters11ba420a0c99f0c77f563fb974e76d6110b4445114137af1fe1b69b0d366d2d7S3VersionKeyD31A83B6" } ] } @@ -1231,7 +1231,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters6d292454aff7fb0ebe25e490b924c9c6b388e55e40b8969d458dc14694f8e195S3VersionKey4F604E85" + "Ref": "AssetParameters11ba420a0c99f0c77f563fb974e76d6110b4445114137af1fe1b69b0d366d2d7S3VersionKeyD31A83B6" } ] } @@ -1253,11 +1253,11 @@ "Arn" ] }, - "referencetoawscdkekshandlersinvpctestAssetParametersd01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34fS3BucketAC8D81C6Ref": { - "Ref": "AssetParametersd01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34fS3Bucket81EA5F11" + "referencetoawscdkekshandlersinvpctestAssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3BucketF3527C76Ref": { + "Ref": "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3Bucket008DBB35" }, - "referencetoawscdkekshandlersinvpctestAssetParametersd01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34fS3VersionKeyA25C9B33Ref": { - "Ref": "AssetParametersd01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34fS3VersionKey32DED07C" + "referencetoawscdkekshandlersinvpctestAssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3VersionKeyE9C79D35Ref": { + "Ref": "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3VersionKey97C3E1A0" }, "referencetoawscdkekshandlersinvpctestEksAllHandlersInVpcStackDefaultVpcPrivateSubnet1Subnet9479BAA8Ref": { "Ref": "EksAllHandlersInVpcStackDefaultVpcPrivateSubnet1SubnetE2B86978" @@ -1274,6 +1274,18 @@ "ClusterSecurityGroupId" ] }, + "referencetoawscdkekshandlersinvpctestAssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3BucketC0281AE8Ref": { + "Ref": "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3Bucket6DACDE73" + }, + "referencetoawscdkekshandlersinvpctestAssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3VersionKeyD6BA7117Ref": { + "Ref": "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3VersionKey015AEA61" + }, + "referencetoawscdkekshandlersinvpctestAssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3Bucket88622CD5Ref": { + "Ref": "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3Bucket7EE7EA15" + }, + "referencetoawscdkekshandlersinvpctestAssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3VersionKey1C342D31Ref": { + "Ref": "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3VersionKey6C948E78" + }, "referencetoawscdkekshandlersinvpctestEksAllHandlersInVpcStackDefaultVpcE40EA7ACRef": { "Ref": "EksAllHandlersInVpcStackDefaultVpcBE11D4AE" }, @@ -1354,17 +1366,41 @@ "Type": "String", "Description": "Artifact hash for asset \"daeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1\"" }, - "AssetParametersd01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34fS3Bucket81EA5F11": { + "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3Bucket008DBB35": { + "Type": "String", + "Description": "S3 bucket for asset \"bafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757\"" + }, + "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3VersionKey97C3E1A0": { + "Type": "String", + "Description": "S3 key for asset version \"bafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757\"" + }, + "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757ArtifactHashF584A7D8": { + "Type": "String", + "Description": "Artifact hash for asset \"bafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757\"" + }, + "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3Bucket6DACDE73": { + "Type": "String", + "Description": "S3 bucket for asset \"efd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1\"" + }, + "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3VersionKey015AEA61": { + "Type": "String", + "Description": "S3 key for asset version \"efd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1\"" + }, + "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1ArtifactHashC9FD06BA": { + "Type": "String", + "Description": "Artifact hash for asset \"efd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1\"" + }, + "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3Bucket7EE7EA15": { "Type": "String", - "Description": "S3 bucket for asset \"d01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34f\"" + "Description": "S3 bucket for asset \"b61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449f\"" }, - "AssetParametersd01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34fS3VersionKey32DED07C": { + "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3VersionKey6C948E78": { "Type": "String", - "Description": "S3 key for asset version \"d01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34f\"" + "Description": "S3 key for asset version \"b61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449f\"" }, - "AssetParametersd01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34fArtifactHashE68669BA": { + "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fArtifactHash7E705796": { "Type": "String", - "Description": "Artifact hash for asset \"d01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34f\"" + "Description": "Artifact hash for asset \"b61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449f\"" }, "AssetParameters1a2bf12b9f0cf5ab2c838e7dd9be4d485bbf32056d6d5333bce57e49d12a172cS3Bucket151BE34C": { "Type": "String", @@ -1378,17 +1414,17 @@ "Type": "String", "Description": "Artifact hash for asset \"1a2bf12b9f0cf5ab2c838e7dd9be4d485bbf32056d6d5333bce57e49d12a172c\"" }, - "AssetParameters6d292454aff7fb0ebe25e490b924c9c6b388e55e40b8969d458dc14694f8e195S3BucketED10A01F": { + "AssetParameters11ba420a0c99f0c77f563fb974e76d6110b4445114137af1fe1b69b0d366d2d7S3BucketE510C342": { "Type": "String", - "Description": "S3 bucket for asset \"6d292454aff7fb0ebe25e490b924c9c6b388e55e40b8969d458dc14694f8e195\"" + "Description": "S3 bucket for asset \"11ba420a0c99f0c77f563fb974e76d6110b4445114137af1fe1b69b0d366d2d7\"" }, - "AssetParameters6d292454aff7fb0ebe25e490b924c9c6b388e55e40b8969d458dc14694f8e195S3VersionKey4F604E85": { + "AssetParameters11ba420a0c99f0c77f563fb974e76d6110b4445114137af1fe1b69b0d366d2d7S3VersionKeyD31A83B6": { "Type": "String", - "Description": "S3 key for asset version \"6d292454aff7fb0ebe25e490b924c9c6b388e55e40b8969d458dc14694f8e195\"" + "Description": "S3 key for asset version \"11ba420a0c99f0c77f563fb974e76d6110b4445114137af1fe1b69b0d366d2d7\"" }, - "AssetParameters6d292454aff7fb0ebe25e490b924c9c6b388e55e40b8969d458dc14694f8e195ArtifactHashFB75BE03": { + "AssetParameters11ba420a0c99f0c77f563fb974e76d6110b4445114137af1fe1b69b0d366d2d7ArtifactHash1C37295C": { "Type": "String", - "Description": "Artifact hash for asset \"6d292454aff7fb0ebe25e490b924c9c6b388e55e40b8969d458dc14694f8e195\"" + "Description": "Artifact hash for asset \"11ba420a0c99f0c77f563fb974e76d6110b4445114137af1fe1b69b0d366d2d7\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-private-endpoint.expected.json b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-private-endpoint.expected.json index 1b3b3db682b51..f76e62c73ee73 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-private-endpoint.expected.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-private-endpoint.expected.json @@ -1129,7 +1129,7 @@ }, "/", { - "Ref": "AssetParameters82a02b024ddccd7e1020d7fb799652ba63ec9fc1b0605b3011233acd374b1601S3Bucket69FEE662" + "Ref": "AssetParameters2e2ec0fae5975d4ee5f3580e522c46615c1bd344e0302bc5d2df7501b7bb1ad0S3Bucket8FBFE327" }, "/", { @@ -1139,7 +1139,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters82a02b024ddccd7e1020d7fb799652ba63ec9fc1b0605b3011233acd374b1601S3VersionKeyF62FBF50" + "Ref": "AssetParameters2e2ec0fae5975d4ee5f3580e522c46615c1bd344e0302bc5d2df7501b7bb1ad0S3VersionKeyF5A05918" } ] } @@ -1152,7 +1152,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters82a02b024ddccd7e1020d7fb799652ba63ec9fc1b0605b3011233acd374b1601S3VersionKeyF62FBF50" + "Ref": "AssetParameters2e2ec0fae5975d4ee5f3580e522c46615c1bd344e0302bc5d2df7501b7bb1ad0S3VersionKeyF5A05918" } ] } @@ -1174,11 +1174,11 @@ "Arn" ] }, - "referencetoawscdkeksclusterprivateendpointtestAssetParametersd01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34fS3Bucket254F28AERef": { - "Ref": "AssetParametersd01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34fS3Bucket81EA5F11" + "referencetoawscdkeksclusterprivateendpointtestAssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3BucketD11B5EC1Ref": { + "Ref": "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3Bucket008DBB35" }, - "referencetoawscdkeksclusterprivateendpointtestAssetParametersd01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34fS3VersionKeyE913A985Ref": { - "Ref": "AssetParametersd01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34fS3VersionKey32DED07C" + "referencetoawscdkeksclusterprivateendpointtestAssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3VersionKey8375F1D2Ref": { + "Ref": "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3VersionKey97C3E1A0" }, "referencetoawscdkeksclusterprivateendpointtestVpcPrivateSubnet1Subnet94DAD769Ref": { "Ref": "VpcPrivateSubnet1Subnet536B997A" @@ -1195,6 +1195,18 @@ "ClusterSecurityGroupId" ] }, + "referencetoawscdkeksclusterprivateendpointtestAssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3Bucket4A0D6BE2Ref": { + "Ref": "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3Bucket6DACDE73" + }, + "referencetoawscdkeksclusterprivateendpointtestAssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3VersionKey6D9B8A02Ref": { + "Ref": "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3VersionKey015AEA61" + }, + "referencetoawscdkeksclusterprivateendpointtestAssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3BucketD44FB215Ref": { + "Ref": "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3Bucket7EE7EA15" + }, + "referencetoawscdkeksclusterprivateendpointtestAssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3VersionKey6C30661CRef": { + "Ref": "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3VersionKey6C948E78" + }, "referencetoawscdkeksclusterprivateendpointtestVpcFCD064BFRef": { "Ref": "Vpc8378EB38" }, @@ -1275,17 +1287,41 @@ "Type": "String", "Description": "Artifact hash for asset \"daeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1\"" }, - "AssetParametersd01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34fS3Bucket81EA5F11": { + "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3Bucket008DBB35": { + "Type": "String", + "Description": "S3 bucket for asset \"bafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757\"" + }, + "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3VersionKey97C3E1A0": { + "Type": "String", + "Description": "S3 key for asset version \"bafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757\"" + }, + "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757ArtifactHashF584A7D8": { + "Type": "String", + "Description": "Artifact hash for asset \"bafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757\"" + }, + "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3Bucket6DACDE73": { + "Type": "String", + "Description": "S3 bucket for asset \"efd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1\"" + }, + "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3VersionKey015AEA61": { + "Type": "String", + "Description": "S3 key for asset version \"efd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1\"" + }, + "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1ArtifactHashC9FD06BA": { + "Type": "String", + "Description": "Artifact hash for asset \"efd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1\"" + }, + "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3Bucket7EE7EA15": { "Type": "String", - "Description": "S3 bucket for asset \"d01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34f\"" + "Description": "S3 bucket for asset \"b61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449f\"" }, - "AssetParametersd01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34fS3VersionKey32DED07C": { + "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3VersionKey6C948E78": { "Type": "String", - "Description": "S3 key for asset version \"d01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34f\"" + "Description": "S3 key for asset version \"b61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449f\"" }, - "AssetParametersd01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34fArtifactHashE68669BA": { + "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fArtifactHash7E705796": { "Type": "String", - "Description": "Artifact hash for asset \"d01b2d8959358117de0017e6f18135905e5680cfc8a83e406229c02671c2b34f\"" + "Description": "Artifact hash for asset \"b61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449f\"" }, "AssetParameters84ba29b05aaf6a233dbb97b37e48eb1300f9d014f270252e29a8b2c22d6a08beS3Bucket9E737267": { "Type": "String", @@ -1299,17 +1335,17 @@ "Type": "String", "Description": "Artifact hash for asset \"84ba29b05aaf6a233dbb97b37e48eb1300f9d014f270252e29a8b2c22d6a08be\"" }, - "AssetParameters82a02b024ddccd7e1020d7fb799652ba63ec9fc1b0605b3011233acd374b1601S3Bucket69FEE662": { + "AssetParameters2e2ec0fae5975d4ee5f3580e522c46615c1bd344e0302bc5d2df7501b7bb1ad0S3Bucket8FBFE327": { "Type": "String", - "Description": "S3 bucket for asset \"82a02b024ddccd7e1020d7fb799652ba63ec9fc1b0605b3011233acd374b1601\"" + "Description": "S3 bucket for asset \"2e2ec0fae5975d4ee5f3580e522c46615c1bd344e0302bc5d2df7501b7bb1ad0\"" }, - "AssetParameters82a02b024ddccd7e1020d7fb799652ba63ec9fc1b0605b3011233acd374b1601S3VersionKeyF62FBF50": { + "AssetParameters2e2ec0fae5975d4ee5f3580e522c46615c1bd344e0302bc5d2df7501b7bb1ad0S3VersionKeyF5A05918": { "Type": "String", - "Description": "S3 key for asset version \"82a02b024ddccd7e1020d7fb799652ba63ec9fc1b0605b3011233acd374b1601\"" + "Description": "S3 key for asset version \"2e2ec0fae5975d4ee5f3580e522c46615c1bd344e0302bc5d2df7501b7bb1ad0\"" }, - "AssetParameters82a02b024ddccd7e1020d7fb799652ba63ec9fc1b0605b3011233acd374b1601ArtifactHash2BC15E4C": { + "AssetParameters2e2ec0fae5975d4ee5f3580e522c46615c1bd344e0302bc5d2df7501b7bb1ad0ArtifactHashDFBC9DE7": { "Type": "String", - "Description": "Artifact hash for asset \"82a02b024ddccd7e1020d7fb799652ba63ec9fc1b0605b3011233acd374b1601\"" + "Description": "Artifact hash for asset \"2e2ec0fae5975d4ee5f3580e522c46615c1bd344e0302bc5d2df7501b7bb1ad0\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json index 23013f70f2925..d3cecf4417e1b 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json @@ -3977,7 +3977,7 @@ }, "/", { - "Ref": "AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dS3Bucket133A4850" + "Ref": "AssetParameters5b4a9f125b1d010c96760d55e0fc56362a73e6ca6da3af20a4d13ea27e369853S3Bucket3EB15EF2" }, "/", { @@ -3987,7 +3987,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dS3VersionKeyC4C77F70" + "Ref": "AssetParameters5b4a9f125b1d010c96760d55e0fc56362a73e6ca6da3af20a4d13ea27e369853S3VersionKeyD6A244FC" } ] } @@ -4000,7 +4000,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dS3VersionKeyC4C77F70" + "Ref": "AssetParameters5b4a9f125b1d010c96760d55e0fc56362a73e6ca6da3af20a4d13ea27e369853S3VersionKeyD6A244FC" } ] } @@ -4043,6 +4043,18 @@ "ClusterSecurityGroupId" ] }, + "referencetoawscdkeksclustertestAssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3Bucket69155862Ref": { + "Ref": "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3Bucket6DACDE73" + }, + "referencetoawscdkeksclustertestAssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3VersionKey0A6CC98ARef": { + "Ref": "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3VersionKey015AEA61" + }, + "referencetoawscdkeksclustertestAssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3BucketDD492793Ref": { + "Ref": "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3Bucket7EE7EA15" + }, + "referencetoawscdkeksclustertestAssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3VersionKeyD869415CRef": { + "Ref": "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3VersionKey6C948E78" + }, "referencetoawscdkeksclustertestVpc9A302ADDRef": { "Ref": "Vpc8378EB38" }, @@ -4725,6 +4737,30 @@ "Type": "String", "Description": "Artifact hash for asset \"bafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757\"" }, + "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3Bucket6DACDE73": { + "Type": "String", + "Description": "S3 bucket for asset \"efd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1\"" + }, + "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3VersionKey015AEA61": { + "Type": "String", + "Description": "S3 key for asset version \"efd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1\"" + }, + "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1ArtifactHashC9FD06BA": { + "Type": "String", + "Description": "Artifact hash for asset \"efd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1\"" + }, + "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3Bucket7EE7EA15": { + "Type": "String", + "Description": "S3 bucket for asset \"b61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449f\"" + }, + "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3VersionKey6C948E78": { + "Type": "String", + "Description": "S3 key for asset version \"b61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449f\"" + }, + "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fArtifactHash7E705796": { + "Type": "String", + "Description": "Artifact hash for asset \"b61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449f\"" + }, "AssetParametersb075459e6bf309093fbd4b9a9e576a5f172b91c14d84eedb0f069566f6abb0deS3Bucket14156880": { "Type": "String", "Description": "S3 bucket for asset \"b075459e6bf309093fbd4b9a9e576a5f172b91c14d84eedb0f069566f6abb0de\"" @@ -4773,17 +4809,17 @@ "Type": "String", "Description": "Artifact hash for asset \"a69aadbed84d554dd9f2eb7987ffe5d8f76b53a86f1909059df07050e57bef0c\"" }, - "AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dS3Bucket133A4850": { + "AssetParameters5b4a9f125b1d010c96760d55e0fc56362a73e6ca6da3af20a4d13ea27e369853S3Bucket3EB15EF2": { "Type": "String", - "Description": "S3 bucket for asset \"c73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09d\"" + "Description": "S3 bucket for asset \"5b4a9f125b1d010c96760d55e0fc56362a73e6ca6da3af20a4d13ea27e369853\"" }, - "AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dS3VersionKeyC4C77F70": { + "AssetParameters5b4a9f125b1d010c96760d55e0fc56362a73e6ca6da3af20a4d13ea27e369853S3VersionKeyD6A244FC": { "Type": "String", - "Description": "S3 key for asset version \"c73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09d\"" + "Description": "S3 key for asset version \"5b4a9f125b1d010c96760d55e0fc56362a73e6ca6da3af20a4d13ea27e369853\"" }, - "AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dArtifactHash7484ACD9": { + "AssetParameters5b4a9f125b1d010c96760d55e0fc56362a73e6ca6da3af20a4d13ea27e369853ArtifactHashD763BE57": { "Type": "String", - "Description": "Artifact hash for asset \"c73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09d\"" + "Description": "Artifact hash for asset \"5b4a9f125b1d010c96760d55e0fc56362a73e6ca6da3af20a4d13ea27e369853\"" }, "SsmParameterValueawsserviceeksoptimizedami118amazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { "Type": "AWS::SSM::Parameter::Value", diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-oidc-provider.expected.json b/packages/@aws-cdk/aws-eks/test/integ.eks-oidc-provider.expected.json index 615f6f5d97d00..b6a2cad449f9c 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-oidc-provider.expected.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-oidc-provider.expected.json @@ -9,12 +9,12 @@ "Arn" ] }, - "ThumbprintList": [ - "9e99a48a9960b14926bb7f3b02e22da2b0ab7280" - ], "ClientIDList": [ "sts.amazonaws.com" ], + "ThumbprintList": [ + "9e99a48a9960b14926bb7f3b02e22da2b0ab7280" + ], "Url": { "Fn::Join": [ "", @@ -145,4 +145,4 @@ "Description": "Artifact hash for asset \"b075459e6bf309093fbd4b9a9e576a5f172b91c14d84eedb0f069566f6abb0de\"" } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-eks/test/integ.fargate-cluster.expected.json b/packages/@aws-cdk/aws-eks/test/integ.fargate-cluster.expected.json index f5d7700c1a775..5d6efed26b63f 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.fargate-cluster.expected.json +++ b/packages/@aws-cdk/aws-eks/test/integ.fargate-cluster.expected.json @@ -1206,7 +1206,7 @@ }, "/", { - "Ref": "AssetParameters8fce5bde577fa3ab216c79574e335882996439da94b6d9183329e4fc4bff4eafS3Bucket36A38A03" + "Ref": "AssetParameters7449e3c4cf21a811d1d6612d2f1a806025f018320ebc8c1d8037eb34f0d0e98dS3BucketF39EF776" }, "/", { @@ -1216,7 +1216,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters8fce5bde577fa3ab216c79574e335882996439da94b6d9183329e4fc4bff4eafS3VersionKey5B11B043" + "Ref": "AssetParameters7449e3c4cf21a811d1d6612d2f1a806025f018320ebc8c1d8037eb34f0d0e98dS3VersionKeyE6E734A4" } ] } @@ -1229,7 +1229,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters8fce5bde577fa3ab216c79574e335882996439da94b6d9183329e4fc4bff4eafS3VersionKey5B11B043" + "Ref": "AssetParameters7449e3c4cf21a811d1d6612d2f1a806025f018320ebc8c1d8037eb34f0d0e98dS3VersionKeyE6E734A4" } ] } @@ -1251,11 +1251,11 @@ "Arn" ] }, - "referencetoawscdkeksfargateclustertestAssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3Bucket5FE0FE25Ref": { - "Ref": "AssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3BucketD473D2B6" + "referencetoawscdkeksfargateclustertestAssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3Bucket78A48DE4Ref": { + "Ref": "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3Bucket008DBB35" }, - "referencetoawscdkeksfargateclustertestAssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3VersionKeyEDF97686Ref": { - "Ref": "AssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3VersionKey8213FD47" + "referencetoawscdkeksfargateclustertestAssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3VersionKey69DB854ARef": { + "Ref": "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3VersionKey97C3E1A0" }, "referencetoawscdkeksfargateclustertestFargateClusterDefaultVpcPrivateSubnet1Subnet0278E6BCRef": { "Ref": "FargateClusterDefaultVpcPrivateSubnet1Subnet50EA43AA" @@ -1272,6 +1272,18 @@ "ClusterSecurityGroupId" ] }, + "referencetoawscdkeksfargateclustertestAssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3Bucket9D3BB190Ref": { + "Ref": "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3Bucket6DACDE73" + }, + "referencetoawscdkeksfargateclustertestAssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3VersionKey3BB3C6F5Ref": { + "Ref": "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3VersionKey015AEA61" + }, + "referencetoawscdkeksfargateclustertestAssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3Bucket99BFDD36Ref": { + "Ref": "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3Bucket7EE7EA15" + }, + "referencetoawscdkeksfargateclustertestAssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3VersionKeyEEC9E8C1Ref": { + "Ref": "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3VersionKey6C948E78" + }, "referencetoawscdkeksfargateclustertestFargateClusterDefaultVpcBD3C976FRef": { "Ref": "FargateClusterDefaultVpcE69D3A13" }, @@ -1352,17 +1364,41 @@ "Type": "String", "Description": "Artifact hash for asset \"daeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1\"" }, - "AssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3BucketD473D2B6": { + "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3Bucket008DBB35": { + "Type": "String", + "Description": "S3 bucket for asset \"bafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757\"" + }, + "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3VersionKey97C3E1A0": { + "Type": "String", + "Description": "S3 key for asset version \"bafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757\"" + }, + "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757ArtifactHashF584A7D8": { + "Type": "String", + "Description": "Artifact hash for asset \"bafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757\"" + }, + "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3Bucket6DACDE73": { + "Type": "String", + "Description": "S3 bucket for asset \"efd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1\"" + }, + "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1S3VersionKey015AEA61": { + "Type": "String", + "Description": "S3 key for asset version \"efd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1\"" + }, + "AssetParametersefd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1ArtifactHashC9FD06BA": { + "Type": "String", + "Description": "Artifact hash for asset \"efd72738f046105c96299fb31b3da40320e71ee9cf74bc37720042898403e2a1\"" + }, + "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3Bucket7EE7EA15": { "Type": "String", - "Description": "S3 bucket for asset \"e4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6c\"" + "Description": "S3 bucket for asset \"b61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449f\"" }, - "AssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3VersionKey8213FD47": { + "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fS3VersionKey6C948E78": { "Type": "String", - "Description": "S3 key for asset version \"e4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6c\"" + "Description": "S3 key for asset version \"b61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449f\"" }, - "AssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cArtifactHashDEE5AB5C": { + "AssetParametersb61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449fArtifactHash7E705796": { "Type": "String", - "Description": "Artifact hash for asset \"e4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6c\"" + "Description": "Artifact hash for asset \"b61858bbf1a0be803552e3efa9647befd728156696dff1b413b7b2fd4da1449f\"" }, "AssetParametersae946640aaf0743990584e4a1cf45ddebbaddcaf60611f572e80100a02162f48S3BucketDA5FB24D": { "Type": "String", @@ -1376,17 +1412,17 @@ "Type": "String", "Description": "Artifact hash for asset \"ae946640aaf0743990584e4a1cf45ddebbaddcaf60611f572e80100a02162f48\"" }, - "AssetParameters8fce5bde577fa3ab216c79574e335882996439da94b6d9183329e4fc4bff4eafS3Bucket36A38A03": { + "AssetParameters7449e3c4cf21a811d1d6612d2f1a806025f018320ebc8c1d8037eb34f0d0e98dS3BucketF39EF776": { "Type": "String", - "Description": "S3 bucket for asset \"8fce5bde577fa3ab216c79574e335882996439da94b6d9183329e4fc4bff4eaf\"" + "Description": "S3 bucket for asset \"7449e3c4cf21a811d1d6612d2f1a806025f018320ebc8c1d8037eb34f0d0e98d\"" }, - "AssetParameters8fce5bde577fa3ab216c79574e335882996439da94b6d9183329e4fc4bff4eafS3VersionKey5B11B043": { + "AssetParameters7449e3c4cf21a811d1d6612d2f1a806025f018320ebc8c1d8037eb34f0d0e98dS3VersionKeyE6E734A4": { "Type": "String", - "Description": "S3 key for asset version \"8fce5bde577fa3ab216c79574e335882996439da94b6d9183329e4fc4bff4eaf\"" + "Description": "S3 key for asset version \"7449e3c4cf21a811d1d6612d2f1a806025f018320ebc8c1d8037eb34f0d0e98d\"" }, - "AssetParameters8fce5bde577fa3ab216c79574e335882996439da94b6d9183329e4fc4bff4eafArtifactHashE40CA470": { + "AssetParameters7449e3c4cf21a811d1d6612d2f1a806025f018320ebc8c1d8037eb34f0d0e98dArtifactHash93FFAA4A": { "Type": "String", - "Description": "Artifact hash for asset \"8fce5bde577fa3ab216c79574e335882996439da94b6d9183329e4fc4bff4eaf\"" + "Description": "Artifact hash for asset \"7449e3c4cf21a811d1d6612d2f1a806025f018320ebc8c1d8037eb34f0d0e98d\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-eks/test/test.cluster.ts b/packages/@aws-cdk/aws-eks/test/test.cluster.ts index 0c8f1dac31f10..fa63e9edc5112 100644 --- a/packages/@aws-cdk/aws-eks/test/test.cluster.ts +++ b/packages/@aws-cdk/aws-eks/test/test.cluster.ts @@ -12,7 +12,6 @@ import * as constructs from 'constructs'; import { Test } from 'nodeunit'; import * as YAML from 'yaml'; import * as eks from '../lib'; -import * as kubectl from '../lib/kubectl-provider'; import { BottleRocketImage } from '../lib/private/bottlerocket'; import { testFixture, testFixtureNoVpc } from './util'; @@ -537,46 +536,6 @@ export = { test.done(); }, - 'create custom cluster correctly in any aws region'(test: Test) { - // GIVEN - const app = new cdk.App(); - const stack = new cdk.Stack(app, 'stack', { env: { region: 'us-east-1' } }); - - // WHEN - const vpc = new ec2.Vpc(stack, 'VPC'); - new eks.Cluster(stack, 'Cluster', { vpc, defaultCapacity: 0, version: CLUSTER_VERSION, prune: false }); - kubectl.getOrCreateKubectlLayer(stack); - - // THEN - expect(stack).to(haveResource('Custom::AWSCDK-EKS-Cluster')); - expect(stack).to(haveResourceLike('AWS::Serverless::Application', { - Location: { - ApplicationId: 'arn:aws:serverlessrepo:us-east-1:903779448426:applications/lambda-layer-kubectl', - }, - })); - test.done(); - }, - - 'create custom cluster correctly in any aws region in china'(test: Test) { - // GIVEN - const app = new cdk.App(); - const stack = new cdk.Stack(app, 'stack', { env: { region: 'cn-north-1' } }); - - // WHEN - const vpc = new ec2.Vpc(stack, 'VPC'); - new eks.Cluster(stack, 'Cluster', { vpc, defaultCapacity: 0, version: CLUSTER_VERSION, prune: false }); - kubectl.getOrCreateKubectlLayer(stack); - - // THEN - expect(stack).to(haveResource('Custom::AWSCDK-EKS-Cluster')); - expect(stack).to(haveResourceLike('AWS::Serverless::Application', { - Location: { - ApplicationId: 'arn:aws-cn:serverlessrepo:cn-north-1:487369736442:applications/lambda-layer-kubectl', - }, - })); - test.done(); - }, - 'if "vpc" is not specified, vpc with default configuration will be created'(test: Test) { // GIVEN const { stack } = testFixtureNoVpc(); @@ -2720,38 +2679,6 @@ export = { test.done(); }, - 'SAR-based kubectl layer can be customized'(test: Test) { - // GIVEN - const { stack } = testFixture(); - - // WHEN - const layer = new eks.KubectlLayer(stack, 'Kubectl', { - applicationId: 'custom:app:id', - version: '2.3.4', - }); - - new eks.Cluster(stack, 'Cluster1', { - version: CLUSTER_VERSION, - prune: false, - kubectlLayer: layer, - }); - - // THEN - const providerStack = stack.node.tryFindChild('@aws-cdk/aws-eks.KubectlProvider') as cdk.NestedStack; - expect(providerStack).to(haveResource('AWS::Lambda::Function', { - Layers: [{ Ref: 'referencetoStackKubectl7F29063EOutputsLayerVersionArn' }], - })); - - expect(stack).to(haveResource('AWS::Serverless::Application', { - Location: { - ApplicationId: 'custom:app:id', - SemanticVersion: '2.3.4', - }, - })); - - test.done(); - }, - 'create a cluster using custom resource with secrets encryption using KMS CMK'(test: Test) { // GIVEN const { stack, vpc } = testFixture(); diff --git a/packages/@aws-cdk/aws-s3-deployment/lambda/build.sh b/packages/@aws-cdk/aws-s3-deployment/lambda/build.sh deleted file mode 100755 index cc9df52d130df..0000000000000 --- a/packages/@aws-cdk/aws-s3-deployment/lambda/build.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -#------------------------------------------------------------------------------- -# builds a python-lambda deployment package -# -set -euo pipefail -set -x - -# make sure we run from the script directory -cd $(dirname $0) - -# clean up old bundle -bundle_out="$PWD/bundle.zip" -rm -f ${bundle_out} - -# prepare staging -staging="$(mktemp -d)" -piptemp="$(mktemp -d)" -trap "rm -rf ${staging} ${piptemp}" EXIT - -echo "staging lambda bundle at ${staging}..." - -# copy sources -rsync -av src/ "${staging}" - -cd ${staging} - -# install python requirements -# Must use --prefix to because --target cannot be used on -# platforms that have a default --prefix set. -pip3 install --ignore-installed --prefix ${piptemp} --no-user -r ${staging}/requirements.txt -mv ${piptemp}/lib/python*/*-packages/* . -[ -d ${piptemp}/lib64 ] && mv ${piptemp}/lib64/python*/*-packages/* . -rm -fr ./awscli/examples - - -# create archive -zip -qr ${bundle_out} . - -echo "bundle: ${bundle_out}" diff --git a/packages/@aws-cdk/aws-s3-deployment/lambda/src/aws b/packages/@aws-cdk/aws-s3-deployment/lambda/src/aws deleted file mode 100644 index 15ee2d7093f85..0000000000000 --- a/packages/@aws-cdk/aws-s3-deployment/lambda/src/aws +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2012 Amazon.com, Inc. or its affiliates. All Rights Reserved. - -# Licensed under the Apache License, Version 2.0 (the "License"). You -# may not use this file except in compliance with the License. A copy of -# the License is located at - -# http://aws.amazon.com/apache2.0/ - -# or in the "license" file accompanying this file. This file is -# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF -# ANY KIND, either express or implied. See the License for the specific -# language governing permissions and limitations under the License. -import sys -import os - -if os.environ.get('LC_CTYPE', '') == 'UTF-8': - os.environ['LC_CTYPE'] = 'en_US.UTF-8' -import awscli.clidriver - - -def main(): - return awscli.clidriver.main() - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/packages/@aws-cdk/aws-s3-deployment/lambda/src/requirements.txt b/packages/@aws-cdk/aws-s3-deployment/lambda/src/requirements.txt deleted file mode 100644 index 9522336d851c8..0000000000000 --- a/packages/@aws-cdk/aws-s3-deployment/lambda/src/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -awscli==1.16.218 -boto3==1.9.208 diff --git a/packages/@aws-cdk/aws-s3-deployment/lambda/src/setup.cfg b/packages/@aws-cdk/aws-s3-deployment/lambda/src/setup.cfg deleted file mode 100644 index eee4ab11a70e6..0000000000000 --- a/packages/@aws-cdk/aws-s3-deployment/lambda/src/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[install] -prefix= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-s3-deployment/lambda/test.sh b/packages/@aws-cdk/aws-s3-deployment/lambda/test.sh deleted file mode 100755 index e87f8dfc2492b..0000000000000 --- a/packages/@aws-cdk/aws-s3-deployment/lambda/test.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -#--------------------------------------------------------------------------------------------------- -# exeuctes unit tests -# -# prepares a staging directory with the requirements -set -e -set -x -scriptdir=$(cd $(dirname $0) && pwd) - -# prepare staging directory -staging=$(mktemp -d) -mkdir -p ${staging} -cd ${staging} - -# copy src and overlay with test -cp -f ${scriptdir}/src/* $PWD -cp -f ${scriptdir}/test/* $PWD - -# install deps -pip3 install --no-user -r requirements.txt -t . - -# run our tests -exec python3 test.py $@ diff --git a/packages/@aws-cdk/aws-s3-deployment/lambda/test/aws b/packages/@aws-cdk/aws-s3-deployment/lambda/test/aws deleted file mode 100644 index 969bb982cd08c..0000000000000 --- a/packages/@aws-cdk/aws-s3-deployment/lambda/test/aws +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python -#=================================================================================================== -# mock for the "aws" cli -# -# the mock behaves as follows: -# - argvs are going to be written to "aws.out" (one command in each line) -# - if "aws s3 cp" is invoked, the destination will be populated with a test zip file. -# - for "cp" and "sync", "aws.out" argv[4] is replaced by "archive.zip" and "contents.zip" -# becuase the actual value is a full path of a temporary directory -# -import sys -import json -import os -import shutil - -scriptdir=os.path.dirname(os.path.realpath(__file__)) - -# if "cp" is called with a local destination, copy a test zip file to the destination or -if sys.argv[2] == "cp" and not sys.argv[4].startswith("s3://"): - shutil.copyfile(os.path.join(scriptdir, 'test.zip'), sys.argv[4]) - sys.argv[4] = "archive.zip" - -if sys.argv[2] == "sync": - sys.argv[4 if '--delete' in sys.argv else 3] = "contents.zip" - -with open("./aws.out", "a") as myfile: - myfile.write(json.dumps(sys.argv[1:]) + "\n") diff --git a/packages/@aws-cdk/aws-s3-deployment/lambda/test/test.py b/packages/@aws-cdk/aws-s3-deployment/lambda/test/test.py deleted file mode 100644 index df48d6cdf38ff..0000000000000 --- a/packages/@aws-cdk/aws-s3-deployment/lambda/test/test.py +++ /dev/null @@ -1,483 +0,0 @@ -# unit tests for the s3 bucket deployment lambda handler -import index -import os -import unittest -import json -import sys -import traceback -import logging -import botocore -from botocore.vendored import requests -from botocore.exceptions import ClientError -from unittest.mock import MagicMock -from unittest.mock import patch - - -class TestHandler(unittest.TestCase): - def setUp(self): - logger = logging.getLogger() - - # clean up old aws.out file (from previous runs) - try: os.remove("aws.out") - except OSError: pass - - def test_invalid_request(self): - resp = invoke_handler("Create", {}, expected_status="FAILED") - self.assertEqual(resp["Reason"], "missing request resource property 'SourceBucketNames'. props: {}") - - def test_create_update(self): - invoke_handler("Create", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "" - }) - - self.assertAwsCommands( - ["s3", "cp", "s3:///", "archive.zip"], - ["s3", "sync", "--delete", "contents.zip", "s3:///"] - ) - - def test_create_no_delete(self): - invoke_handler("Create", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "Prune": "false" - }) - - self.assertAwsCommands( - ["s3", "cp", "s3:///", "archive.zip"], - ["s3", "sync", "contents.zip", "s3:///"] - ) - - def test_update_no_delete(self): - invoke_handler("Update", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "Prune": "false" - }, old_resource_props={ - "DestinationBucketName": "", - }, physical_id="") - - self.assertAwsCommands( - ["s3", "cp", "s3:///", "archive.zip"], - ["s3", "sync", "contents.zip", "s3:///"] - ) - - def test_create_update_multiple_sources(self): - invoke_handler("Create", { - "SourceBucketNames": ["", ""], - "SourceObjectKeys": ["", ""], - "DestinationBucketName": "" - }) - - # Note: these are different files in real-life. For testing purposes, we hijack - # the command to output a static filename, archive.zip - self.assertAwsCommands( - ["s3", "cp", "s3:///", "archive.zip"], - ["s3", "cp", "s3:///", "archive.zip"], - ["s3", "sync", "--delete", "contents.zip", "s3:///"] - ) - - def test_create_with_backslash_prefix_same_as_no_prefix(self): - invoke_handler("Create", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "DestinationBucketKeyPrefix": "/" - }) - - self.assertAwsCommands( - ["s3", "cp", "s3:///", "archive.zip"], - ["s3", "sync", "--delete", "contents.zip", "s3:///"] - ) - - - def test_create_update_with_dest_key(self): - invoke_handler("Create", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "DestinationBucketKeyPrefix": "" - }) - - self.assertAwsCommands( - ["s3", "cp", "s3:///", "archive.zip"], - ["s3", "sync", "--delete", "contents.zip", "s3:///"] - ) - - def test_create_update_with_metadata(self): - invoke_handler("Create", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "DestinationBucketKeyPrefix": "", - "UserMetadata": { "best": "game" }, - "SystemMetadata": { "content-type": "text/html", "content-language": "en" } - }) - - self.assertAwsCommands( - ["s3", "cp", "s3:///", "archive.zip"], - ["s3", "sync", "--delete", "contents.zip", "s3:///", "--content-type", "text/html", "--content-language", "en", "--metadata", "{\"x-amz-meta-best\":\"game\"}", "--metadata-directive", "REPLACE"] - ) - - def test_delete_no_retain(self): - invoke_handler("Delete", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "RetainOnDelete": "false" - }, physical_id="") - - self.assertAwsCommands(["s3", "rm", "s3:///", "--recursive"]) - - def test_delete_with_dest_key(self): - invoke_handler("Delete", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "DestinationBucketKeyPrefix": "", - "RetainOnDelete": "false" - }, physical_id="") - - self.assertAwsCommands(["s3", "rm", "s3:///", "--recursive"]) - - def test_delete_with_retain_explicit(self): - invoke_handler("Delete", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "RetainOnDelete": "true" - }, physical_id="") - - # no aws commands (retain) - self.assertAwsCommands() - - # RetainOnDelete=true is the default - def test_delete_with_retain_implicit_default(self): - invoke_handler("Delete", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "" - }, physical_id="") - - # no aws commands (retain) - self.assertAwsCommands() - - def test_delete_with_retain_explicitly_false(self): - invoke_handler("Delete", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "RetainOnDelete": "false" - }, physical_id="") - - self.assertAwsCommands( - ["s3", "rm", "s3:///", "--recursive"] - ) - - # - # update - # - - def test_update_same_dest(self): - invoke_handler("Update", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - }, old_resource_props={ - "DestinationBucketName": "", - }, physical_id="") - - self.assertAwsCommands( - ["s3", "cp", "s3:///", "archive.zip"], - ["s3", "sync", "--delete", "contents.zip", "s3:///"] - ) - - def test_update_same_dest_cf_invalidate(self): - def mock_make_api_call(self, operation_name, kwarg): - if operation_name == 'CreateInvalidation': - assert kwarg['DistributionId'] == '' - assert kwarg['InvalidationBatch']['Paths']['Quantity'] == 1 - assert kwarg['InvalidationBatch']['Paths']['Items'][0] == '/*' - return {'Invalidation': {'Id': ''}} - if operation_name == 'GetInvalidation' and kwarg['Id'] == '': - return {'Invalidation': {'Id': '', 'Status': 'Completed'}} - raise ClientError({'Error': {'Code': '500', 'Message': 'Unsupported operation'}}, operation_name) - - with patch('botocore.client.BaseClient._make_api_call', new=mock_make_api_call): - invoke_handler("Update", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "DistributionId": "" - }, old_resource_props={ - "DestinationBucketName": "", - }, physical_id="") - - def test_update_same_dest_cf_invalidate_custom_prefix(self): - def mock_make_api_call(self, operation_name, kwarg): - if operation_name == 'CreateInvalidation': - assert kwarg['DistributionId'] == '' - assert kwarg['InvalidationBatch']['Paths']['Quantity'] == 1 - assert kwarg['InvalidationBatch']['Paths']['Items'][0] == '//*' - return {'Invalidation': {'Id': ''}} - if operation_name == 'GetInvalidation' and kwarg['Id'] == '': - return {'Invalidation': {'Id': '', 'Status': 'Completed'}} - raise ClientError({'Error': {'Code': '500', 'Message': 'Unsupported operation'}}, operation_name) - - with patch('botocore.client.BaseClient._make_api_call', new=mock_make_api_call): - invoke_handler("Update", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "DestinationBucketKeyPrefix": "", - "DistributionId": "" - }, old_resource_props={ - "DestinationBucketName": "", - }, physical_id="") - - def test_update_same_dest_cf_invalidate_custom_paths(self): - def mock_make_api_call(self, operation_name, kwarg): - if operation_name == 'CreateInvalidation': - assert kwarg['DistributionId'] == '' - assert kwarg['InvalidationBatch']['Paths']['Quantity'] == 2 - assert kwarg['InvalidationBatch']['Paths']['Items'][0] == '/path1/*' - assert kwarg['InvalidationBatch']['Paths']['Items'][1] == '/path2/*' - return {'Invalidation': {'Id': ''}} - if operation_name == 'GetInvalidation' and kwarg['Id'] == '': - return {'Invalidation': {'Id': '', 'Status': 'Completed'}} - raise ClientError({'Error': {'Code': '500', 'Message': 'Unsupported operation'}}, operation_name) - - with patch('botocore.client.BaseClient._make_api_call', new=mock_make_api_call): - invoke_handler("Update", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "DistributionId": "", - "DistributionPaths": ["/path1/*", "/path2/*"] - }, old_resource_props={ - "DestinationBucketName": "", - }, physical_id="") - - def test_update_new_dest_retain(self): - invoke_handler("Update", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - }, old_resource_props={ - "DestinationBucketName": "", - "RetainOnDelete": "true" - }, physical_id="") - - self.assertAwsCommands( - ["s3", "cp", "s3:///", "archive.zip"], - ["s3", "sync", "--delete", "contents.zip", "s3:///"] - ) - - def test_update_new_dest_no_retain(self): - invoke_handler("Update", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "RetainOnDelete": "false" - }, old_resource_props={ - "DestinationBucketName": "", - "DestinationBucketKeyPrefix": "", - "RetainOnDelete": "false" - }, physical_id="") - - self.assertAwsCommands( - ["s3", "rm", "s3:///", "--recursive"], - ["s3", "cp", "s3:///", "archive.zip"], - ["s3", "sync", "--delete", "contents.zip", "s3:///"] - ) - - def test_update_new_dest_retain_implicit(self): - invoke_handler("Update", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - }, old_resource_props={ - "DestinationBucketName": "", - "DestinationBucketKeyPrefix": "" - }, physical_id="") - - self.assertAwsCommands( - ["s3", "cp", "s3:///", "archive.zip"], - ["s3", "sync", "--delete", "contents.zip", "s3:///"] - ) - - def test_update_new_dest_prefix_no_retain(self): - invoke_handler("Update", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "DestinationBucketKeyPrefix": "", - "RetainOnDelete": "false" - }, old_resource_props={ - "DestinationBucketName": "", - "RetainOnDelete": "false" - }, physical_id="") - - self.assertAwsCommands( - ["s3", "rm", "s3:///", "--recursive"], - ["s3", "cp", "s3:///", "archive.zip"], - ["s3", "sync", "--delete", "contents.zip", "s3:///"] - ) - - def test_update_new_dest_prefix_retain_implicit(self): - invoke_handler("Update", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "DestinationBucketKeyPrefix": "" - }, old_resource_props={ - "DestinationBucketName": "", - }, physical_id="") - - self.assertAwsCommands( - ["s3", "cp", "s3:///", "archive.zip"], - ["s3", "sync", "--delete", "contents.zip", "s3:///"] - ) - - # - # physical id - # - - def test_physical_id_allocated_on_create_and_reused_afterwards(self): - create_resp = invoke_handler("Create", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - }) - - phid = create_resp['PhysicalResourceId'] - self.assertTrue(phid.startswith('aws.cdk.s3deployment')) - - # now issue an update and pass in the physical id. expect the same - # one to be returned back - update_resp = invoke_handler("Update", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - }, old_resource_props={ - "DestinationBucketName": "", - }, physical_id=phid) - self.assertEqual(update_resp['PhysicalResourceId'], phid) - - # now issue a delete, and make sure this also applies - delete_resp = invoke_handler("Delete", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - "RetainOnDelete": "false" - }, physical_id=phid) - self.assertEqual(delete_resp['PhysicalResourceId'], phid) - - def test_fails_when_physical_id_not_present_in_update(self): - update_resp = invoke_handler("Update", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - }, old_resource_props={ - "DestinationBucketName": "", - }, expected_status="FAILED") - - self.assertEqual(update_resp['Reason'], "invalid request: request type is 'Update' but 'PhysicalResourceId' is not defined") - - def test_fails_when_physical_id_not_present_in_delete(self): - update_resp = invoke_handler("Delete", { - "SourceBucketNames": [""], - "SourceObjectKeys": [""], - "DestinationBucketName": "", - }, old_resource_props={ - "DestinationBucketName": "", - }, expected_status="FAILED") - - self.assertEqual(update_resp['Reason'], "invalid request: request type is 'Delete' but 'PhysicalResourceId' is not defined") - - - # asserts that a given list of "aws xxx" commands have been invoked (in order) - def assertAwsCommands(self, *expected): - actual = read_aws_out() - self.assertEqual(actual, list(expected)) - -# ================================================================================================== -# helpers - -# -# reads "aws.out" and returns a list of "aws" commands (as strings) -def read_aws_out(): - if not os.path.exists("aws.out"): - return [] - - with open("aws.out") as f: - return [json.loads(l) for l in f.read().splitlines()] - -# -# invokes the handler under test -# requestType: CloudFormation request type ("Create", "Update", "Delete") -# resourceProps: map to pass to "ResourceProperties" -# expected_status: "SUCCESS" or "FAILED" -def invoke_handler(requestType, resourceProps, old_resource_props=None, physical_id=None, expected_status='SUCCESS'): - response_url = '' - - event={ - 'ResponseURL': response_url, - 'StackId': '', - 'RequestId': '', - 'LogicalResourceId': '', - 'RequestType': requestType, - 'ResourceProperties': resourceProps - } - - if old_resource_props: - event['OldResourceProperties'] = old_resource_props - - if physical_id: - event['PhysicalResourceId'] = physical_id - - class ContextMock: log_stream_name = 'log_stream' - class ResponseMock: reason = 'OK' - - context = ContextMock() - requests.put = MagicMock(return_value=ResponseMock()) - - #-------------------- - # invoke the handler - #-------------------- - index.handler(event, context) - - requests.put.assert_called_once() - (pos_args, kw_args) = requests.put.call_args - - actual_url = pos_args[0] - actual_data = kw_args['data'] - - if actual_url != response_url: - raise Exception("Invalid url used for sending CFN response. expected=%s actual=%s" % (response_url, actual_url)) - - resp = json.loads(actual_data) - - def assert_field(name, expect=None): - value=resp.get(name) - - if not expect: - if not resp.get(name): - raise Exception("Missing '%s' field from response: %s" % (name, resp)) - elif expect and value != expect: - raise Exception("Expecting response field '%s' to be '%s' but got '%s'.\n%s" % (name, expect, value, json.dumps(resp, indent=2))) - - assert_field('Status', expected_status) - assert_field('Reason') - assert_field('PhysicalResourceId') - assert_field('StackId', '') - assert_field('RequestId', '') - assert_field('LogicalResourceId', '') - - return resp - -if __name__ == '__main__': - unittest.main() diff --git a/packages/@aws-cdk/aws-s3-deployment/lambda/test/test.zip b/packages/@aws-cdk/aws-s3-deployment/lambda/test/test.zip deleted file mode 100644 index 56829f65a2681a83665ce8539b84c0dd081e97bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179 zcmWIWW@h1H00AzGVBcl-QSQ7zHVAVt$S{d2?{eZMTh{FH?)6OLz diff --git a/packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts b/packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts index 9cb91bffc4f16..352f350b91600 100644 --- a/packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts +++ b/packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts @@ -1,5 +1,3 @@ -import * as crypto from 'crypto'; -import * as fs from 'fs'; import * as path from 'path'; import * as cloudfront from '@aws-cdk/aws-cloudfront'; import * as ec2 from '@aws-cdk/aws-ec2'; @@ -7,12 +5,10 @@ import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; import * as s3 from '@aws-cdk/aws-s3'; import * as cdk from '@aws-cdk/core'; +import { AwsCliLayer } from '@aws-cdk/lambda-layer-awscli'; import { Construct } from 'constructs'; import { ISource, SourceConfig } from './source'; -const handlerCodeBundle = path.join(__dirname, '..', 'lambda', 'bundle.zip'); -const handlerSourceDirectory = path.join(__dirname, '..', 'lambda', 'src'); - export interface BucketDeploymentProps { /** * The sources from which to deploy the contents of this bucket. @@ -187,11 +183,10 @@ export class BucketDeployment extends cdk.Construct { throw new Error('Distribution must be specified if distribution paths are specified'); } - const assetHash = calcSourceHash(handlerSourceDirectory); - const handler = new lambda.SingletonFunction(this, 'CustomResourceHandler', { uuid: this.renderSingletonUuid(props.memoryLimit), - code: lambda.Code.fromAsset(handlerCodeBundle, { assetHash }), + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda')), + layers: [new AwsCliLayer(this, 'AwsCliLayer')], runtime: lambda.Runtime.PYTHON_3_6, handler: 'index.handler', lambdaPurpose: 'Custom::CDKBucketDeployment', @@ -253,25 +248,6 @@ export class BucketDeployment extends cdk.Construct { } } -/** - * We need a custom source hash calculation since the bundle.zip file - * contains python dependencies installed during build and results in a - * non-deterministic behavior. - * - * So we just take the `src/` directory of our custom resoruce code. - */ -function calcSourceHash(srcDir: string): string { - const sha = crypto.createHash('sha256'); - for (const file of fs.readdirSync(srcDir)) { - const data = fs.readFileSync(path.join(srcDir, file)); - sha.update(``); - sha.update(data); - sha.update(''); - } - - return sha.digest('hex'); -} - /** * Metadata */ diff --git a/packages/@aws-cdk/aws-s3-deployment/lambda/src/index.py b/packages/@aws-cdk/aws-s3-deployment/lib/lambda/index.py similarity index 98% rename from packages/@aws-cdk/aws-s3-deployment/lambda/src/index.py rename to packages/@aws-cdk/aws-s3-deployment/lib/lambda/index.py index 300e8d0772bf0..34a2da1681f4d 100644 --- a/packages/@aws-cdk/aws-s3-deployment/lambda/src/index.py +++ b/packages/@aws-cdk/aws-s3-deployment/lib/lambda/index.py @@ -182,9 +182,9 @@ def create_metadata_args(raw_user_metadata, raw_system_metadata): #--------------------------------------------------------------------------------------------------- # executes an "aws" cli command def aws_command(*args): - aws=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'aws') + aws="/opt/awscli/aws" # from AwsCliLayer logger.info("| aws %s" % ' '.join(args)) - subprocess.check_call(["python3", aws] + list(args)) + subprocess.check_call([aws] + list(args)) #--------------------------------------------------------------------------------------------------- # sends a response to cloudformation diff --git a/packages/@aws-cdk/aws-s3-deployment/package.json b/packages/@aws-cdk/aws-s3-deployment/package.json index df5c84cf3283b..fc802538bb33f 100644 --- a/packages/@aws-cdk/aws-s3-deployment/package.json +++ b/packages/@aws-cdk/aws-s3-deployment/package.json @@ -49,13 +49,9 @@ "build+test+package": "npm run build+test && npm run package", "build+test": "npm run build && npm test", "compat": "cdk-compat", - "gen": "/bin/bash lambda/build.sh", "rosetta:extract": "yarn --silent jsii-rosetta extract" }, "cdk-build": { - "test": [ - "/bin/bash lambda/test.sh" - ], "jest": true, "env": { "AWSLINT_BASE_CONSTRUCT": true @@ -73,8 +69,7 @@ "test/**", "examples/**", "lib/*.generated.js", - "build-tools/**", - "lambda/**" + "build-tools/**" ] }, "author": { @@ -98,6 +93,7 @@ "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/aws-s3-assets": "0.0.0", + "@aws-cdk/lambda-layer-awscli": "0.0.0", "@aws-cdk/core": "0.0.0", "constructs": "^3.2.0" }, @@ -109,6 +105,7 @@ "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/aws-s3-assets": "0.0.0", + "@aws-cdk/lambda-layer-awscli": "0.0.0", "@aws-cdk/core": "0.0.0", "constructs": "^3.2.0" }, diff --git a/packages/@aws-cdk/aws-s3-deployment/test/integ.bucket-deployment-cloudfront.expected.json b/packages/@aws-cdk/aws-s3-deployment/test/integ.bucket-deployment-cloudfront.expected.json index 3f025bb6bf6a9..aa8c7fddd60c7 100644 --- a/packages/@aws-cdk/aws-s3-deployment/test/integ.bucket-deployment-cloudfront.expected.json +++ b/packages/@aws-cdk/aws-s3-deployment/test/integ.bucket-deployment-cloudfront.expected.json @@ -53,6 +53,50 @@ } } }, + "DeployWithInvalidationAwsCliLayerDEDD5787": { + "Type": "AWS::Lambda::LayerVersion", + "Properties": { + "Content": { + "S3Bucket": { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3BucketAEADE8C7" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" + } + ] + } + ] + } + ] + ] + } + }, + "Description": "/opt/awscli/aws" + } + }, "DeployWithInvalidationCustomResourceE3FF7455": { "Type": "Custom::CDKBucketDeployment", "Properties": { @@ -251,7 +295,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3Bucket77147E20" + "Ref": "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3Bucket28CE5152" }, "S3Key": { "Fn::Join": [ @@ -264,7 +308,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3VersionKey4253216F" + "Ref": "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3VersionKeyAF6E05ED" } ] } @@ -277,7 +321,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3VersionKey4253216F" + "Ref": "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3VersionKeyAF6E05ED" } ] } @@ -295,6 +339,11 @@ ] }, "Runtime": "python3.6", + "Layers": [ + { + "Ref": "DeployWithInvalidationAwsCliLayerDEDD5787" + } + ], "Timeout": 900 }, "DependsOn": [ @@ -304,17 +353,29 @@ } }, "Parameters": { - "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3Bucket77147E20": { + "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3BucketAEADE8C7": { + "Type": "String", + "Description": "S3 bucket for asset \"e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68\"" + }, + "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F": { + "Type": "String", + "Description": "S3 key for asset version \"e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68\"" + }, + "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68ArtifactHashD9A515C3": { + "Type": "String", + "Description": "Artifact hash for asset \"e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68\"" + }, + "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3Bucket28CE5152": { "Type": "String", - "Description": "S3 bucket for asset \"c9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176\"" + "Description": "S3 bucket for asset \"3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7\"" }, - "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3VersionKey4253216F": { + "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3VersionKeyAF6E05ED": { "Type": "String", - "Description": "S3 key for asset version \"c9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176\"" + "Description": "S3 key for asset version \"3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7\"" }, - "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176ArtifactHash4E343C6C": { + "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7ArtifactHash8926088E": { "Type": "String", - "Description": "Artifact hash for asset \"c9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176\"" + "Description": "Artifact hash for asset \"3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7\"" }, "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A": { "Type": "String", diff --git a/packages/@aws-cdk/aws-s3-deployment/test/integ.bucket-deployment.expected.json b/packages/@aws-cdk/aws-s3-deployment/test/integ.bucket-deployment.expected.json index ff9a3162fbae8..267c6eaa23476 100644 --- a/packages/@aws-cdk/aws-s3-deployment/test/integ.bucket-deployment.expected.json +++ b/packages/@aws-cdk/aws-s3-deployment/test/integ.bucket-deployment.expected.json @@ -10,6 +10,50 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, + "DeployMeAwsCliLayer5F9219E9": { + "Type": "AWS::Lambda::LayerVersion", + "Properties": { + "Content": { + "S3Bucket": { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3BucketAEADE8C7" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" + } + ] + } + ] + } + ] + ] + } + }, + "Description": "/opt/awscli/aws" + } + }, "DeployMeCustomResource4455EE35": { "Type": "Custom::CDKBucketDeployment", "Properties": { @@ -260,7 +304,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3Bucket77147E20" + "Ref": "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3Bucket28CE5152" }, "S3Key": { "Fn::Join": [ @@ -273,7 +317,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3VersionKey4253216F" + "Ref": "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3VersionKeyAF6E05ED" } ] } @@ -286,7 +330,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3VersionKey4253216F" + "Ref": "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3VersionKeyAF6E05ED" } ] } @@ -304,6 +348,11 @@ ] }, "Runtime": "python3.6", + "Layers": [ + { + "Ref": "DeployMeAwsCliLayer5F9219E9" + } + ], "Timeout": 900 }, "DependsOn": [ @@ -316,6 +365,50 @@ "UpdateReplacePolicy": "Retain", "DeletionPolicy": "Retain" }, + "DeployWithPrefixAwsCliLayerC9DDB597": { + "Type": "AWS::Lambda::LayerVersion", + "Properties": { + "Content": { + "S3Bucket": { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3BucketAEADE8C7" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" + } + ] + } + ] + } + ] + ] + } + }, + "Description": "/opt/awscli/aws" + } + }, "DeployWithPrefixCustomResource9CF7C694": { "Type": "Custom::CDKBucketDeployment", "Properties": { @@ -380,6 +473,50 @@ "UpdateReplacePolicy": "Retain", "DeletionPolicy": "Retain" }, + "DeployWithMetadataAwsCliLayer2C774B41": { + "Type": "AWS::Lambda::LayerVersion", + "Properties": { + "Content": { + "S3Bucket": { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3BucketAEADE8C7" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" + } + ] + } + ] + } + ] + ] + } + }, + "Description": "/opt/awscli/aws" + } + }, "DeployWithMetadataCustomResourceA73C95DC": { "Type": "Custom::CDKBucketDeployment", "Properties": { @@ -447,6 +584,50 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, + "DeployMeWithoutDeletingFilesOnDestinationAwsCliLayer4D54C41C": { + "Type": "AWS::Lambda::LayerVersion", + "Properties": { + "Content": { + "S3Bucket": { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3BucketAEADE8C7" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" + } + ] + } + ] + } + ] + ] + } + }, + "Description": "/opt/awscli/aws" + } + }, "DeployMeWithoutDeletingFilesOnDestinationCustomResourceA390B02B": { "Type": "Custom::CDKBucketDeployment", "Properties": { @@ -507,17 +688,29 @@ } }, "Parameters": { - "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3Bucket77147E20": { + "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3BucketAEADE8C7": { + "Type": "String", + "Description": "S3 bucket for asset \"e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68\"" + }, + "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F": { + "Type": "String", + "Description": "S3 key for asset version \"e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68\"" + }, + "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68ArtifactHashD9A515C3": { + "Type": "String", + "Description": "Artifact hash for asset \"e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68\"" + }, + "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3Bucket28CE5152": { "Type": "String", - "Description": "S3 bucket for asset \"c9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176\"" + "Description": "S3 bucket for asset \"3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7\"" }, - "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176S3VersionKey4253216F": { + "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7S3VersionKeyAF6E05ED": { "Type": "String", - "Description": "S3 key for asset version \"c9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176\"" + "Description": "S3 key for asset version \"3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7\"" }, - "AssetParametersc9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176ArtifactHash4E343C6C": { + "AssetParameters3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7ArtifactHash8926088E": { "Type": "String", - "Description": "Artifact hash for asset \"c9ac4b3b65f3510a2088b7fd003de23d2aefac424025eb168725ce6769e3c176\"" + "Description": "Artifact hash for asset \"3c3ed777478fe845fb5950df5e26461242b39cf220f00e0683aab244d9d7c0f7\"" }, "AssetParametersfc4481abf279255619ff7418faa5d24456fef3432ea0da59c95542578ff0222eS3Bucket9CD8B20A": { "Type": "String", diff --git a/packages/@aws-cdk/lambda-layer-awscli/.eslintrc.js b/packages/@aws-cdk/lambda-layer-awscli/.eslintrc.js new file mode 100644 index 0000000000000..61dd8dd001f63 --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-awscli/.eslintrc.js @@ -0,0 +1,3 @@ +const baseConfig = require('cdk-build-tools/config/eslintrc'); +baseConfig.parserOptions.project = __dirname + '/tsconfig.json'; +module.exports = baseConfig; diff --git a/packages/@aws-cdk/lambda-layer-awscli/.gitignore b/packages/@aws-cdk/lambda-layer-awscli/.gitignore new file mode 100644 index 0000000000000..a86aa21cbaad0 --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-awscli/.gitignore @@ -0,0 +1,20 @@ +*.js +*.js.map +*.d.ts +tsconfig.json +node_modules +*.generated.ts +dist +.jsii + +.LAST_BUILD +.nyc_output +coverage +nyc.config.js +.LAST_PACKAGE +*.snk +!.eslintrc.js +!jest.config.js + +junit.xml +lib/*.zip diff --git a/packages/@aws-cdk/lambda-layer-awscli/.npmignore b/packages/@aws-cdk/lambda-layer-awscli/.npmignore new file mode 100644 index 0000000000000..a7cfe248b3336 --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-awscli/.npmignore @@ -0,0 +1,30 @@ +# Don't include original .ts files when doing `npm pack` +*.ts +!*.d.ts +coverage +.nyc_output +*.tgz + +dist +.LAST_PACKAGE +.LAST_BUILD +!*.js + +# Include .jsii +!.jsii + +*.snk + +*.tsbuildinfo + +tsconfig.json +.eslintrc.js +jest.config.js + +# exclude cdk artifacts +**/cdk.out +junit.xml + +layer/ + +test/ \ No newline at end of file diff --git a/packages/@aws-cdk/lambda-layer-awscli/LICENSE b/packages/@aws-cdk/lambda-layer-awscli/LICENSE new file mode 100644 index 0000000000000..b71ec1688783a --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-awscli/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/@aws-cdk/lambda-layer-awscli/NOTICE b/packages/@aws-cdk/lambda-layer-awscli/NOTICE new file mode 100644 index 0000000000000..bfccac9a7f69c --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-awscli/NOTICE @@ -0,0 +1,2 @@ +AWS Cloud Development Kit (AWS CDK) +Copyright 2018-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/packages/@aws-cdk/lambda-layer-awscli/README.md b/packages/@aws-cdk/lambda-layer-awscli/README.md new file mode 100644 index 0000000000000..ae6460fae09d3 --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-awscli/README.md @@ -0,0 +1,28 @@ +# AWS Lambda Layer with AWS CLI + + +--- + +![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge) + +> The APIs of higher level constructs in this module are experimental and under active development. +> They are subject to non-backward compatible changes or removal in any future version. These are +> not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be +> announced in the release notes. This means that while you may use them, you may need to update +> your source code when upgrading to a newer version of this package. + +--- + + + + +This module exports a single class called `AwsCliLayer` which is a `lambda.Layer` that bundles the AWS CLI. + +Usage: + +```ts +const fn = new lambda.Function(...); +fn.addLayers(new AwsCliLayer(stack, 'AwsCliLayer')); +``` + +The CLI will be installed under `/opt/awscli/aws`. diff --git a/packages/@aws-cdk/lambda-layer-awscli/jest.config.js b/packages/@aws-cdk/lambda-layer-awscli/jest.config.js new file mode 100644 index 0000000000000..54e28beb9798b --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-awscli/jest.config.js @@ -0,0 +1,2 @@ +const baseConfig = require('cdk-build-tools/config/jest.config'); +module.exports = baseConfig; diff --git a/packages/@aws-cdk/lambda-layer-awscli/layer/.dockerignore b/packages/@aws-cdk/lambda-layer-awscli/layer/.dockerignore new file mode 100644 index 0000000000000..88a84e55aa43b --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-awscli/layer/.dockerignore @@ -0,0 +1 @@ +build.sh diff --git a/packages/@aws-cdk/lambda-layer-awscli/layer/Dockerfile b/packages/@aws-cdk/lambda-layer-awscli/layer/Dockerfile new file mode 100644 index 0000000000000..7cf1287e2023c --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-awscli/layer/Dockerfile @@ -0,0 +1,51 @@ +FROM public.ecr.aws/lambda/provided:latest + +# +# versions +# + +ARG AWSCLI_VERSION=1.18.198 + +USER root +RUN mkdir -p /opt +WORKDIR /tmp + +# +# tools +# + +RUN yum update -y \ + && yum install -y zip unzip wget tar gzip + +# +# aws cli +# + +RUN curl https://s3.amazonaws.com/aws-cli/awscli-bundle-${AWSCLI_VERSION}.zip -o awscli-bundle.zip +RUN unzip awscli-bundle.zip +RUN ./awscli-bundle/install -i /opt/awscli -b /opt/awscli/aws + +# organize for self-contained usage +RUN mv /opt/awscli /opt/awscli.tmp +RUN mv /opt/awscli.tmp/lib/python2.7/site-packages /opt/awscli +RUN mv /opt/awscli.tmp/bin /opt/awscli/bin +RUN mv /opt/awscli/bin/aws /opt/awscli + +# cleanup +RUN rm -fr /opt/awscli.tmp +RUN rm -rf \ + /opt/awscli/pip* \ + /opt/awscli/setuptools* \ + /opt/awscli/awscli/examples + +# +# create the bundle +# + +RUN cd /opt \ + && zip --symlinks -r ../layer.zip * \ + && echo "/layer.zip is ready" \ + && ls -alh /layer.zip; + +WORKDIR / +ENTRYPOINT [ "/bin/bash" ] \ No newline at end of file diff --git a/packages/@aws-cdk/lambda-layer-awscli/layer/build.sh b/packages/@aws-cdk/lambda-layer-awscli/layer/build.sh new file mode 100755 index 0000000000000..a7c13263ebdce --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-awscli/layer/build.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -euo pipefail + +cd $(dirname $0) + +echo ">> Building AWS Lambda layer inside a docker image..." + +TAG='aws-lambda-layer' + +docker build -t ${TAG} . + +echo ">> Extrating layer.zip from the build container..." +CONTAINER=$(docker run -d ${TAG} false) +docker cp ${CONTAINER}:/layer.zip ../lib/layer.zip + +echo ">> Stopping container..." +docker rm -f ${CONTAINER} +echo ">> lib/layer.zip is ready" diff --git a/packages/@aws-cdk/lambda-layer-awscli/lib/awscli-layer.ts b/packages/@aws-cdk/lambda-layer-awscli/lib/awscli-layer.ts new file mode 100644 index 0000000000000..525babcac82f3 --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-awscli/lib/awscli-layer.ts @@ -0,0 +1,27 @@ +import * as crypto from 'crypto'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as lambda from '@aws-cdk/aws-lambda'; +import { Construct } from 'constructs'; + +/** + * An AWS Lambda layer that includes the AWS CLI. + */ +export class AwsCliLayer extends lambda.LayerVersion { + constructor(scope: Construct, id: string) { + super(scope, id, { + code: lambda.Code.fromAsset(path.join(__dirname, 'layer.zip'), { + // we hash the Dockerfile (it contains the tools versions) because hashing the zip is non-deterministic + assetHash: hashFile(path.join(__dirname, '..', 'layer', 'Dockerfile')), + }), + description: '/opt/awscli/aws', + }); + } +} + +function hashFile(fileName: string) { + return crypto + .createHash('sha256') + .update(fs.readFileSync(fileName)) + .digest('hex'); +} \ No newline at end of file diff --git a/packages/@aws-cdk/lambda-layer-awscli/lib/index.ts b/packages/@aws-cdk/lambda-layer-awscli/lib/index.ts new file mode 100644 index 0000000000000..8bf4706a24cc4 --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-awscli/lib/index.ts @@ -0,0 +1 @@ +export * from './awscli-layer'; diff --git a/packages/@aws-cdk/lambda-layer-awscli/package.json b/packages/@aws-cdk/lambda-layer-awscli/package.json new file mode 100644 index 0000000000000..344ffc2e43521 --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-awscli/package.json @@ -0,0 +1,106 @@ +{ + "name": "@aws-cdk/lambda-layer-awscli", + "private": false, + "version": "0.0.0", + "description": "An AWS Lambda layer that contains the AWS CLI", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "jsii": { + "outdir": "dist", + "targets": { + "java": { + "package": "software.amazon.awscdk.lambdalayer.awscli", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "cdk-lambda-layer-awscli" + } + }, + "dotnet": { + "namespace": "Amazon.CDK.LambdaLayer.AwsCli", + "packageId": "Amazon.CDK.LambdaLayer.AwsCli", + "signAssembly": true, + "assemblyOriginatorKeyFile": "../../key.snk", + "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png" + }, + "python": { + "distName": "aws-cdk.lambda-layer-awscli", + "module": "aws_cdk.lambda_layer_awscli", + "classifiers": [ + "Framework :: AWS CDK", + "Framework :: AWS CDK :: 1" + ] + } + }, + "projectReferences": true + }, + "repository": { + "type": "git", + "url": "https://github.com/aws/aws-cdk.git", + "directory": "packages/@aws-cdk/lambda-layer-awscli" + }, + "scripts": { + "build": "cdk-build", + "watch": "cdk-watch", + "lint": "cdk-lint", + "test": "cdk-test", + "integ": "cdk-integ", + "pkglint": "pkglint -f", + "package": "cdk-package", + "awslint": "cdk-awslint", + "build+test": "npm run build && npm test", + "build+test+package": "npm run build+test && npm run package", + "compat": "cdk-compat", + "rosetta:extract": "yarn --silent jsii-rosetta extract" + }, + "keywords": [ + "aws", + "cdk", + "example", + "construct", + "library" + ], + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "organization": true + }, + "license": "Apache-2.0", + "devDependencies": { + "@aws-cdk/assert": "0.0.0", + "cdk-build-tools": "0.0.0", + "cdk-integ-tools": "0.0.0", + "jest": "^26.6.3", + "pkglint": "0.0.0" + }, + "dependencies": { + "@aws-cdk/aws-lambda": "0.0.0", + "@aws-cdk/core": "0.0.0", + "constructs": "^3.2.0" + }, + "homepage": "https://github.com/aws/aws-cdk", + "peerDependencies": { + "@aws-cdk/aws-lambda": "0.0.0", + "@aws-cdk/core": "0.0.0", + "constructs": "^3.2.0" + }, + "engines": { + "node": ">= 10.13.0 <13 || >=13.7.0" + }, + "stability": "experimental", + "maturity": "experimental", + "awscdkio": { + "announce": false + }, + "cdk-build": { + "pre": [ + "layer/build.sh" + ], + "jest": true, + "env": { + "AWSLINT_BASE_CONSTRUCT": true + } + }, + "ubergen": { + "exclude": false + } +} diff --git a/packages/@aws-cdk/lambda-layer-awscli/test/awscli-layer.test.ts b/packages/@aws-cdk/lambda-layer-awscli/test/awscli-layer.test.ts new file mode 100644 index 0000000000000..923d4f3ceaf64 --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-awscli/test/awscli-layer.test.ts @@ -0,0 +1,16 @@ +import { Stack } from '@aws-cdk/core'; +import { AwsCliLayer } from '../lib'; +import '@aws-cdk/assert/jest'; + +test('synthesized to a layer version', () => { + //GIVEN + const stack = new Stack(); + + // WHEN + new AwsCliLayer(stack, 'MyLayer'); + + // THEN + expect(stack).toHaveResource('AWS::Lambda::LayerVersion', { + Description: '/opt/awscli/aws', + }); +}); diff --git a/packages/@aws-cdk/lambda-layer-kubectl/.eslintrc.js b/packages/@aws-cdk/lambda-layer-kubectl/.eslintrc.js new file mode 100644 index 0000000000000..61dd8dd001f63 --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-kubectl/.eslintrc.js @@ -0,0 +1,3 @@ +const baseConfig = require('cdk-build-tools/config/eslintrc'); +baseConfig.parserOptions.project = __dirname + '/tsconfig.json'; +module.exports = baseConfig; diff --git a/packages/@aws-cdk/lambda-layer-kubectl/.gitignore b/packages/@aws-cdk/lambda-layer-kubectl/.gitignore new file mode 100644 index 0000000000000..a86aa21cbaad0 --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-kubectl/.gitignore @@ -0,0 +1,20 @@ +*.js +*.js.map +*.d.ts +tsconfig.json +node_modules +*.generated.ts +dist +.jsii + +.LAST_BUILD +.nyc_output +coverage +nyc.config.js +.LAST_PACKAGE +*.snk +!.eslintrc.js +!jest.config.js + +junit.xml +lib/*.zip diff --git a/packages/@aws-cdk/lambda-layer-kubectl/.npmignore b/packages/@aws-cdk/lambda-layer-kubectl/.npmignore new file mode 100644 index 0000000000000..a7cfe248b3336 --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-kubectl/.npmignore @@ -0,0 +1,30 @@ +# Don't include original .ts files when doing `npm pack` +*.ts +!*.d.ts +coverage +.nyc_output +*.tgz + +dist +.LAST_PACKAGE +.LAST_BUILD +!*.js + +# Include .jsii +!.jsii + +*.snk + +*.tsbuildinfo + +tsconfig.json +.eslintrc.js +jest.config.js + +# exclude cdk artifacts +**/cdk.out +junit.xml + +layer/ + +test/ \ No newline at end of file diff --git a/packages/@aws-cdk/lambda-layer-kubectl/LICENSE b/packages/@aws-cdk/lambda-layer-kubectl/LICENSE new file mode 100644 index 0000000000000..b71ec1688783a --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-kubectl/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/@aws-cdk/lambda-layer-kubectl/NOTICE b/packages/@aws-cdk/lambda-layer-kubectl/NOTICE new file mode 100644 index 0000000000000..ebe97bffffac1 --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-kubectl/NOTICE @@ -0,0 +1,37 @@ +AWS Cloud Development Kit (AWS CDK) +Copyright 2018-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +---------------- + +** kubectl - https://github.com/kubernetes/kubectl +Copyright 2017 The Kubernetes Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +---------------- + +** helm - https://github.com/helm/helm +Copyright 2016 The Kubernetes Authors All Rights Reserved + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/packages/@aws-cdk/lambda-layer-kubectl/README.md b/packages/@aws-cdk/lambda-layer-kubectl/README.md new file mode 100644 index 0000000000000..ae6460fae09d3 --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-kubectl/README.md @@ -0,0 +1,28 @@ +# AWS Lambda Layer with AWS CLI + + +--- + +![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge) + +> The APIs of higher level constructs in this module are experimental and under active development. +> They are subject to non-backward compatible changes or removal in any future version. These are +> not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be +> announced in the release notes. This means that while you may use them, you may need to update +> your source code when upgrading to a newer version of this package. + +--- + + + + +This module exports a single class called `AwsCliLayer` which is a `lambda.Layer` that bundles the AWS CLI. + +Usage: + +```ts +const fn = new lambda.Function(...); +fn.addLayers(new AwsCliLayer(stack, 'AwsCliLayer')); +``` + +The CLI will be installed under `/opt/awscli/aws`. diff --git a/packages/@aws-cdk/lambda-layer-kubectl/jest.config.js b/packages/@aws-cdk/lambda-layer-kubectl/jest.config.js new file mode 100644 index 0000000000000..54e28beb9798b --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-kubectl/jest.config.js @@ -0,0 +1,2 @@ +const baseConfig = require('cdk-build-tools/config/jest.config'); +module.exports = baseConfig; diff --git a/packages/@aws-cdk/lambda-layer-kubectl/layer/.dockerignore b/packages/@aws-cdk/lambda-layer-kubectl/layer/.dockerignore new file mode 100644 index 0000000000000..88a84e55aa43b --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-kubectl/layer/.dockerignore @@ -0,0 +1 @@ +build.sh diff --git a/packages/@aws-cdk/lambda-layer-kubectl/layer/Dockerfile b/packages/@aws-cdk/lambda-layer-kubectl/layer/Dockerfile new file mode 100644 index 0000000000000..c04c0cc9bfbea --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-kubectl/layer/Dockerfile @@ -0,0 +1,47 @@ +# base lambda image +FROM public.ecr.aws/lambda/provided:latest + +# +# versions +# + +ARG KUBECTL_VERSION=1.20.0 +ARG HELM_VERSION=3.4.2 + +USER root +RUN mkdir -p /opt +WORKDIR /tmp + +# +# tools +# + +RUN yum update -y \ + && yum install -y zip unzip wget tar gzip + +# +# kubectl +# + +RUN mkdir -p /opt/kubectl +RUN cd /opt/kubectl && curl -LO "https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl" +RUN chmod +x /opt/kubectl/kubectl + +# +# helm +# + +RUN mkdir -p /tmp/helm && wget -qO- https://get.helm.sh/helm-v${HELM_VERSION}-linux-amd64.tar.gz | tar -xvz -C /tmp/helm +RUN mkdir -p /opt/helm && cp /tmp/helm/linux-amd64/helm /opt/helm/helm + +# +# create the bundle +# + +RUN cd /opt \ + && zip --symlinks -r ../layer.zip * \ + && echo "/layer.zip is ready" \ + && ls -alh /layer.zip; + +WORKDIR / +ENTRYPOINT [ "/bin/bash" ] \ No newline at end of file diff --git a/packages/@aws-cdk/lambda-layer-kubectl/layer/build.sh b/packages/@aws-cdk/lambda-layer-kubectl/layer/build.sh new file mode 100755 index 0000000000000..a7c13263ebdce --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-kubectl/layer/build.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -euo pipefail + +cd $(dirname $0) + +echo ">> Building AWS Lambda layer inside a docker image..." + +TAG='aws-lambda-layer' + +docker build -t ${TAG} . + +echo ">> Extrating layer.zip from the build container..." +CONTAINER=$(docker run -d ${TAG} false) +docker cp ${CONTAINER}:/layer.zip ../lib/layer.zip + +echo ">> Stopping container..." +docker rm -f ${CONTAINER} +echo ">> lib/layer.zip is ready" diff --git a/packages/@aws-cdk/lambda-layer-kubectl/lib/index.ts b/packages/@aws-cdk/lambda-layer-kubectl/lib/index.ts new file mode 100644 index 0000000000000..1967f462ac1dc --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-kubectl/lib/index.ts @@ -0,0 +1 @@ +export * from './kubectl-layer'; diff --git a/packages/@aws-cdk/lambda-layer-kubectl/lib/kubectl-layer.ts b/packages/@aws-cdk/lambda-layer-kubectl/lib/kubectl-layer.ts new file mode 100644 index 0000000000000..91c8b3e9cc1de --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-kubectl/lib/kubectl-layer.ts @@ -0,0 +1,27 @@ +import * as crypto from 'crypto'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as lambda from '@aws-cdk/aws-lambda'; +import { Construct } from 'constructs'; + +/** + * An AWS Lambda layer that includes `kubectl` and `helm`. + */ +export class KubectlLayer extends lambda.LayerVersion { + constructor(scope: Construct, id: string) { + super(scope, id, { + code: lambda.Code.fromAsset(path.join(__dirname, 'layer.zip'), { + // we hash the Dockerfile (it contains the tools versions) because hashing the zip is non-deterministic + assetHash: hashFile(path.join(__dirname, '..', 'layer', 'Dockerfile')), + }), + description: '/opt/kubectl/kubectl and /opt/helm/helm', + }); + } +} + +function hashFile(fileName: string) { + return crypto + .createHash('sha256') + .update(fs.readFileSync(fileName)) + .digest('hex'); +} \ No newline at end of file diff --git a/packages/@aws-cdk/lambda-layer-kubectl/package.json b/packages/@aws-cdk/lambda-layer-kubectl/package.json new file mode 100644 index 0000000000000..8a6c18ac0e9c4 --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-kubectl/package.json @@ -0,0 +1,112 @@ +{ + "name": "@aws-cdk/lambda-layer-kubectl", + "private": false, + "version": "0.0.0", + "description": "An AWS Lambda layer that contains the `kubectl` and `helm`", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "jsii": { + "outdir": "dist", + "targets": { + "java": { + "package": "software.amazon.awscdk.lambdalayer.kubectl", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "cdk-lambda-layer-kubectl" + } + }, + "dotnet": { + "namespace": "Amazon.CDK.LambdaLayer.Kubectl", + "packageId": "Amazon.CDK.LambdaLayer.Kubectl", + "signAssembly": true, + "assemblyOriginatorKeyFile": "../../key.snk", + "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png" + }, + "python": { + "distName": "aws-cdk.lambda-layer-kubectl", + "module": "aws_cdk.lambda_layer_kubectl", + "classifiers": [ + "Framework :: AWS CDK", + "Framework :: AWS CDK :: 1" + ] + } + }, + "projectReferences": true + }, + "repository": { + "type": "git", + "url": "https://github.com/aws/aws-cdk.git", + "directory": "packages/@aws-cdk/lambda-layer-kubectl" + }, + "scripts": { + "build": "cdk-build", + "watch": "cdk-watch", + "lint": "cdk-lint", + "test": "cdk-test", + "integ": "cdk-integ", + "pkglint": "pkglint -f", + "package": "cdk-package", + "awslint": "cdk-awslint", + "build+test": "npm run build && npm test", + "build+test+package": "npm run build+test && npm run package", + "compat": "cdk-compat", + "rosetta:extract": "yarn --silent jsii-rosetta extract" + }, + "keywords": [ + "aws", + "cdk", + "example", + "construct", + "library" + ], + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "organization": true + }, + "license": "Apache-2.0", + "devDependencies": { + "@aws-cdk/assert": "0.0.0", + "cdk-build-tools": "0.0.0", + "cdk-integ-tools": "0.0.0", + "jest": "^26.6.3", + "pkglint": "0.0.0" + }, + "pkglint": { + "attribution": [ + "kubectl", + "helm" + ] + }, + "dependencies": { + "@aws-cdk/aws-lambda": "0.0.0", + "@aws-cdk/core": "0.0.0", + "constructs": "^3.2.0" + }, + "homepage": "https://github.com/aws/aws-cdk", + "peerDependencies": { + "@aws-cdk/aws-lambda": "0.0.0", + "@aws-cdk/core": "0.0.0", + "constructs": "^3.2.0" + }, + "engines": { + "node": ">= 10.13.0 <13 || >=13.7.0" + }, + "stability": "experimental", + "maturity": "experimental", + "awscdkio": { + "announce": false + }, + "cdk-build": { + "pre": [ + "layer/build.sh" + ], + "jest": true, + "env": { + "AWSLINT_BASE_CONSTRUCT": true + } + }, + "ubergen": { + "exclude": false + } +} diff --git a/packages/@aws-cdk/lambda-layer-kubectl/test/kubectl-layer.test.ts b/packages/@aws-cdk/lambda-layer-kubectl/test/kubectl-layer.test.ts new file mode 100644 index 0000000000000..d73303dd5e32d --- /dev/null +++ b/packages/@aws-cdk/lambda-layer-kubectl/test/kubectl-layer.test.ts @@ -0,0 +1,16 @@ +import { Stack } from '@aws-cdk/core'; +import { KubectlLayer } from '../lib'; +import '@aws-cdk/assert/jest'; + +test('synthesized to a layer version', () => { + //GIVEN + const stack = new Stack(); + + // WHEN + new KubectlLayer(stack, 'MyLayer'); + + // THEN + expect(stack).toHaveResource('AWS::Lambda::LayerVersion', { + Description: '/opt/kubectl/kubectl and /opt/helm/helm', + }); +}); diff --git a/packages/aws-cdk-lib/package.json b/packages/aws-cdk-lib/package.json index 3e637757b47de..e311335fa1b04 100644 --- a/packages/aws-cdk-lib/package.json +++ b/packages/aws-cdk-lib/package.json @@ -260,6 +260,8 @@ "@aws-cdk/aws-wafregional": "0.0.0", "@aws-cdk/aws-wafv2": "0.0.0", "@aws-cdk/aws-workspaces": "0.0.0", + "@aws-cdk/lambda-layer-awscli": "0.0.0", + "@aws-cdk/lambda-layer-kubectl": "0.0.0", "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/cloudformation-include": "0.0.0", "@aws-cdk/core": "0.0.0", diff --git a/packages/decdk/package.json b/packages/decdk/package.json index f32367e7265ea..188ceb25e8c26 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -194,6 +194,8 @@ "@aws-cdk/pipelines": "0.0.0", "@aws-cdk/region-info": "0.0.0", "@aws-cdk/yaml-cfn": "0.0.0", + "@aws-cdk/lambda-layer-awscli": "0.0.0", + "@aws-cdk/lambda-layer-kubectl": "0.0.0", "constructs": "^3.2.0", "fs-extra": "^9.0.1", "jsii-reflect": "^1.15.0", diff --git a/packages/monocdk/package.json b/packages/monocdk/package.json index b78a8c6adcc9c..d3d36459b0941 100644 --- a/packages/monocdk/package.json +++ b/packages/monocdk/package.json @@ -264,9 +264,13 @@ "@aws-cdk/core": "0.0.0", "@aws-cdk/custom-resources": "0.0.0", "@aws-cdk/cx-api": "0.0.0", + "@aws-cdk/lambda-layer-awscli": "0.0.0", + "@aws-cdk/lambda-layer-kubectl": "0.0.0", "@aws-cdk/pipelines": "0.0.0", "@aws-cdk/region-info": "0.0.0", "@aws-cdk/yaml-cfn": "0.0.0", + "@aws-cdk/lambda-layer-awscli": "0.0.0", + "@aws-cdk/lambda-layer-kubectl": "0.0.0", "@types/fs-extra": "^8.1.1", "@types/node": "^10.17.48", "cdk-build-tools": "0.0.0", diff --git a/tools/pkglint/lib/rules.ts b/tools/pkglint/lib/rules.ts index 1729eaef0a23d..88688249729a6 100644 --- a/tools/pkglint/lib/rules.ts +++ b/tools/pkglint/lib/rules.ts @@ -147,6 +147,7 @@ export class ThirdPartyAttributions extends ValidationRule { return; } const bundled = pkg.getAllBundledDependencies().filter(dep => !dep.startsWith('@aws-cdk')); + const attribution = pkg.json.pkglint?.attribution ?? []; const noticePath = path.join(pkg.packageRoot, 'NOTICE'); const lines = fs.existsSync(noticePath) ? fs.readFileSync(noticePath, { encoding: 'utf8' }).split('\n') @@ -164,9 +165,9 @@ export class ThirdPartyAttributions extends ValidationRule { } } for (const attr of attributions) { - if (!bundled.includes(attr)) { + if (!bundled.includes(attr) && !attribution.includes(attr)) { pkg.report({ - message: `Unnecessary attribution found for dependency '${attr}' in NOTICE file.`, + message: `Unnecessary attribution found for dependency '${attr}' in NOTICE file. Attribution is determined from package.json (all "bundledDependencies" or the list in "pkglint.attribution")`, ruleName: this.name, }); }