Skip to content

Commit

Permalink
feat(rds): use user-defined security group for db user rotation funct…
Browse files Browse the repository at this point in the history
…ion (#23087)

closes #23086 

----

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
clueleaf authored Nov 29, 2022
1 parent 69e6978 commit 9d8f69e
Show file tree
Hide file tree
Showing 11 changed files with 1,269 additions and 42 deletions.
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-rds/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,11 @@ When the master password is generated and stored in AWS Secrets Manager, it can
import * as cdk from '@aws-cdk/core';

declare const instance: rds.DatabaseInstance;
declare const mySecurityGroup: ec2.SecurityGroup;
instance.addRotationSingleUser({
automaticallyAfter: cdk.Duration.days(7), // defaults to 30 days
excludeCharacters: '!@#$%^&*', // defaults to the set " %+~`#$&*()|[]{}:;<>?!'/@\"\\"
securityGroup: mySecurityGroup, // defaults to an auto-created security group
});
```

Expand Down
7 changes: 7 additions & 0 deletions packages/@aws-cdk/aws-rds/lib/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,13 @@ export interface CommonRotationUserOptions {
* @default https://secretsmanager.<region>.amazonaws.com
*/
readonly endpoint?: ec2.IInterfaceVpcEndpoint;

/**
* The security group for the Lambda rotation function
*
* @default - a new security group is created
*/
readonly securityGroup?: ec2.ISecurityGroup;
}

/**
Expand Down
24 changes: 22 additions & 2 deletions packages/@aws-cdk/aws-rds/test/cluster.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,7 @@ describe('cluster', () => {
});
});

test('addRotationSingleUser() with custom automaticallyAfter, excludeCharacters and vpcSubnets', () => {
test('addRotationSingleUser() with custom automaticallyAfter, excludeCharacters, vpcSubnets and securityGroup', () => {
// GIVEN
const stack = new cdk.Stack();
const vpcWithIsolated = ec2.Vpc.fromVpcAttributes(stack, 'Vpc', {
Expand All @@ -967,6 +967,9 @@ describe('cluster', () => {
isolatedSubnetIds: ['isolated-subnet-id-1', 'isolated-subnet-id-2'],
isolatedSubnetNames: ['isolated-subnet-name-1', 'isolated-subnet-name-2'],
});
const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup', {
vpc: vpcWithIsolated,
});

// WHEN
// DB in isolated subnet (no internet connectivity)
Expand All @@ -984,6 +987,7 @@ describe('cluster', () => {
automaticallyAfter: cdk.Duration.days(15),
excludeCharacters: '°_@',
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
securityGroup,
});

// THEN
Expand All @@ -1005,11 +1009,17 @@ describe('cluster', () => {
},
vpcSubnetIds: 'private-subnet-id-1,private-subnet-id-2',
excludeCharacters: '°_@',
vpcSecurityGroupIds: {
'Fn::GetAtt': [
stack.getLogicalId(securityGroup.node.defaultChild as ec2.CfnSecurityGroup),
'GroupId',
],
},
},
});
});

test('addRotationMultiUser() with custom automaticallyAfter, excludeCharacters and vpcSubnets', () => {
test('addRotationMultiUser() with custom automaticallyAfter, excludeCharacters, vpcSubnets and securityGroup', () => {
// GIVEN
const stack = new cdk.Stack();
const vpcWithIsolated = ec2.Vpc.fromVpcAttributes(stack, 'Vpc', {
Expand All @@ -1022,6 +1032,9 @@ describe('cluster', () => {
isolatedSubnetIds: ['isolated-subnet-id-1', 'isolated-subnet-id-2'],
isolatedSubnetNames: ['isolated-subnet-name-1', 'isolated-subnet-name-2'],
});
const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup', {
vpc: vpcWithIsolated,
});
const userSecret = new DatabaseSecret(stack, 'UserSecret', { username: 'user' });

// WHEN
Expand All @@ -1041,6 +1054,7 @@ describe('cluster', () => {
automaticallyAfter: cdk.Duration.days(15),
excludeCharacters: '°_@',
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
securityGroup,
});

// THEN
Expand All @@ -1062,6 +1076,12 @@ describe('cluster', () => {
},
vpcSubnetIds: 'private-subnet-id-1,private-subnet-id-2',
excludeCharacters: '°_@',
vpcSecurityGroupIds: {
'Fn::GetAtt': [
stack.getLogicalId(securityGroup.node.defaultChild as ec2.CfnSecurityGroup),
'GroupId',
],
},
},
});
});
Expand Down
24 changes: 22 additions & 2 deletions packages/@aws-cdk/aws-rds/test/instance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,7 @@ describe('instance', () => {
});
});

test('addRotationSingleUser() with custom automaticallyAfter, excludeCharacters and vpcSubnets', () => {
test('addRotationSingleUser() with custom automaticallyAfter, excludeCharacters, vpcSubnets and securityGroup', () => {
// GIVEN
const vpcWithIsolated = ec2.Vpc.fromVpcAttributes(stack, 'Vpc', {
vpcId: 'vpc-id',
Expand All @@ -835,6 +835,9 @@ describe('instance', () => {
isolatedSubnetIds: ['isolated-subnet-id-1', 'isolated-subnet-id-2'],
isolatedSubnetNames: ['isolated-subnet-name-1', 'isolated-subnet-name-2'],
});
const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup', {
vpc: vpcWithIsolated,
});

// WHEN
// DB in isolated subnet (no internet connectivity)
Expand All @@ -849,6 +852,7 @@ describe('instance', () => {
automaticallyAfter: cdk.Duration.days(15),
excludeCharacters: '°_@',
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
securityGroup,
});

// THEN
Expand All @@ -870,11 +874,17 @@ describe('instance', () => {
},
vpcSubnetIds: 'private-subnet-id-1,private-subnet-id-2',
excludeCharacters: '°_@',
vpcSecurityGroupIds: {
'Fn::GetAtt': [
stack.getLogicalId(securityGroup.node.defaultChild as ec2.CfnSecurityGroup),
'GroupId',
],
},
},
});
});

test('addRotationMultiUser() with custom automaticallyAfter, excludeCharacters and vpcSubnets', () => {
test('addRotationMultiUser() with custom automaticallyAfter, excludeCharacters, vpcSubnets and securityGroup', () => {
// GIVEN
const vpcWithIsolated = ec2.Vpc.fromVpcAttributes(stack, 'Vpc', {
vpcId: 'vpc-id',
Expand All @@ -886,6 +896,9 @@ describe('instance', () => {
isolatedSubnetIds: ['isolated-subnet-id-1', 'isolated-subnet-id-2'],
isolatedSubnetNames: ['isolated-subnet-name-1', 'isolated-subnet-name-2'],
});
const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup', {
vpc: vpcWithIsolated,
});
const userSecret = new rds.DatabaseSecret(stack, 'UserSecret', { username: 'user' });

// WHEN
Expand All @@ -902,6 +915,7 @@ describe('instance', () => {
automaticallyAfter: cdk.Duration.days(15),
excludeCharacters: '°_@',
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
securityGroup,
});

// THEN
Expand All @@ -923,6 +937,12 @@ describe('instance', () => {
},
vpcSubnetIds: 'private-subnet-id-1,private-subnet-id-2',
excludeCharacters: '°_@',
vpcSecurityGroupIds: {
'Fn::GetAtt': [
stack.getLogicalId(securityGroup.node.defaultChild as ec2.CfnSecurityGroup),
'GroupId',
],
},
},
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"version": "20.0.0",
"version": "21.0.0",
"files": {
"b5d2442773f45a1a63e67895776106093341355451336b5073275c46364c618e": {
"dfc2f8e8aa2f2f42357312f7f92524a12cb383c762b91eaecbbefb8ad8400f82": {
"source": {
"path": "aws-cdk-rds-cluster-rotation.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "b5d2442773f45a1a63e67895776106093341355451336b5073275c46364c618e.json",
"objectKey": "dfc2f8e8aa2f2f42357312f7f92524a12cb383c762b91eaecbbefb8ad8400f82.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
Expand Down
Loading

0 comments on commit 9d8f69e

Please sign in to comment.