From 4982aca6f95ca864a285ed9955a9618a20ca0415 Mon Sep 17 00:00:00 2001 From: markussiebert Date: Thu, 25 Nov 2021 00:43:03 +0100 Subject: [PATCH] feat(docdb): implement audit and profiler logs (#17570) closes #17478 *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-docdb/README.md | 16 +++++ packages/@aws-cdk/aws-docdb/lib/cluster.ts | 29 +++++++++ .../@aws-cdk/aws-docdb/test/cluster.test.ts | 64 +++++++++++++++++++ 3 files changed, 109 insertions(+) diff --git a/packages/@aws-cdk/aws-docdb/README.md b/packages/@aws-cdk/aws-docdb/README.md index 808fe85208c45..650d37ffffc5f 100644 --- a/packages/@aws-cdk/aws-docdb/README.md +++ b/packages/@aws-cdk/aws-docdb/README.md @@ -116,3 +116,19 @@ cluster.addRotationMultiUser('MyUser', { // Add rotation using the multi user sc The rotation will start as soon as this user exists. See also [@aws-cdk/aws-secretsmanager](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-secretsmanager/README.md) for credentials rotation of existing clusters. + +## Audit and profiler Logs + +Sending audit or profiler needs to be configured in two places: + +1. Check / create the needed options in your ParameterGroup for [audit](https://docs.aws.amazon.com/documentdb/latest/developerguide/event-auditing.html#event-auditing-enabling-auditing) and +[profiler](https://docs.aws.amazon.com/documentdb/latest/developerguide/profiling.html#profiling.enable-profiling) logs. +2. Enable the corresponding option(s) when creating the `DatabaseCluster`: + +```ts +const cluster = new DatabaseCluster(this, 'Database', { + ..., + exportProfilerLogsToCloudWatch: true, // Enable sending profiler logs + exportAuditLogsToCloudWatch: true, // Enable sending audit logs +}); +``` diff --git a/packages/@aws-cdk/aws-docdb/lib/cluster.ts b/packages/@aws-cdk/aws-docdb/lib/cluster.ts index 6a744d089320c..fe208c068c213 100644 --- a/packages/@aws-cdk/aws-docdb/lib/cluster.ts +++ b/packages/@aws-cdk/aws-docdb/lib/cluster.ts @@ -146,6 +146,24 @@ export interface DatabaseClusterProps { * @default - false */ readonly deletionProtection?: boolean; + + /** + * Whether the profiler logs should be exported to CloudWatch. + * Note that you also have to configure the profiler log export in the Cluster's Parameter Group. + * + * @see https://docs.aws.amazon.com/documentdb/latest/developerguide/profiling.html#profiling.enable-profiling + * @default false + */ + readonly exportProfilerLogsToCloudWatch?: boolean; + + /** + * Whether the audit logs should be exported to CloudWatch. + * Note that you also have to configure the audit log export in the Cluster's Parameter Group. + * + * @see https://docs.aws.amazon.com/documentdb/latest/developerguide/event-auditing.html#event-auditing-enabling-auditing + * @default false + */ + readonly exportAuditLogsToCloudWatch?: boolean; } /** @@ -346,6 +364,15 @@ export class DatabaseCluster extends DatabaseClusterBase { } this.securityGroupId = securityGroup.securityGroupId; + // Create the CloudwatchLogsConfiguratoin + const enableCloudwatchLogsExports: string[] = []; + if (props.exportAuditLogsToCloudWatch) { + enableCloudwatchLogsExports.push('audit'); + } + if (props.exportProfilerLogsToCloudWatch) { + enableCloudwatchLogsExports.push('profiler'); + } + // Create the secret manager secret if no password is specified let secret: DatabaseSecret | undefined; if (!props.masterUser.password) { @@ -383,6 +410,8 @@ export class DatabaseCluster extends DatabaseClusterBase { backupRetentionPeriod: props.backup?.retention?.toDays(), preferredBackupWindow: props.backup?.preferredWindow, preferredMaintenanceWindow: props.preferredMaintenanceWindow, + // EnableCloudwatchLogsExports + enableCloudwatchLogsExports: enableCloudwatchLogsExports.length > 0 ? enableCloudwatchLogsExports : undefined, // Encryption kmsKeyId: props.kmsKey?.keyArn, storageEncrypted, diff --git a/packages/@aws-cdk/aws-docdb/test/cluster.test.ts b/packages/@aws-cdk/aws-docdb/test/cluster.test.ts index 819825f6df094..f8bfdc65adda1 100644 --- a/packages/@aws-cdk/aws-docdb/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-docdb/test/cluster.test.ts @@ -588,6 +588,70 @@ describe('DatabaseCluster', () => { })); }); + test('can configure CloudWatchLogs for audit', () => { + // GIVEN + const stack = testStack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + + // WHEN + new DatabaseCluster(stack, 'Database', { + masterUser: { + username: 'admin', + }, + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + vpc, + exportAuditLogsToCloudWatch: true, + }); + + // THEN + expectCDK(stack).to(haveResource('AWS::DocDB::DBCluster', { + EnableCloudwatchLogsExports: ['audit'], + })); + }); + + test('can configure CloudWatchLogs for profiler', () => { + // GIVEN + const stack = testStack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + + // WHEN + new DatabaseCluster(stack, 'Database', { + masterUser: { + username: 'admin', + }, + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + vpc, + exportProfilerLogsToCloudWatch: true, + }); + + // THEN + expectCDK(stack).to(haveResource('AWS::DocDB::DBCluster', { + EnableCloudwatchLogsExports: ['profiler'], + })); + }); + + test('can configure CloudWatchLogs for all logs', () => { + // GIVEN + const stack = testStack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + + // WHEN + new DatabaseCluster(stack, 'Database', { + masterUser: { + username: 'admin', + }, + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + vpc, + exportAuditLogsToCloudWatch: true, + exportProfilerLogsToCloudWatch: true, + }); + + // THEN + expectCDK(stack).to(haveResource('AWS::DocDB::DBCluster', { + EnableCloudwatchLogsExports: ['audit', 'profiler'], + })); + }); + test('single user rotation', () => { // GIVEN const stack = testStack();