Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(aws-rds): grantConnect generates incorrect policy for DatabaseInstanceReadReplica #31061

Open
moltar opened this issue Aug 8, 2024 · 4 comments · May be fixed by #31068
Open

(aws-rds): grantConnect generates incorrect policy for DatabaseInstanceReadReplica #31061

moltar opened this issue Aug 8, 2024 · 4 comments · May be fixed by #31068
Assignees
Labels
@aws-cdk/aws-rds Related to Amazon Relational Database bug This issue is a bug. effort/small Small work item – less than a day of effort p2

Comments

@moltar
Copy link
Contributor

moltar commented Aug 8, 2024

Describe the bug

Calling grantConnect on an instance of DatabaseInstanceReadReplica generates an incorrect policy that uses the full ARN of the instance instead of the instanceResourceId value.

Expected Behavior

{
    "Action": "rds-db:connect",
    "Resource": "arn:aws:rds-db:us-east-1:1234567890:dbuser:db-INSTANCE_RESOURCE_ID/user",
    "Effect": "Allow"
}

Current Behavior

{
    "Action": "rds-db:connect",
    "Resource": "arn:aws:rds-db:us-east-1:1234567890:dbuser:arn:aws:rds:us-east-1:1234567890:db:instance-name-wq2y5qzlfdy6/user",
    "Effect": "Allow"
}

Reproduction Steps

  1. Create a read replica
  2. Call grantConnect on it

Possible Solution

No response

Additional Information/Context

Stack.of(this).formatArn({
arnFormat: ArnFormat.COLON_RESOURCE_NAME,
service: 'rds-db',
resource: 'dbuser',
resourceName: [this.instanceResourceId, dbUser].join('/'),
}),

CDK CLI Version

2.150.0

Framework Version

2.150.0

Node.js Version

v20.14.0

OS

macOS

Language

TypeScript

Language Version

No response

Other information

No response

@moltar moltar added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Aug 8, 2024
@github-actions github-actions bot added the @aws-cdk/aws-rds Related to Amazon Relational Database label Aug 8, 2024
@moltar
Copy link
Contributor Author

moltar commented Aug 8, 2024

I think the culprit is here:

this.instanceResourceId = instance.attrDbInstanceArn;

@moltar
Copy link
Contributor Author

moltar commented Aug 8, 2024

@moltar
Copy link
Contributor Author

moltar commented Aug 8, 2024

I confirmed by applying this workaround.

Add this code to the end of the stack for a temporary fix.

    for (const node of this.node.findAll()) {
      if (node instanceof DatabaseInstanceReadReplica && node.node.defaultChild instanceof CfnDBInstance) {
        Object.assign(node, {
          instanceResourceId: node.node.defaultChild.attrDbiResourceId,
        } satisfies Partial<DatabaseInstanceReadReplica>);
      }
    }

@ashishdhingra ashishdhingra self-assigned this Aug 8, 2024
@ashishdhingra ashishdhingra added p2 needs-reproduction This issue needs reproduction. and removed needs-triage This issue or PR still needs to be triaged. labels Aug 8, 2024
@ashishdhingra
Copy link
Contributor

ashishdhingra commented Aug 8, 2024

Reproducible using below code:

import * as iam from 'aws-cdk-lib/aws-iam';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as cdk from 'aws-cdk-lib';
import * as rds from 'aws-cdk-lib/aws-rds';

export class CdktestStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const vpc = new ec2.Vpc(this, 'myVpc');
    
    const sourceInstance = new rds.DatabaseInstance(this, 'TestDBInstance', {
      engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_15_4 }),
      instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE),
      vpc,
    });

    const dbReadReplica = new rds.DatabaseInstanceReadReplica(this, 'TestDBReadReplica', {
      sourceDatabaseInstance: sourceInstance,
      instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE),
      vpc,
    });

    const role = new iam.Role(this, 'DBTestRole', {assumedBy: new iam.AccountPrincipal(this.account)});
    dbReadReplica.grantConnect(role, 'someuser');
  }
}

Running cdk synth generates the below CloudFormation template:

Resources:
...
...
    Metadata:
      aws:cdk:path: CdktestStack/TestDBInstance/SecurityGroup/Resource
  TestDBInstanceSecret0BA9F4B5:
    Type: AWS::SecretsManager::Secret
