Skip to content

Commit

Permalink
fix(secretsmanager): cannot set hourly rotation (#28303)
Browse files Browse the repository at this point in the history
Allows to set hourly rotation up to 4 hours on secrets as per [official docs](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotate-secrets_managed.html).

Closes #28261.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
lpizzinidev authored Dec 14, 2023
1 parent be38982 commit 09cb003
Show file tree
Hide file tree
Showing 23 changed files with 141 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@
]
},
"RotationRules": {
"AutomaticallyAfterDays": 30
"ScheduleExpression": "rate(30 days)"
},
"SecretId": {
"Ref": "DatabaseSecretAttachmentE5D1B020"
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@
]
},
"RotationRules": {
"AutomaticallyAfterDays": 30
"ScheduleExpression": "rate(30 days)"
},
"SecretId": {
"Ref": "DatabaseSecretAttachmentE5D1B020"
Expand Down Expand Up @@ -920,7 +920,7 @@
]
},
"RotationRules": {
"AutomaticallyAfterDays": 7
"ScheduleExpression": "rate(7 days)"
},
"SecretId": {
"Ref": "CustomRotationOptionsSecretAttachment697A23BF"
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -1403,7 +1403,7 @@
]
},
"RotationRules": {
"AutomaticallyAfterDays": 30
"ScheduleExpression": "rate(30 days)"
},
"SecretId": {
"Ref": "FromSnapshotSnapshotSecretAttachmentA3F619B8"
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@
]
},
"RotationRules": {
"AutomaticallyAfterDays": 30
"ScheduleExpression": "rate(30 days)"
},
"SecretId": {
"Ref": "InstanceSecretAttachment83BEE581"
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"RotationType": "MySQLSingleUser"
},
"RotationRules": {
"AutomaticallyAfterDays": 30
"ScheduleExpression": "rate(30 days)"
}
}
},
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"RotationType": "MySQLSingleUser"
},
"RotationRules": {
"AutomaticallyAfterDays": 30
"ScheduleExpression": "rate(30 days)"
}
}
},
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"RotationType": "MySQLSingleUser"
},
"RotationRules": {
"AutomaticallyAfterDays": 30
"ScheduleExpression": "rate(30 days)"
}
}
},
Expand Down Expand Up @@ -84,7 +84,7 @@
},
"RotateImmediatelyOnUpdate": false,
"RotationRules": {
"AutomaticallyAfterDays": 30
"ScheduleExpression": "rate(30 days)"
}
}
},
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
]
},
"RotationRules": {
"AutomaticallyAfterDays": 30
"ScheduleExpression": "rate(4 hours)"
},
"SecretId": {
"Ref": "SecretA720EF05"
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class TestStack extends cdk.Stack {
handler: 'index.handler',
code: lambda.Code.fromInline('NOOP'),
}),
automaticallyAfter: cdk.Duration.hours(4),
});
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/aws-cdk-lib/aws-docdb/test/cluster.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ describe('DatabaseCluster', () => {
'Fn::GetAtt': ['DatabaseRotationSingleUser65F55654', 'Outputs.RotationLambdaARN'],
},
RotationRules: {
AutomaticallyAfterDays: 5,
ScheduleExpression: 'rate(5 days)',
},
});
});
Expand Down Expand Up @@ -899,7 +899,7 @@ describe('DatabaseCluster', () => {
'Fn::GetAtt': ['DatabaseRotation6B6E1D86', 'Outputs.RotationLambdaARN'],
},
RotationRules: {
AutomaticallyAfterDays: 5,
ScheduleExpression: 'rate(5 days)',
},
});
});
Expand Down
16 changes: 8 additions & 8 deletions packages/aws-cdk-lib/aws-rds/test/cluster.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1975,7 +1975,7 @@ describe('cluster', () => {
],
},
RotationRules: {
AutomaticallyAfterDays: 30,
ScheduleExpression: 'rate(30 days)',
},
});
});
Expand Down Expand Up @@ -2006,7 +2006,7 @@ describe('cluster', () => {
],
},
RotationRules: {
AutomaticallyAfterDays: 30,
ScheduleExpression: 'rate(30 days)',
},
});

Expand Down Expand Up @@ -2058,7 +2058,7 @@ describe('cluster', () => {
// THEN
Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::RotationSchedule', {
RotationRules: {
AutomaticallyAfterDays: 15,
ScheduleExpression: 'rate(15 days)',
},
});

Expand Down Expand Up @@ -2125,7 +2125,7 @@ describe('cluster', () => {
// THEN
Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::RotationSchedule', {
RotationRules: {
AutomaticallyAfterDays: 15,
ScheduleExpression: 'rate(15 days)',
},
});

