From 56c6f98dbcfc98740446f699a8985d7d6b44c503 Mon Sep 17 00:00:00 2001 From: alex-vance <50587352+alex-vance@users.noreply.github.com> Date: Thu, 1 Apr 2021 13:24:27 -0500 Subject: [PATCH] feat(eks): Support `secretsEncryptionKey` in FargateCluster (#13866) This PR adds a secretEncryptionKey to the FargateClusterProps to allow generating an EKS Fargate cluster with a KMS key to encrypt Kubernetes Secrets. The existing EKS Cluster contruct already exposes this prop by default so this allows it to pass through to work with the existing functionality. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-eks/README.md | 9 ++++++ packages/@aws-cdk/aws-eks/lib/cluster.ts | 32 +++++++++---------- .../@aws-cdk/aws-eks/test/test.fargate.ts | 32 +++++++++++++++++++ 3 files changed, 57 insertions(+), 16 deletions(-) diff --git a/packages/@aws-cdk/aws-eks/README.md b/packages/@aws-cdk/aws-eks/README.md index 1cc2ce685070b..43e765b337fd9 100644 --- a/packages/@aws-cdk/aws-eks/README.md +++ b/packages/@aws-cdk/aws-eks/README.md @@ -654,6 +654,15 @@ const cluster = new eks.Cluster(this, 'MyCluster', { }); ``` +You can also use a similiar configuration for running a cluster built using the FargateCluster construct. + +```ts +const secretsKey = new kms.Key(this, 'SecretsKey'); +const cluster = new eks.FargateCluster(this, 'MyFargateCluster', { + secretsEncryptionKey: secretsKey +}); +``` + The Amazon Resource Name (ARN) for that CMK can be retrieved. ```ts diff --git a/packages/@aws-cdk/aws-eks/lib/cluster.ts b/packages/@aws-cdk/aws-eks/lib/cluster.ts index 3b6f6fa9be348..9feac854438cb 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster.ts @@ -467,6 +467,15 @@ export interface ClusterOptions extends CommonClusterOptions { * @default false */ readonly placeClusterHandlerInVpc?: boolean; + + /** + * KMS secret for envelope encryption for Kubernetes secrets. + * + * @default - By default, Kubernetes stores all secret object data within etcd and + * all etcd volumes used by Amazon EKS are encrypted at the disk-level + * using AWS-Managed encryption keys. + */ + readonly secretsEncryptionKey?: kms.IKey; } /** @@ -594,15 +603,6 @@ export interface ClusterProps extends ClusterOptions { * @default NODEGROUP */ readonly defaultCapacityType?: DefaultCapacityType; - - /** - * KMS secret for envelope encryption for Kubernetes secrets. - * - * @default - By default, Kubernetes stores all secret object data within etcd and - * all etcd volumes used by Amazon EKS are encrypted at the disk-level - * using AWS-Managed encryption keys. - */ - readonly secretsEncryptionKey?: kms.IKey; } /** @@ -983,8 +983,8 @@ export class Cluster extends ClusterBase { const privateSubents = this.selectPrivateSubnets().slice(0, 16); const publicAccessDisabled = !this.endpointAccess._config.publicAccess; const publicAccessRestricted = !publicAccessDisabled - && this.endpointAccess._config.publicCidrs - && this.endpointAccess._config.publicCidrs.length !== 0; + && this.endpointAccess._config.publicCidrs + && this.endpointAccess._config.publicCidrs.length !== 0; // validate endpoint access configuration @@ -1020,7 +1020,7 @@ export class Cluster extends ClusterBase { }, resources: ['secrets'], }], - } : {} ), + } : {}), endpointPrivateAccess: this.endpointAccess._config.privateAccess, endpointPublicAccess: this.endpointAccess._config.publicAccess, publicAccessCidrs: this.endpointAccess._config.publicCidrs, @@ -1167,7 +1167,7 @@ export class Cluster extends ClusterBase { * [EC2 Spot Instance Termination Notices](https://aws.amazon.com/blogs/aws/new-ec2-spot-instance-termination-notices/). */ public addAutoScalingGroupCapacity(id: string, options: AutoScalingGroupCapacityOptions): autoscaling.AutoScalingGroup { - if (options.machineImageType === MachineImageType.BOTTLEROCKET && options.bootstrapOptions !== undefined ) { + if (options.machineImageType === MachineImageType.BOTTLEROCKET && options.bootstrapOptions !== undefined) { throw new Error('bootstrapOptions is not supported for Bottlerocket'); } const asg = new autoscaling.AutoScalingGroup(this, id, { @@ -1852,9 +1852,9 @@ export class EksOptimizedImage implements ec2.IMachineImage { // set the SSM parameter name this.amiParameterName = `/aws/service/eks/optimized-ami/${this.kubernetesVersion}/` - + ( this.nodeType === NodeType.STANDARD ? this.cpuArch === CpuArch.X86_64 ? - 'amazon-linux-2/' : 'amazon-linux-2-arm64/' :'' ) - + ( this.nodeType === NodeType.GPU ? 'amazon-linux-2-gpu/' : '' ) + + (this.nodeType === NodeType.STANDARD ? this.cpuArch === CpuArch.X86_64 ? + 'amazon-linux-2/' : 'amazon-linux-2-arm64/' : '') + + (this.nodeType === NodeType.GPU ? 'amazon-linux-2-gpu/' : '') + (this.nodeType === NodeType.INFERENTIA ? 'amazon-linux-2-gpu/' : '') + 'recommended/image_id'; } diff --git a/packages/@aws-cdk/aws-eks/test/test.fargate.ts b/packages/@aws-cdk/aws-eks/test/test.fargate.ts index ee17950915e9d..053279d7d076d 100644 --- a/packages/@aws-cdk/aws-eks/test/test.fargate.ts +++ b/packages/@aws-cdk/aws-eks/test/test.fargate.ts @@ -1,10 +1,12 @@ import { expect, haveResource, haveResourceLike, ResourcePart } from '@aws-cdk/assert'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; +import * as kms from '@aws-cdk/aws-kms'; import { Stack, Tags } from '@aws-cdk/core'; import { Test } from 'nodeunit'; import * as eks from '../lib'; + const CLUSTER_VERSION = eks.KubernetesVersion.V1_19; export = { @@ -427,4 +429,34 @@ export = { })); test.done(); }, + + 'supports passing secretsEncryptionKey with FargateCluster'(test: Test) { + // GIVEN + const stack = new Stack(); + + // WHEN + + new eks.FargateCluster(stack, 'FargateCluster', { + version: CLUSTER_VERSION, + secretsEncryptionKey: new kms.Key(stack, 'Key'), + }); + + // THEN + expect(stack).to(haveResourceLike('Custom::AWSCDK-EKS-Cluster', { + Config: { + encryptionConfig: [{ + provider: { + keyArn: { + 'Fn::GetAtt': [ + 'Key961B73FD', + 'Arn', + ], + }, + }, + resources: ['secrets'], + }], + }, + })); + test.done(); + }, };