...
  TestDBInstanceSecretAttachment19197643:
    Type: AWS::SecretsManager::SecretTargetAttachment
    Properties:
...
  TestDBInstance0686406D:
    Type: AWS::RDS::DBInstance
    Properties:
      AllocatedStorage: "100"
      CopyTagsToSnapshot: true
      DBInstanceClass: db.m5.large
      DBSubnetGroupName:
        Ref: TestDBInstanceSubnetGroup5C562BBA
      Engine: postgres
      EngineVersion: "15.4"
      MasterUserPassword:
        Fn::Join:
          - ""
          - - "{{resolve:secretsmanager:"
            - Ref: TestDBInstanceSecret0BA9F4B5
            - :SecretString:password::}}
      MasterUsername:
        Fn::Join:
          - ""
          - - "{{resolve:secretsmanager:"
            - Ref: TestDBInstanceSecret0BA9F4B5
            - :SecretString:username::}}
      StorageType: gp2
      VPCSecurityGroups:
        - Fn::GetAtt:
            - TestDBInstanceSecurityGroup5CAD0C42
            - GroupId
    UpdateReplacePolicy: Snapshot
    DeletionPolicy: Snapshot
    Metadata:
      aws:cdk:path: CdktestStack/TestDBInstance/Resource
  TestDBReadReplicaSubnetGroupE39B8C4A:
    Type: AWS::RDS::DBSubnetGroup
    Properties:
...
  TestDBReadReplicaSecurityGroupC4105A64:
    Type: AWS::EC2::SecurityGroup
    Properties:
...
  TestDBReadReplicaEE06F740:
    Type: AWS::RDS::DBInstance
    Properties:
      CopyTagsToSnapshot: true
      DBInstanceClass: db.m5.large
      DBSubnetGroupName:
        Ref: TestDBReadReplicaSubnetGroupE39B8C4A
      EnableIAMDatabaseAuthentication: true
      SourceDBInstanceIdentifier:
        Fn::Join:
          - ""
          - - "arn:aws:rds:us-east-2:<<account-id-redacted>>:db:"
            - Ref: TestDBInstance0686406D
      StorageType: gp2
      VPCSecurityGroups:
        - Fn::GetAtt:
            - TestDBReadReplicaSecurityGroupC4105A64
            - GroupId
    UpdateReplacePolicy: Snapshot
    DeletionPolicy: Snapshot
    Metadata:
      aws:cdk:path: CdktestStack/TestDBReadReplica/Resource
  DBTestRole834396B2:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              AWS: arn:aws:iam::<<account-id-redacted>>:root
        Version: "2012-10-17"
    Metadata:
      aws:cdk:path: CdktestStack/DBTestRole/Resource
  DBTestRoleDefaultPolicy7501B762:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action: rds-db:connect
            Effect: Allow
            Resource:
              Fn::Join:
                - ""
                - - "arn:aws:rds-db:us-east-2:<<account-id-redacted>>:dbuser:"
                  - Fn::GetAtt:
                      - TestDBReadReplicaEE06F740
                      - DBInstanceArn
                  - /someuser
        Version: "2012-10-17"
      PolicyName: DBTestRoleDefaultPolicy7501B762
      Roles:
        - Ref: DBTestRole834396B2
...

Running cdk deploy creates the DB instance and Read replica, and attached the below policy to the specified DB Role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "rds-db:connect",
            "Resource": "arn:aws:rds-db:us-east-2:<<account-id-redacted>>:dbuser:arn:aws:rds:us-east-2:account-id-redacted:db:cdkteststack-testdbreadreplicaee06f740-dycl1vgyuydy/someuser",
            "Effect": "Allow"
        }
    ]
}

It should have created policy with correct resource format arn:aws:rds-db:region:account-id:dbuser:DbiResourceId/db-user-name per Creating and using an IAM policy for IAM database access.

@ashishdhingra ashishdhingra added effort/small Small work item – less than a day of effort and removed needs-reproduction This issue needs reproduction. labels Aug 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-rds Related to Amazon Relational Database bug This issue is a bug. effort/small Small work item – less than a day of effort p2
Projects
None yet
2 participants