Expand Down Expand Up @@ -2231,7 +2231,7 @@ describe('cluster', () => {
],
},
RotationRules: {
AutomaticallyAfterDays: 30,
ScheduleExpression: 'rate(30 days)',
},
RotateImmediatelyOnUpdate: false,
});
Expand Down Expand Up @@ -2266,7 +2266,7 @@ describe('cluster', () => {
],
},
RotationRules: {
AutomaticallyAfterDays: 30,
ScheduleExpression: 'rate(30 days)',
},
RotateImmediatelyOnUpdate: false,
});
Expand Down Expand Up @@ -3439,7 +3439,7 @@ describe('cluster', () => {
// THEN
Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::RotationSchedule', {
RotationRules: {
AutomaticallyAfterDays: 30,
ScheduleExpression: 'rate(30 days)',
},
});
});
Expand Down Expand Up @@ -3493,7 +3493,7 @@ describe('cluster', () => {
],
},
RotationRules: {
AutomaticallyAfterDays: 30,
ScheduleExpression: 'rate(30 days)',
},
});

Expand Down
8 changes: 4 additions & 4 deletions packages/aws-cdk-lib/aws-rds/test/instance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ describe('instance', () => {
],
},
RotationRules: {
AutomaticallyAfterDays: 30,
ScheduleExpression: 'rate(30 days)',
},
});
});
Expand Down Expand Up @@ -810,7 +810,7 @@ describe('instance', () => {
],
},
RotationRules: {
AutomaticallyAfterDays: 30,
ScheduleExpression: 'rate(30 days)',
},
});

Expand Down Expand Up @@ -858,7 +858,7 @@ describe('instance', () => {
// THEN
Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::RotationSchedule', {
RotationRules: {
AutomaticallyAfterDays: 15,
ScheduleExpression: 'rate(15 days)',
},
});

Expand Down Expand Up @@ -921,7 +921,7 @@ describe('instance', () => {
// THEN
Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::RotationSchedule', {
RotationRules: {
AutomaticallyAfterDays: 15,
ScheduleExpression: 'rate(15 days)',
},
});

Expand Down
28 changes: 19 additions & 9 deletions packages/aws-cdk-lib/aws-secretsmanager/lib/rotation-schedule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Construct } from 'constructs';
import { ISecret, Secret } from './secret';
import { CfnRotationSchedule } from './secretsmanager.generated';
import * as ec2 from '../../aws-ec2';
import { Schedule } from '../../aws-events';
import * as iam from '../../aws-iam';
import * as kms from '../../aws-kms';
import * as lambda from '../../aws-lambda';
Expand Down Expand Up @@ -37,6 +38,7 @@ export interface RotationScheduleOptions {
* Specifies the number of days after the previous rotation before
* Secrets Manager triggers the next automatic rotation.
*
* The minimum value is 4 hours.
* The maximum value is 1000 days.
*
* A value of zero (`Duration.days(0)`) will not create RotationRules.
Expand Down Expand Up @@ -126,18 +128,26 @@ export class RotationSchedule extends Resource {
);
}

let automaticallyAfterDays: number | undefined = undefined;
if (props.automaticallyAfter && props.automaticallyAfter.toDays() > 1000) {
throw new Error(`automaticallyAfter must not be greater than 1000 days, got ${props.automaticallyAfter.toDays()} days`);
}
if (props.automaticallyAfter?.toMilliseconds() !== 0) {
automaticallyAfterDays = props.automaticallyAfter?.toDays() || 30;
let scheduleExpression: string | undefined;
if (props.automaticallyAfter) {
const automaticallyAfterMillis = props.automaticallyAfter.toMilliseconds();
if (automaticallyAfterMillis > 0) {
if (automaticallyAfterMillis < Duration.hours(4).toMilliseconds()) {
throw new Error(`automaticallyAfter must not be smaller than 4 hours, got ${props.automaticallyAfter.toHours()} hours`);
}
if (automaticallyAfterMillis > Duration.days(1000).toMilliseconds()) {
throw new Error(`automaticallyAfter must not be greater than 1000 days, got ${props.automaticallyAfter.toDays()} days`);
}
scheduleExpression = Schedule.rate(props.automaticallyAfter).expressionString;
}
} else {
scheduleExpression = Schedule.rate(Duration.days(30)).expressionString;
}

let rotationRules: CfnRotationSchedule.RotationRulesProperty | undefined = undefined;
if (automaticallyAfterDays !== undefined) {
let rotationRules: CfnRotationSchedule.RotationRulesProperty | undefined;
if (scheduleExpression) {
rotationRules = {
automaticallyAfterDays,
scheduleExpression,
};
}

Expand Down
Loading

0 comments on commit 09cb003

Please sign in to comment.