1
1
import * as ec2 from '@aws-cdk/aws-ec2' ;
2
2
import * as iam from '@aws-cdk/aws-iam' ;
3
3
import * as kms from '@aws-cdk/aws-kms' ;
4
- import { Duration , IResource , RemovalPolicy , Resource , Token } from '@aws-cdk/core' ;
4
+ import { Aws , Duration , IResource , Lazy , RemovalPolicy , Resource , Token } from '@aws-cdk/core' ;
5
5
import { Construct } from 'constructs' ;
6
6
import { Endpoint } from './endpoint' ;
7
7
import { InstanceType } from './instance' ;
@@ -119,6 +119,13 @@ export interface DatabaseClusterProps {
119
119
*/
120
120
readonly dbClusterName ?: string ;
121
121
122
+ /**
123
+ * Map AWS Identity and Access Management (IAM) accounts to database accounts
124
+ *
125
+ * @default - `false`
126
+ */
127
+ readonly iamAuthentication ?: boolean ;
128
+
122
129
/**
123
130
* Base identifier for instances
124
131
*
@@ -233,6 +240,11 @@ export interface IDatabaseCluster extends IResource, ec2.IConnectable {
233
240
* @attribute ReadEndpoint
234
241
*/
235
242
readonly clusterReadEndpoint : Endpoint ;
243
+
244
+ /**
245
+ * Grant the given identity connection access to the database.
246
+ */
247
+ grantConnect ( grantee : iam . IGrantable ) : iam . Grant ;
236
248
}
237
249
238
250
/**
@@ -266,23 +278,15 @@ export interface DatabaseClusterAttributes {
266
278
}
267
279
268
280
/**
269
- * Create a clustered database with a given number of instances.
270
- *
271
- * @resource AWS::Neptune::DBCluster
281
+ * A new or imported database cluster.
272
282
*/
273
- export class DatabaseCluster extends Resource implements IDatabaseCluster {
274
-
275
- /**
276
- * The default number of instances in the Neptune cluster if none are
277
- * specified
278
- */
279
- public static readonly DEFAULT_NUM_INSTANCES = 1 ;
283
+ export abstract class DatabaseClusterBase extends Resource implements IDatabaseCluster {
280
284
281
285
/**
282
286
* Import an existing DatabaseCluster from properties
283
287
*/
284
288
public static fromDatabaseClusterAttributes ( scope : Construct , id : string , attrs : DatabaseClusterAttributes ) : IDatabaseCluster {
285
- class Import extends Resource implements IDatabaseCluster {
289
+ class Import extends DatabaseClusterBase implements IDatabaseCluster {
286
290
public readonly defaultPort = ec2 . Port . tcp ( attrs . port ) ;
287
291
public readonly connections = new ec2 . Connections ( {
288
292
securityGroups : [ attrs . securityGroup ] ,
@@ -291,6 +295,7 @@ export class DatabaseCluster extends Resource implements IDatabaseCluster {
291
295
public readonly clusterIdentifier = attrs . clusterIdentifier ;
292
296
public readonly clusterEndpoint = new Endpoint ( attrs . clusterEndpointAddress , attrs . port ) ;
293
297
public readonly clusterReadEndpoint = new Endpoint ( attrs . readerEndpointAddress , attrs . port ) ;
298
+ protected enableIamAuthentication = true ;
294
299
}
295
300
296
301
return new Import ( scope , id ) ;
@@ -299,17 +304,65 @@ export class DatabaseCluster extends Resource implements IDatabaseCluster {
299
304
/**
300
305
* Identifier of the cluster
301
306
*/
302
- public readonly clusterIdentifier : string ;
307
+ public abstract readonly clusterIdentifier : string ;
303
308
304
309
/**
305
310
* The endpoint to use for read/write operations
306
311
*/
307
- public readonly clusterEndpoint : Endpoint ;
312
+ public abstract readonly clusterEndpoint : Endpoint ;
308
313
309
314
/**
310
315
* Endpoint to use for load-balanced read-only operations.
311
316
*/
317
+ public abstract readonly clusterReadEndpoint : Endpoint ;
318
+
319
+ /**
320
+ * The connections object to implement IConnectable
321
+ */
322
+ public abstract readonly connections : ec2 . Connections ;
323
+
324
+ protected abstract enableIamAuthentication ?: boolean ;
325
+
326
+ public grantConnect ( grantee : iam . IGrantable ) : iam . Grant {
327
+ if ( this . enableIamAuthentication === false ) {
328
+ throw new Error ( 'Cannot grant connect when IAM authentication is disabled' ) ;
329
+ }
330
+
331
+ this . enableIamAuthentication = true ;
332
+ return iam . Grant . addToPrincipal ( {
333
+ grantee,
334
+ actions : [ 'neptune-db:*' ] ,
335
+ resourceArns : [
336
+ [
337
+ 'arn' ,
338
+ Aws . PARTITION ,
339
+ 'neptune-db' ,
340
+ Aws . REGION ,
341
+ Aws . ACCOUNT_ID ,
342
+ `${ this . clusterIdentifier } /*` ,
343
+ ] . join ( ':' ) ,
344
+ ] ,
345
+ } ) ;
346
+ }
347
+ }
348
+
349
+ /**
350
+ * Create a clustered database with a given number of instances.
351
+ *
352
+ * @resource AWS::Neptune::DBCluster
353
+ */
354
+ export class DatabaseCluster extends DatabaseClusterBase implements IDatabaseCluster {
355
+
356
+ /**
357
+ * The default number of instances in the Neptune cluster if none are
358
+ * specified
359
+ */
360
+ public static readonly DEFAULT_NUM_INSTANCES = 1 ;
361
+
362
+ public readonly clusterIdentifier : string ;
363
+ public readonly clusterEndpoint : Endpoint ;
312
364
public readonly clusterReadEndpoint : Endpoint ;
365
+ public readonly connections : ec2 . Connections ;
313
366
314
367
/**
315
368
* The resource id for the cluster; for example: cluster-ABCD1234EFGH5678IJKL90MNOP. The cluster ID uniquely
@@ -318,11 +371,6 @@ export class DatabaseCluster extends Resource implements IDatabaseCluster {
318
371
*/
319
372
public readonly clusterResourceIdentifier : string ;
320
373
321
- /**
322
- * The connections object to implement IConectable
323
- */
324
- public readonly connections : ec2 . Connections ;
325
-
326
374
/**
327
375
* The VPC where the DB subnet group is created.
328
376
*/
@@ -348,6 +396,8 @@ export class DatabaseCluster extends Resource implements IDatabaseCluster {
348
396
*/
349
397
public readonly instanceEndpoints : Endpoint [ ] = [ ] ;
350
398
399
+ protected enableIamAuthentication ?: boolean ;
400
+
351
401
constructor ( scope : Construct , id : string , props : DatabaseClusterProps ) {
352
402
super ( scope , id ) ;
353
403
@@ -385,6 +435,8 @@ export class DatabaseCluster extends Resource implements IDatabaseCluster {
385
435
386
436
const deletionProtection = props . deletionProtection ?? ( props . removalPolicy === RemovalPolicy . RETAIN ? true : undefined ) ;
387
437
438
+ this . enableIamAuthentication = props . iamAuthentication ;
439
+
388
440
// Create the Neptune cluster
389
441
const cluster = new CfnDBCluster ( this , 'Resource' , {
390
442
// Basic
@@ -396,6 +448,7 @@ export class DatabaseCluster extends Resource implements IDatabaseCluster {
396
448
dbClusterParameterGroupName : props . clusterParameterGroup ?. clusterParameterGroupName ,
397
449
deletionProtection : deletionProtection ,
398
450
associatedRoles : props . associatedRoles ? props . associatedRoles . map ( role => ( { roleArn : role . roleArn } ) ) : undefined ,
451
+ iamAuthEnabled : Lazy . any ( { produce : ( ) => this . enableIamAuthentication } ) ,
399
452
// Backup
400
453
backupRetentionPeriod : props . backupRetention ?. toDays ( ) ,
401
454
preferredBackupWindow : props . preferredBackupWindow ,
0 commit comments