diff --git a/packages/@aws-cdk/aws-rds/README.md b/packages/@aws-cdk/aws-rds/README.md index 703e205705f37..318f0c9b7a683 100644 --- a/packages/@aws-cdk/aws-rds/README.md +++ b/packages/@aws-cdk/aws-rds/README.md @@ -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 for setup instructions. diff --git a/packages/@aws-cdk/aws-rds/lib/proxy.ts b/packages/@aws-cdk/aws-rds/lib/proxy.ts index e7468871758a3..5d986f08f17be 100644 --- a/packages/@aws-cdk/aws-rds/lib/proxy.ts +++ b/packages/@aws-cdk/aws-rds/lib/proxy.ts @@ -315,6 +315,29 @@ 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], + }); + } } /** @@ -322,8 +345,8 @@ export interface IDatabaseProxy extends cdk.IResource { * * @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. */ @@ -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; diff --git a/packages/@aws-cdk/aws-rds/test/test.proxy.ts b/packages/@aws-cdk/aws-rds/test/test.proxy.ts index db57aaf4d8b93..73068f8953778 100644 --- a/packages/@aws-cdk/aws-rds/test/test.proxy.ts +++ b/packages/@aws-cdk/aws-rds/test/test.proxy.ts @@ -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'; @@ -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(); + }, };