aws / aws/aws-cdk

(aws-rds): Add support to `DatabaseCluster` to support `iam-db-auth` for masterUsername user.

Open
#37,658 5 comments 0 reactions 0 assignees View on GitHub
@aws-cdk/aws-rds effort/medium feature-request p2
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
2d 3h
Merged PRs (30d)
83

Description

### Describe the feature

Using the `aws cli` one can create an AWS Aurora Serverless V2 Postgres cluster that utilizes IAM Authentication for the `master-username`.

```
# Create the cluster with IAM-only master auth
aws rds create-db-cluster \
--db-cluster-identifier my-aurora-cluster \
--engine aurora-postgresql \
--region us-west-2 \
--master-username postgres \
--master-user-authentication-type iam-db-auth \
--enable-iam-database-authentication

# Set scaling policy
aws rds modify-db-cluster \
--db-cluster-identifier my-aurora-cluster \
--serverless-v2-scaling-configuration MinCapacity=0.5,MaxCapacity=2 \
--region us-west-2

# Add a Serverless v2 writer instance
aws rds create-db-instance \
--db-instance-identifier my-aurora-cluster-writer \
--db-cluster-identifier my-aurora-cluster \
--engine aurora-postgresql \
--db-instance-class db.serverless \
--region us-west-2
```

This can be replicated using `aws-cdk` with the L1 constructs:

```
import { App, Stack, RemovalPolicy } from 'aws-cdk-lib';
import { CfnDBCluster, CfnDBInstance, CfnDBSubnetGroup } from 'aws-cdk-lib/aws-rds';
import { Vpc, SecurityGroup } from 'aws-cdk-lib/aws-ec2';

const app = new App();
const stack = new Stack(app, 'L1-IamAuth', {
env: { account: 'YOUR-ACCOUNT-HERE', region: 'us-west-2' },
});

const vpc = Vpc.fromLookup(stack, 'Vpc', { vpcId: 'YOUR-VPC-HERE' });

const sg = new SecurityGroup(stack, 'DbSg', {
vpc,
description: 'Aurora cluster security group',
});

const subnetGroup = new CfnDBSubnetGroup(stack, 'SubnetGroup', {
dbSubnetGroupDescription: 'Subnets for IAM auth repro cluster',
subnetIds: vpc.privateSubnets.map(s => s.subnetId),
});

const cluster = new CfnDBCluster(stack, 'Cluster', {
engine: 'aurora-postgresql',
engineVersion: '17.5',
masterUsername: 'postgres',
masterUserAuthenticationType: 'iam-db-auth',
enableIamDatabaseAuthentication: true,
serverlessV2ScalingConfiguration: { minCapacity: 0.5, maxCapacity: 2 },
dbSubnetGroupName: subnetGroup.ref,
vpcSecurityGroupIds: [sg.securityGroupId],
storageEncrypted: true,
});
cluster.applyRemovalPolicy(RemovalPolicy.DESTROY);

const writer = new CfnDBInstance(stack, 'Writer', {
dbClusterIdentifier: cluster.ref,
dbInstanceClass: 'db.serverless',
engine: 'aurora-postgresql',
});
```

However there does not appear to be a functional way to use the L2 `DatabaseCluster` construct to achieve this same functionality. There is no `masterUserAuthenticationType` passed through in the [construct](https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/aws-rds/lib/cluster.ts#L1481).

```
const cluster = new DatabaseCluster(stack, 'DB', {
engine: DatabaseClusterEngine.auroraPostgres({
version: AuroraPostgresEngineVersion.VER_17_5,
}),
vpc,
writer: ClusterInstance.serverlessV2('writer'),
iamAuthentication: true,
defaultDatabaseName: 'repro',
removalPolicy: RemovalPolicy.DESTROY,
});
```

One can add a PropertyOverride:

```
const cfnCluster = cluster.node.defaultChild as CfnDBCluster;
cfnCluster.addPropertyOverride('MasterUserAuthenticationType', 'iam-db-auth');
```

However the `MasterUserPassword` is always set.

```
"DB4924F778": {
"Type": "AWS::RDS::DBCluster",
"Properties": {
"CopyTagsToSnapshot": true,
"DBClusterParameterGroupName": "default.aurora-postgresql17",
"DBSubnetGroupName": {
"Ref": "DBSubnets7B70DA43"
},
"EnableIAMDatabaseAuthentication": true,
"Engine": "aurora-postgresql",
"EngineVersion": "17.5",
"MasterUserAuthenticationType": "iam-db-auth",
"MasterUserPassword": {
"Fn::Join": [
"",
[
"{{resolve:secretsmanager:",
{
"Ref": "DBSecretB8D1B379"
},
":SecretString:password::}}"
]
]
},
```

It is possible to override the masterUserPassword to enable creating an RDS Cluster with the L2 construct and IAM Master user authentication.

```
const cfnCluster = this.databaseCluster.node.defaultChild as CfnDBCluster;
const origDescriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(cfnCluster), 'cfnProperties');
Object.defineProperty(cfnCluster, 'cfnProperties', {
get() {
const baseProps = origDescriptor?.get?.call(this) ?? {};
delete baseProps.masterUserPassword;
delete baseProps.manageMasterUserPassword;
baseProps.masterUserAuthenticationType = 'iam-db-auth';
return baseProps;
},
configurable: true,
});
```
### References

- https://docs.aws.amazon.com/cli/latest/reference/rds/create-db-cluster.html
- https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBCluster.html
- https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_rds-readme.html

### Use Case

Functional equivalency with the command line, and L1 construct should exist in the L2 construct.

### Proposed Solution

Allow a prop that can configure the master database user to use IAM, and not set the `MasterPassword` value (which is always set right now, as [renderCredentials](https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/aws-rds/lib/cluster.ts#L1486) will always set a password).

### Other Information

_No response_

### Acknowledgements

- [x] I may be able to implement this feature request
- [ ] This feature might incur a breaking change

### AWS CDK Library version (aws-cdk-lib)

aws-cdk-lib@2.217.0

### AWS CDK CLI version

2.1030.0

### Environment details (OS name and version, etc.)

AL2023

Contributor guide

Open the contributing guide

Research direction

The L2 DatabaseCluster implementation is in packages/aws-cdk-lib/aws-rds/lib/cluster.ts; start at the prop handling around line 1481 and renderCredentials around line 1486. Trace how CfnDBCluster properties are synthesized, then verify the IAM master-user option omits the password while preserving existing behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, typescript
Domain
cloud, databases, infrastructure
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.