@@ -47,6 +47,14 @@ export interface IDatabaseInstance extends IResource, ec2.IConnectable, secretsm
47
47
*/
48
48
readonly dbInstanceEndpointPort : string ;
49
49
50
+ /**
51
+ * The AWS Region-unique, immutable identifier for the DB instance.
52
+ * This identifier is found in AWS CloudTrail log entries whenever the AWS KMS key for the DB instance is accessed.
53
+ *
54
+ * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-dbinstance.html#aws-resource-rds-dbinstance-return-values
55
+ */
56
+ readonly instanceResourceId ?: string ;
57
+
50
58
/**
51
59
* The instance endpoint.
52
60
*/
@@ -66,10 +74,11 @@ export interface IDatabaseInstance extends IResource, ec2.IConnectable, secretsm
66
74
67
75
/**
68
76
* Grant the given identity connection access to the database.
69
- * **Note**: this method does not currently work, see https://github.com/aws/aws-cdk/issues/11851 for details.
70
- * @see https://github.com/aws/aws-cdk/issues/11851
77
+ *
78
+ * @param grantee the Principal to grant the permissions to
79
+ * @param dbUser the name of the database user to allow connecting as to the db instance
71
80
*/
72
- grantConnect ( grantee : iam . IGrantable ) : iam . Grant ;
81
+ grantConnect ( grantee : iam . IGrantable , dbUser ?: string ) : iam . Grant ;
73
82
74
83
/**
75
84
* Defines a CloudWatch event rule which triggers for instance events. Use
@@ -97,6 +106,14 @@ export interface DatabaseInstanceAttributes {
97
106
*/
98
107
readonly port : number ;
99
108
109
+ /**
110
+ * The AWS Region-unique, immutable identifier for the DB instance.
111
+ * This identifier is found in AWS CloudTrail log entries whenever the AWS KMS key for the DB instance is accessed.
112
+ *
113
+ * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-dbinstance.html#aws-resource-rds-dbinstance-return-values
114
+ */
115
+ readonly instanceResourceId ?: string ;
116
+
100
117
/**
101
118
* The security groups of the instance.
102
119
*/
@@ -130,6 +147,7 @@ export abstract class DatabaseInstanceBase extends Resource implements IDatabase
130
147
public readonly instanceEndpoint = new Endpoint ( attrs . instanceEndpointAddress , attrs . port ) ;
131
148
public readonly engine = attrs . engine ;
132
149
protected enableIamAuthentication = true ;
150
+ public readonly instanceResourceId = attrs . instanceResourceId ;
133
151
}
134
152
135
153
return new Import ( scope , id ) ;
@@ -138,6 +156,7 @@ export abstract class DatabaseInstanceBase extends Resource implements IDatabase
138
156
public abstract readonly instanceIdentifier : string ;
139
157
public abstract readonly dbInstanceEndpointAddress : string ;
140
158
public abstract readonly dbInstanceEndpointPort : string ;
159
+ public abstract readonly instanceResourceId ?: string ;
141
160
public abstract readonly instanceEndpoint : Endpoint ;
142
161
// only required because of JSII bug: https://github.com/aws/jsii/issues/2040
143
162
public abstract readonly engine ?: IInstanceEngine ;
@@ -158,16 +177,33 @@ export abstract class DatabaseInstanceBase extends Resource implements IDatabase
158
177
} ) ;
159
178
}
160
179
161
- public grantConnect ( grantee : iam . IGrantable ) : iam . Grant {
180
+ public grantConnect ( grantee : iam . IGrantable , dbUser ?: string ) : iam . Grant {
162
181
if ( this . enableIamAuthentication === false ) {
163
182
throw new Error ( 'Cannot grant connect when IAM authentication is disabled' ) ;
164
183
}
165
184
185
+ if ( ! this . instanceResourceId ) {
186
+ throw new Error ( 'For imported Database Instances, instanceResourceId is required to grantConnect()' ) ;
187
+ }
188
+
189
+ if ( ! dbUser ) {
190
+ throw new Error ( 'For imported Database Instances, the dbUser is required to grantConnect()' ) ;
191
+ }
192
+
166
193
this . enableIamAuthentication = true ;
167
194
return iam . Grant . addToPrincipal ( {
168
195
grantee,
169
196
actions : [ 'rds-db:connect' ] ,
170
- resourceArns : [ this . instanceArn ] ,
197
+ resourceArns : [
198
+ // The ARN of an IAM policy for IAM database access is not the same as the instance ARN, so we cannot use `this.instanceArn`.
199
+ // See https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html
200
+ Stack . of ( this ) . formatArn ( {
201
+ arnFormat : ArnFormat . COLON_RESOURCE_NAME ,
202
+ service : 'rds-db' ,
203
+ resource : 'dbuser' ,
204
+ resourceName : [ this . instanceResourceId , dbUser ] . join ( '/' ) ,
205
+ } ) ,
206
+ ] ,
171
207
} ) ;
172
208
}
173
209
@@ -1029,6 +1065,26 @@ abstract class DatabaseInstanceSource extends DatabaseInstanceNew implements IDa
1029
1065
target : this ,
1030
1066
} ) ;
1031
1067
}
1068
+
1069
+ /**
1070
+ * Grant the given identity connection access to the database.
1071
+ *
1072
+ * @param grantee the Principal to grant the permissions to
1073
+ * @param dbUser the name of the database user to allow connecting as to the db instance
1074
+ *
1075
+ * @default the default user, obtained from the Secret
1076
+ */
1077
+ public grantConnect ( grantee : iam . IGrantable , dbUser ?: string ) : iam . Grant {
1078
+ if ( ! dbUser ) {
1079
+ if ( ! this . secret ) {
1080
+ throw new Error ( 'A secret or dbUser is required to grantConnect()' ) ;
1081
+ }
1082
+
1083
+ dbUser = this . secret . secretValueFromJson ( 'username' ) . toString ( ) ;
1084
+ }
1085
+
1086
+ return super . grantConnect ( grantee , dbUser ) ;
1087
+ }
1032
1088
}
1033
1089
1034
1090
/**
@@ -1074,6 +1130,7 @@ export class DatabaseInstance extends DatabaseInstanceSource implements IDatabas
1074
1130
public readonly instanceIdentifier : string ;
1075
1131
public readonly dbInstanceEndpointAddress : string ;
1076
1132
public readonly dbInstanceEndpointPort : string ;
1133
+ public readonly instanceResourceId ?: string ;
1077
1134
public readonly instanceEndpoint : Endpoint ;
1078
1135
public readonly secret ?: secretsmanager . ISecret ;
1079
1136
@@ -1095,6 +1152,7 @@ export class DatabaseInstance extends DatabaseInstanceSource implements IDatabas
1095
1152
this . instanceIdentifier = this . getResourceNameAttribute ( instance . ref ) ;
1096
1153
this . dbInstanceEndpointAddress = instance . attrEndpointAddress ;
1097
1154
this . dbInstanceEndpointPort = instance . attrEndpointPort ;
1155
+ this . instanceResourceId = instance . attrDbiResourceId ;
1098
1156
1099
1157
// create a number token that represents the port of the instance
1100
1158
const portAttribute = Token . asNumber ( instance . attrEndpointPort ) ;
@@ -1141,6 +1199,7 @@ export class DatabaseInstanceFromSnapshot extends DatabaseInstanceSource impleme
1141
1199
public readonly instanceIdentifier : string ;
1142
1200
public readonly dbInstanceEndpointAddress : string ;
1143
1201
public readonly dbInstanceEndpointPort : string ;
1202
+ public readonly instanceResourceId ?: string ;
1144
1203
public readonly instanceEndpoint : Endpoint ;
1145
1204
public readonly secret ?: secretsmanager . ISecret ;
1146
1205
@@ -1172,6 +1231,7 @@ export class DatabaseInstanceFromSnapshot extends DatabaseInstanceSource impleme
1172
1231
this . instanceIdentifier = instance . ref ;
1173
1232
this . dbInstanceEndpointAddress = instance . attrEndpointAddress ;
1174
1233
this . dbInstanceEndpointPort = instance . attrEndpointPort ;
1234
+ this . instanceResourceId = instance . attrDbiResourceId ;
1175
1235
1176
1236
// create a number token that represents the port of the instance
1177
1237
const portAttribute = Token . asNumber ( instance . attrEndpointPort ) ;
@@ -1229,6 +1289,7 @@ export class DatabaseInstanceReadReplica extends DatabaseInstanceNew implements
1229
1289
public readonly instanceIdentifier : string ;
1230
1290
public readonly dbInstanceEndpointAddress : string ;
1231
1291
public readonly dbInstanceEndpointPort : string ;
1292
+ public readonly instanceResourceId ?: string ;
1232
1293
public readonly instanceEndpoint : Endpoint ;
1233
1294
public readonly engine ?: IInstanceEngine = undefined ;
1234
1295
protected readonly instanceType : ec2 . InstanceType ;
@@ -1260,6 +1321,7 @@ export class DatabaseInstanceReadReplica extends DatabaseInstanceNew implements
1260
1321
this . instanceIdentifier = instance . ref ;
1261
1322
this . dbInstanceEndpointAddress = instance . attrEndpointAddress ;
1262
1323
this . dbInstanceEndpointPort = instance . attrEndpointPort ;
1324
+ this . instanceResourceId = instance . attrDbInstanceArn ;
1263
1325
1264
1326
// create a number token that represents the port of the instance
1265
1327
const portAttribute = Token . asNumber ( instance . attrEndpointPort ) ;
0 commit comments