Skip to content

Commit

Permalink
feat(rds): add grantConnect for RDS Proxy (#12243)
Browse files Browse the repository at this point in the history
Closes: #10133

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
saudkhanzada authored Dec 28, 2020
1 parent b8f48e5 commit eb45ca8
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 3 deletions.
18 changes: 18 additions & 0 deletions packages/@aws-cdk/aws-rds/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,24 @@ const role = new Role(stack, 'DBRole', { assumedBy: new AccountPrincipal(stack.a
instance.grantConnect(role); // Grant the role connection access to the DB.
```

The following example shows granting connection access for RDS Proxy to an IAM role.

```ts
const cluster = new rds.DatabaseCluster(stack, 'Database'{
engine: rds.DatabaseClusterEngine.AURORA,
instanceProps: { vpc },
});

const proxy = new rds.DatabaseProxy(stack, 'Proxy', {
proxyTarget: rds.ProxyTarget.fromCluster(cluster),
secrets: [cluster.secret!],
vpc,
});

const role = new Role(stack, 'DBProxyRole', { assumedBy: new AccountPrincipal(stack.account) });
proxy.grantConnect(role); // Grant the role connection access to the DB Proxy.
```

**Note**: In addition to the setup above, a database user will need to be created to support IAM auth.
See <https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.DBAccounts.html> for setup instructions.

Expand Down
29 changes: 26 additions & 3 deletions packages/@aws-cdk/aws-rds/lib/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,15 +315,38 @@ export interface IDatabaseProxy extends cdk.IResource {
* @attribute
*/
readonly endpoint: string;

/**
* Grant the given identity connection access to the proxy.
*/
grantConnect(grantee: iam.IGrantable): iam.Grant;
}

/**
* Represents an RDS Database Proxy.
*
*/
abstract class DatabaseProxyBase extends cdk.Resource implements IDatabaseProxy {
public abstract readonly dbProxyName: string;
public abstract readonly dbProxyArn: string;
public abstract readonly endpoint: string;

public grantConnect(grantee: iam.IGrantable): iam.Grant {
return iam.Grant.addToPrincipal({
grantee,
actions: ['rds-db:connect'],
resourceArns: [this.dbProxyArn],
});
}
}

/**
* RDS Database Proxy
*
* @resource AWS::RDS::DBProxy
*/
export class DatabaseProxy extends cdk.Resource
implements IDatabaseProxy, ec2.IConnectable, secretsmanager.ISecretAttachmentTarget {
export class DatabaseProxy extends DatabaseProxyBase
implements ec2.IConnectable, secretsmanager.ISecretAttachmentTarget {
/**
* Import an existing database proxy.
*/
Expand All @@ -332,7 +355,7 @@ export class DatabaseProxy extends cdk.Resource
id: string,
attrs: DatabaseProxyAttributes,
): IDatabaseProxy {
class Import extends cdk.Resource implements IDatabaseProxy {
class Import extends DatabaseProxyBase {
public readonly dbProxyName = attrs.dbProxyName;
public readonly dbProxyArn = attrs.dbProxyArn;
public readonly endpoint = attrs.endpoint;
Expand Down
40 changes: 40 additions & 0 deletions packages/@aws-cdk/aws-rds/test/test.proxy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ABSENT, expect, haveResourceLike } from '@aws-cdk/assert';
import * as ec2 from '@aws-cdk/aws-ec2';
import { AccountPrincipal, Role } from '@aws-cdk/aws-iam';
import * as secretsmanager from '@aws-cdk/aws-secretsmanager';
import * as cdk from '@aws-cdk/core';
import { Test } from 'nodeunit';
Expand Down Expand Up @@ -223,4 +224,43 @@ export = {

test.done();
},

'grantConnect should add IAM Policy with action rds-db:connect'(test: Test) {
// GIVEN
const cluster = new rds.DatabaseCluster(stack, 'Database', {
engine: rds.DatabaseClusterEngine.AURORA,
instanceProps: { vpc },
});

const proxy = new rds.DatabaseProxy(stack, 'Proxy', {
proxyTarget: rds.ProxyTarget.fromCluster(cluster),
secrets: [cluster.secret!],
vpc,
});

// WHEN
const role = new Role(stack, 'DBProxyRole', {
assumedBy: new AccountPrincipal(stack.account),
});
proxy.grantConnect(role);

// THEN
expect(stack).to(haveResourceLike('AWS::IAM::Policy', {
PolicyDocument: {
Statement: [{
Effect: 'Allow',
Action: 'rds-db:connect',
Resource: {
'Fn::GetAtt': [
'ProxyCB0DFB71',
'DBProxyArn',
],
},
}],
Version: '2012-10-17',
},
}));

test.done();
},
};

0 comments on commit eb45ca8

Please sign in to comment.