From c77b3ee2ae2925eacff36a905085a81c8b338249 Mon Sep 17 00:00:00 2001 From: Choryu Park Date: Sat, 29 Jan 2022 03:51:56 +0900 Subject: [PATCH] feat(eks): cluster logging (#18112) Fixes #4159 ---- *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 | 25 +++++++++++ .../lib/cluster-resource-handler/cluster.ts | 4 ++ .../@aws-cdk/aws-eks/lib/cluster-resource.ts | 2 + packages/@aws-cdk/aws-eks/lib/cluster.ts | 44 +++++++++++++++++++ .../test/integ.eks-cluster.expected.json | 8 ++++ .../aws-eks/test/integ.eks-cluster.ts | 5 +++ 6 files changed, 88 insertions(+) diff --git a/packages/@aws-cdk/aws-eks/README.md b/packages/@aws-cdk/aws-eks/README.md index 1403e56d817fe..d389487e2f419 100644 --- a/packages/@aws-cdk/aws-eks/README.md +++ b/packages/@aws-cdk/aws-eks/README.md @@ -1397,6 +1397,31 @@ Kubernetes [endpoint access](#endpoint-access), you must also specify: * `kubectlPrivateSubnetIds` - a list of private VPC subnets IDs that will be used to access the Kubernetes endpoint. +## Logging + +EKS supports cluster logging for 5 different types of events: + +* API requests to the cluster. +* Cluster access via the Kubernetes API. +* Authentication requests into the cluster. +* State of cluster controllers. +* Scheduling decisions. + +You can enable logging for each one separately using the `clusterLogging` +property. For example: + +```ts +const cluster = new eks.Cluster(this, 'Cluster', { + // ... + version: eks.KubernetesVersion.V1_21, + clusterLogging: [ + eks.ClusterLoggingTypes.API, + eks.ClusterLoggingTypes.AUTHENTICATOR, + eks.ClusterLoggingTypes.SCHEDULER, + ], +}); +``` + ## Known Issues and Limitations * [One cluster per stack](https://github.com/aws/aws-cdk/issues/10073) diff --git a/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts b/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts index 61a33ddb3ab05..0ad46af16eaef 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts @@ -285,6 +285,10 @@ function parseProps(props: any): aws.EKS.CreateClusterRequest { parsed.resourcesVpcConfig.endpointPublicAccess = parsed.resourcesVpcConfig.endpointPublicAccess === 'true'; } + if (typeof (parsed.logging?.clusterLogging[0].enabled) === 'string') { + parsed.logging.clusterLogging[0].enabled = parsed.logging.clusterLogging[0].enabled === 'true'; + } + return parsed; } diff --git a/packages/@aws-cdk/aws-eks/lib/cluster-resource.ts b/packages/@aws-cdk/aws-eks/lib/cluster-resource.ts index 6a947380e3dd1..db5dc023ae32a 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster-resource.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster-resource.ts @@ -29,6 +29,7 @@ export interface ClusterResourceProps { readonly onEventLayer?: lambda.ILayerVersion; readonly clusterHandlerSecurityGroup?: ec2.ISecurityGroup; readonly tags?: { [key: string]: string }; + readonly logging?: { [key: string]: [ { [key: string]: any } ] }; } /** @@ -91,6 +92,7 @@ export class ClusterResource extends CoreConstruct { publicAccessCidrs: props.publicAccessCidrs, }, tags: props.tags, + logging: props.logging, }, AssumeRoleArn: this.adminRole.roleArn, diff --git a/packages/@aws-cdk/aws-eks/lib/cluster.ts b/packages/@aws-cdk/aws-eks/lib/cluster.ts index 10a3f2123aac1..c8a05ef59beaa 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster.ts @@ -757,6 +757,13 @@ export interface ClusterProps extends ClusterOptions { * @default - none */ readonly tags?: { [key: string]: string }; + + /** + * The cluster log types which you want to enable. + * + * @default - none + */ + readonly clusterLogging?: ClusterLoggingTypes[]; } /** @@ -815,6 +822,32 @@ export class KubernetesVersion { private constructor(public readonly version: string) { } } +/** + * EKS cluster logging types + */ +export enum ClusterLoggingTypes { + /** + * Logs pertaining to API requests to the cluster. + */ + API = 'api', + /** + * Logs pertaining to cluster access via the Kubernetes API. + */ + AUDIT = 'audit', + /** + * Logs pertaining to authentication requests into the cluster. + */ + AUTHENTICATOR = 'authenticator', + /** + * Logs pertaining to state of cluster controllers. + */ + CONTROLLER_MANAGER = 'controllerManager', + /** + * Logs pertaining to scheduling decisions. + */ + SCHEDULER = 'scheduler', +} + abstract class ClusterBase extends Resource implements ICluster { public abstract readonly connections: ec2.Connections; public abstract readonly vpc: ec2.IVpc; @@ -1253,6 +1286,8 @@ export class Cluster extends ClusterBase { private readonly version: KubernetesVersion; + private readonly logging?: { [key: string]: [ { [key: string]: any } ] }; + /** * A dummy CloudFormation resource that is used as a wait barrier which * represents that the cluster is ready to receive "kubectl" commands. @@ -1313,6 +1348,14 @@ export class Cluster extends ClusterBase { // Get subnetIds for all selected subnets const subnetIds = Array.from(new Set(flatten(selectedSubnetIdsPerGroup))); + this.logging = props.clusterLogging ? { + clusterLogging: [ + { + enabled: true, + types: Object.values(props.clusterLogging), + }, + ], + } : undefined; this.endpointAccess = props.endpointAccess ?? EndpointAccess.PUBLIC_AND_PRIVATE; this.kubectlEnvironment = props.kubectlEnvironment; @@ -1379,6 +1422,7 @@ export class Cluster extends ClusterBase { clusterHandlerSecurityGroup: this.clusterHandlerSecurityGroup, onEventLayer: this.onEventLayer, tags: props.tags, + logging: this.logging, }); if (this.endpointAccess._config.privateAccess && privateSubnets.length !== 0) { 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 7b5af8f848f2e..1476182e23c37 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 @@ -954,6 +954,14 @@ }, "tags": { "foo": "bar" + }, + "logging": { + "clusterLogging": [ + { + "enabled": true, + "types": [ "api", "authenticator", "scheduler" ] + } + ] } }, "AssumeRoleArn": { diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts index 8dd012b3e2d66..1ae9a97e5bb37 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts @@ -41,6 +41,11 @@ class EksClusterStack extends TestStack { tags: { foo: 'bar', }, + clusterLogging: [ + eks.ClusterLoggingTypes.API, + eks.ClusterLoggingTypes.AUTHENTICATOR, + eks.ClusterLoggingTypes.SCHEDULER, + ], }); this.assertFargateProfile();