Skip to content

Commit 002202f

Browse files
authored
feat(docdb): allow setting log retention (#18120)
Provide an option to configure the number of days log events are kept in CloudWatch Logs. Properties `cloudwatchLogsRetention` and `cloudwatchLogsRetentionRole` are added to `DatabaseClusterProps`. Closes #13191. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 5ee8e3a commit 002202f

File tree

4 files changed

+83
-0
lines changed

4 files changed

+83
-0
lines changed

packages/@aws-cdk/aws-docdb/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -130,5 +130,7 @@ const cluster = new DatabaseCluster(this, 'Database', {
130130
...,
131131
exportProfilerLogsToCloudWatch: true, // Enable sending profiler logs
132132
exportAuditLogsToCloudWatch: true, // Enable sending audit logs
133+
cloudWatchLogsRetention: logs.RetentionDays.THREE_MONTHS, // Optional - default is to never expire logs
134+
cloudWatchLogsRetentionRole: myLogsPublishingRole, // Optional - a role will be created if not provided
133135
});
134136
```

packages/@aws-cdk/aws-docdb/lib/cluster.ts

+36
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import * as ec2 from '@aws-cdk/aws-ec2';
2+
import { IRole } from '@aws-cdk/aws-iam';
23
import * as kms from '@aws-cdk/aws-kms';
4+
import * as logs from '@aws-cdk/aws-logs';
35
import * as secretsmanager from '@aws-cdk/aws-secretsmanager';
46
import { CfnResource, Duration, RemovalPolicy, Resource, Token } from '@aws-cdk/core';
57
import { Construct } from 'constructs';
@@ -164,6 +166,23 @@ export interface DatabaseClusterProps {
164166
* @default false
165167
*/
166168
readonly exportAuditLogsToCloudWatch?: boolean;
169+
170+
/**
171+
* The number of days log events are kept in CloudWatch Logs. When updating
172+
* this property, unsetting it doesn't remove the log retention policy. To
173+
* remove the retention policy, set the value to `Infinity`.
174+
*
175+
* @default - logs never expire
176+
*/
177+
readonly cloudWatchLogsRetention?: logs.RetentionDays;
178+
179+
/**
180+
* The IAM role for the Lambda function associated with the custom resource
181+
* that sets the retention policy.
182+
*
183+
* @default - a new role is created.
184+
*/
185+
readonly cloudWatchLogsRetentionRole?: IRole;
167186
}
168187

169188
/**
@@ -428,6 +447,8 @@ export class DatabaseCluster extends DatabaseClusterBase {
428447
this.clusterEndpoint = new Endpoint(this.cluster.attrEndpoint, port);
429448
this.clusterReadEndpoint = new Endpoint(this.cluster.attrReadEndpoint, port);
430449

450+
this.setLogRetention(this, props, enableCloudwatchLogsExports);
451+
431452
if (secret) {
432453
this.secret = secret.attach(this);
433454
}
@@ -470,6 +491,21 @@ export class DatabaseCluster extends DatabaseClusterBase {
470491
});
471492
}
472493

494+
/**
495+
* Sets up CloudWatch log retention if configured.
496+
*/
497+
private setLogRetention(cluster: DatabaseCluster, props: DatabaseClusterProps, cloudwatchLogsExports: string[]) {
498+
if (props.cloudWatchLogsRetention) {
499+
for (const log of cloudwatchLogsExports) {
500+
new logs.LogRetention(cluster, `LogRetention${log}`, {
501+
logGroupName: `/aws/docdb/${cluster.clusterIdentifier}/${log}`,
502+
retention: props.cloudWatchLogsRetention,
503+
role: props.cloudWatchLogsRetentionRole,
504+
});
505+
}
506+
}
507+
}
508+
473509
/**
474510
* Adds the single user rotation of the master password to this cluster.
475511
*

packages/@aws-cdk/aws-docdb/package.json

+4
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,19 @@
8484
"dependencies": {
8585
"@aws-cdk/aws-ec2": "0.0.0",
8686
"@aws-cdk/aws-efs": "0.0.0",
87+
"@aws-cdk/aws-iam": "0.0.0",
8788
"@aws-cdk/aws-kms": "0.0.0",
89+
"@aws-cdk/aws-logs": "0.0.0",
8890
"@aws-cdk/aws-secretsmanager": "0.0.0",
8991
"@aws-cdk/core": "0.0.0",
9092
"constructs": "^3.3.69"
9193
},
9294
"peerDependencies": {
9395
"@aws-cdk/aws-ec2": "0.0.0",
9496
"@aws-cdk/aws-efs": "0.0.0",
97+
"@aws-cdk/aws-iam": "0.0.0",
9598
"@aws-cdk/aws-kms": "0.0.0",
99+
"@aws-cdk/aws-logs": "0.0.0",
96100
"@aws-cdk/aws-secretsmanager": "0.0.0",
97101
"@aws-cdk/core": "0.0.0",
98102
"constructs": "^3.3.69"

packages/@aws-cdk/aws-docdb/test/cluster.test.ts

+41
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { expect as expectCDK, haveResource, ResourcePart, arrayWith, haveResourceLike, objectLike } from '@aws-cdk/assert-internal';
22
import * as ec2 from '@aws-cdk/aws-ec2';
33
import * as kms from '@aws-cdk/aws-kms';
4+
import * as logs from '@aws-cdk/aws-logs';
45
import * as cdk from '@aws-cdk/core';
56

67
import { ClusterParameterGroup, DatabaseCluster, DatabaseSecret } from '../lib';
@@ -652,6 +653,46 @@ describe('DatabaseCluster', () => {
652653
}));
653654
});
654655

656+
test('can set CloudWatch log retention', () => {
657+
// GIVEN
658+
const stack = testStack();
659+
const vpc = new ec2.Vpc(stack, 'VPC');
660+
661+
// WHEN
662+
new DatabaseCluster(stack, 'Database', {
663+
masterUser: {
664+
username: 'admin',
665+
},
666+
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL),
667+
vpc,
668+
exportAuditLogsToCloudWatch: true,
669+
exportProfilerLogsToCloudWatch: true,
670+
cloudWatchLogsRetention: logs.RetentionDays.THREE_MONTHS,
671+
});
672+
673+
// THEN
674+
expectCDK(stack).to(haveResource('Custom::LogRetention', {
675+
ServiceToken: {
676+
'Fn::GetAtt': [
677+
'LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A',
678+
'Arn',
679+
],
680+
},
681+
LogGroupName: { 'Fn::Join': ['', ['/aws/docdb/', { Ref: 'DatabaseB269D8BB' }, '/audit']] },
682+
RetentionInDays: 90,
683+
}));
684+
expectCDK(stack).to(haveResource('Custom::LogRetention', {
685+
ServiceToken: {
686+
'Fn::GetAtt': [
687+
'LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A',
688+
'Arn',
689+
],
690+
},
691+
LogGroupName: { 'Fn::Join': ['', ['/aws/docdb/', { Ref: 'DatabaseB269D8BB' }, '/profiler']] },
692+
RetentionInDays: 90,
693+
}));
694+
});
695+
655696
test('single user rotation', () => {
656697
// GIVEN
657698
const stack = testStack();

0 commit comments

Comments
 (0)