diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/cdk-rds-read-replica.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/cdk-rds-read-replica.assets.json index ba06e003cadc1..ad41e49e27ce0 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/cdk-rds-read-replica.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/cdk-rds-read-replica.assets.json @@ -1,7 +1,7 @@ { "version": "36.0.0", "files": { - "3a230c6ac4fd9d5aa1c50b3d259d306931b243a5d23f9dfd23bff0ebd01ad9a2": { + "4f2dcd7b7c7528c9dc40a786b8e94ed681d7edf1f42b9ca16d0d3e6ab419c019": { "source": { "path": "cdk-rds-read-replica.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "3a230c6ac4fd9d5aa1c50b3d259d306931b243a5d23f9dfd23bff0ebd01ad9a2.json", + "objectKey": "4f2dcd7b7c7528c9dc40a786b8e94ed681d7edf1f42b9ca16d0d3e6ab419c019.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/cdk-rds-read-replica.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/cdk-rds-read-replica.template.json index fe70fce66650b..0b72839e32f73 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/cdk-rds-read-replica.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/cdk-rds-read-replica.template.json @@ -1,545 +1,652 @@ { - "Resources": { - "Vpc8378EB38": { - "Type": "AWS::EC2::VPC", - "Properties": { - "CidrBlock": "10.0.0.0/16", - "EnableDnsHostnames": true, - "EnableDnsSupport": true, - "InstanceTenancy": "default", - "Tags": [ - { - "Key": "Name", - "Value": "cdk-rds-read-replica/Vpc" - } - ] + "Resources": { + "Vpc8378EB38": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "cdk-rds-read-replica/Vpc" + } + ] + } + }, + "VpcisolatedSubnet1SubnetE62B1B9B": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" } + ] }, - "VpcisolatedSubnet1SubnetE62B1B9B": { - "Type": "AWS::EC2::Subnet", - "Properties": { - "AvailabilityZone": { - "Fn::Select": [ - 0, - { - "Fn::GetAZs": "" - } - ] - }, - "CidrBlock": "10.0.0.0/17", - "MapPublicIpOnLaunch": false, - "Tags": [ - { - "Key": "aws-cdk:subnet-name", - "Value": "isolated" - }, - { - "Key": "aws-cdk:subnet-type", - "Value": "Isolated" - }, - { - "Key": "Name", - "Value": "cdk-rds-read-replica/Vpc/isolatedSubnet1" - } - ], - "VpcId": { - "Ref": "Vpc8378EB38" - } - } + "CidrBlock": "10.0.0.0/17", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "isolated" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Isolated" + }, + { + "Key": "Name", + "Value": "cdk-rds-read-replica/Vpc/isolatedSubnet1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "VpcisolatedSubnet1RouteTableE442650B": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "cdk-rds-read-replica/Vpc/isolatedSubnet1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "VpcisolatedSubnet1RouteTableAssociationD259E31A": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcisolatedSubnet1RouteTableE442650B" }, - "VpcisolatedSubnet1RouteTableE442650B": { - "Type": "AWS::EC2::RouteTable", - "Properties": { - "Tags": [ - { - "Key": "Name", - "Value": "cdk-rds-read-replica/Vpc/isolatedSubnet1" - } - ], - "VpcId": { - "Ref": "Vpc8378EB38" - } + "SubnetId": { + "Ref": "VpcisolatedSubnet1SubnetE62B1B9B" + } + } + }, + "VpcisolatedSubnet2Subnet39217055": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" } + ] }, - "VpcisolatedSubnet1RouteTableAssociationD259E31A": { - "Type": "AWS::EC2::SubnetRouteTableAssociation", - "Properties": { - "RouteTableId": { - "Ref": "VpcisolatedSubnet1RouteTableE442650B" - }, - "SubnetId": { - "Ref": "VpcisolatedSubnet1SubnetE62B1B9B" - } - } + "CidrBlock": "10.0.128.0/17", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "isolated" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Isolated" + }, + { + "Key": "Name", + "Value": "cdk-rds-read-replica/Vpc/isolatedSubnet2" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "VpcisolatedSubnet2RouteTable334F9764": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "cdk-rds-read-replica/Vpc/isolatedSubnet2" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "VpcisolatedSubnet2RouteTableAssociation25A4716F": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcisolatedSubnet2RouteTable334F9764" }, - "VpcisolatedSubnet2Subnet39217055": { - "Type": "AWS::EC2::Subnet", - "Properties": { - "AvailabilityZone": { - "Fn::Select": [ - 1, - { - "Fn::GetAZs": "" - } - ] - }, - "CidrBlock": "10.0.128.0/17", - "MapPublicIpOnLaunch": false, - "Tags": [ - { - "Key": "aws-cdk:subnet-name", - "Value": "isolated" - }, - { - "Key": "aws-cdk:subnet-type", - "Value": "Isolated" - }, - { - "Key": "Name", - "Value": "cdk-rds-read-replica/Vpc/isolatedSubnet2" - } - ], - "VpcId": { - "Ref": "Vpc8378EB38" - } - } + "SubnetId": { + "Ref": "VpcisolatedSubnet2Subnet39217055" + } + } + }, + "PostgresSourceSubnetGroupBEEB1740": { + "Type": "AWS::RDS::DBSubnetGroup", + "Properties": { + "DBSubnetGroupDescription": "Subnet group for PostgresSource database", + "SubnetIds": [ + { + "Ref": "VpcisolatedSubnet1SubnetE62B1B9B" + }, + { + "Ref": "VpcisolatedSubnet2Subnet39217055" + } + ] + } + }, + "PostgresSourceSecurityGroup69289E68": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Security group for PostgresSource database", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "PostgresSourceSecret0A09A7AD": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "Description": { + "Fn::Join": [ + "", + [ + "Generated by the CDK for stack: ", + { + "Ref": "AWS::StackName" + } + ] + ] }, - "VpcisolatedSubnet2RouteTable334F9764": { - "Type": "AWS::EC2::RouteTable", - "Properties": { - "Tags": [ - { - "Key": "Name", - "Value": "cdk-rds-read-replica/Vpc/isolatedSubnet2" - } - ], - "VpcId": { - "Ref": "Vpc8378EB38" - } - } + "GenerateSecretString": { + "ExcludeCharacters": " %+~`#$&*()|[]{}:;<>?!'/@\"\\", + "GenerateStringKey": "password", + "PasswordLength": 30, + "SecretStringTemplate": "{\"username\":\"postgres\"}" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "PostgresSourceSecretAttachmentE3C3B705": { + "Type": "AWS::SecretsManager::SecretTargetAttachment", + "Properties": { + "SecretId": { + "Ref": "PostgresSourceSecret0A09A7AD" }, - "VpcisolatedSubnet2RouteTableAssociation25A4716F": { - "Type": "AWS::EC2::SubnetRouteTableAssociation", - "Properties": { - "RouteTableId": { - "Ref": "VpcisolatedSubnet2RouteTable334F9764" - }, - "SubnetId": { - "Ref": "VpcisolatedSubnet2Subnet39217055" - } - } + "TargetId": { + "Ref": "PostgresSourceEB66BFC9" }, - "PostgresSourceSubnetGroupBEEB1740": { - "Type": "AWS::RDS::DBSubnetGroup", - "Properties": { - "DBSubnetGroupDescription": "Subnet group for PostgresSource database", - "SubnetIds": [ - { - "Ref": "VpcisolatedSubnet1SubnetE62B1B9B" - }, - { - "Ref": "VpcisolatedSubnet2Subnet39217055" - } - ] - } + "TargetType": "AWS::RDS::DBInstance" + } + }, + "PostgresSourceEB66BFC9": { + "Type": "AWS::RDS::DBInstance", + "Properties": { + "AllocatedStorage": "100", + "BackupRetentionPeriod": 5, + "CopyTagsToSnapshot": true, + "DBInstanceClass": "db.t3.small", + "DBSubnetGroupName": { + "Ref": "PostgresSourceSubnetGroupBEEB1740" }, - "PostgresSourceSecurityGroup69289E68": { - "Type": "AWS::EC2::SecurityGroup", - "Properties": { - "GroupDescription": "Security group for PostgresSource database", - "SecurityGroupEgress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow all outbound traffic by default", - "IpProtocol": "-1" - } - ], - "VpcId": { - "Ref": "Vpc8378EB38" - } - } + "Engine": "postgres", + "EngineVersion": "16.3", + "MasterUserPassword": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "PostgresSourceSecret0A09A7AD" + }, + ":SecretString:password::}}" + ] + ] }, - "PostgresSourceSecret0A09A7AD": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "Description": { - "Fn::Join": [ - "", - [ - "Generated by the CDK for stack: ", - { - "Ref": "AWS::StackName" - } - ] - ] - }, - "GenerateSecretString": { - "ExcludeCharacters": " %+~`#$&*()|[]{}:;<>?!'/@\"\\", - "GenerateStringKey": "password", - "PasswordLength": 30, - "SecretStringTemplate": "{\"username\":\"postgres\"}" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" + "MasterUsername": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "PostgresSourceSecret0A09A7AD" + }, + ":SecretString:username::}}" + ] + ] }, - "PostgresSourceSecretAttachmentE3C3B705": { - "Type": "AWS::SecretsManager::SecretTargetAttachment", - "Properties": { - "SecretId": { - "Ref": "PostgresSourceSecret0A09A7AD" - }, - "TargetId": { - "Ref": "PostgresSourceEB66BFC9" - }, - "TargetType": "AWS::RDS::DBInstance" - } + "PubliclyAccessible": false, + "StorageType": "gp2", + "VPCSecurityGroups": [ + { + "Fn::GetAtt": [ + "PostgresSourceSecurityGroup69289E68", + "GroupId" + ] + } + ] + }, + "UpdateReplacePolicy": "Snapshot", + "DeletionPolicy": "Snapshot" + }, + "PostgresReplicaSubnetGroup301B59DA": { + "Type": "AWS::RDS::DBSubnetGroup", + "Properties": { + "DBSubnetGroupDescription": "Subnet group for PostgresReplica database", + "SubnetIds": [ + { + "Ref": "VpcisolatedSubnet1SubnetE62B1B9B" + }, + { + "Ref": "VpcisolatedSubnet2Subnet39217055" + } + ] + } + }, + "PostgresReplicaSecurityGroup5385C4C2": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Security group for PostgresReplica database", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "PostgresReplica23A3C738": { + "Type": "AWS::RDS::DBInstance", + "Properties": { + "CopyTagsToSnapshot": true, + "DBInstanceClass": "db.t3.small", + "DBSubnetGroupName": { + "Ref": "PostgresReplicaSubnetGroup301B59DA" }, - "PostgresSourceEB66BFC9": { - "Type": "AWS::RDS::DBInstance", - "Properties": { - "AllocatedStorage": "100", - "BackupRetentionPeriod": 5, - "CopyTagsToSnapshot": true, - "DBInstanceClass": "db.t3.small", - "DBSubnetGroupName": { - "Ref": "PostgresSourceSubnetGroupBEEB1740" - }, - "Engine": "postgres", - "EngineVersion": "16.3", - "MasterUserPassword": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "PostgresSourceSecret0A09A7AD" - }, - ":SecretString:password::}}" - ] - ] - }, - "MasterUsername": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "PostgresSourceSecret0A09A7AD" - }, - ":SecretString:username::}}" - ] - ] - }, - "PubliclyAccessible": false, - "StorageType": "gp2", - "VPCSecurityGroups": [ - { - "Fn::GetAtt": ["PostgresSourceSecurityGroup69289E68", "GroupId"] - } - ] - }, - "UpdateReplacePolicy": "Snapshot", - "DeletionPolicy": "Snapshot" + "PubliclyAccessible": false, + "SourceDBInstanceIdentifier": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":rds:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":db:", + { + "Ref": "PostgresSourceEB66BFC9" + } + ] + ] }, - "PostgresReplicaSubnetGroup301B59DA": { - "Type": "AWS::RDS::DBSubnetGroup", - "Properties": { - "DBSubnetGroupDescription": "Subnet group for PostgresReplica database", - "SubnetIds": [ - { - "Ref": "VpcisolatedSubnet1SubnetE62B1B9B" - }, - { - "Ref": "VpcisolatedSubnet2Subnet39217055" - } - ] - } + "StorageType": "gp2", + "VPCSecurityGroups": [ + { + "Fn::GetAtt": [ + "PostgresReplicaSecurityGroup5385C4C2", + "GroupId" + ] + } + ] + }, + "UpdateReplacePolicy": "Snapshot", + "DeletionPolicy": "Snapshot" + }, + "MysqlSourceSubnetGroup213E979B": { + "Type": "AWS::RDS::DBSubnetGroup", + "Properties": { + "DBSubnetGroupDescription": "Subnet group for MysqlSource database", + "SubnetIds": [ + { + "Ref": "VpcisolatedSubnet1SubnetE62B1B9B" + }, + { + "Ref": "VpcisolatedSubnet2Subnet39217055" + } + ] + } + }, + "MysqlSourceSecurityGroupC691E169": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Security group for MysqlSource database", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "MysqlSourceSecretB727C3F2": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "Description": { + "Fn::Join": [ + "", + [ + "Generated by the CDK for stack: ", + { + "Ref": "AWS::StackName" + } + ] + ] }, - "PostgresReplicaSecurityGroup5385C4C2": { - "Type": "AWS::EC2::SecurityGroup", - "Properties": { - "GroupDescription": "Security group for PostgresReplica database", - "SecurityGroupEgress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow all outbound traffic by default", - "IpProtocol": "-1" - } - ], - "VpcId": { - "Ref": "Vpc8378EB38" - } - } + "GenerateSecretString": { + "ExcludeCharacters": " %+~`#$&*()|[]{}:;<>?!'/@\"\\", + "GenerateStringKey": "password", + "PasswordLength": 30, + "SecretStringTemplate": "{\"username\":\"admin\"}" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "MysqlSourceSecretAttachment5E4EDF73": { + "Type": "AWS::SecretsManager::SecretTargetAttachment", + "Properties": { + "SecretId": { + "Ref": "MysqlSourceSecretB727C3F2" }, - "PostgresReplica23A3C738": { - "Type": "AWS::RDS::DBInstance", - "Properties": { - "CopyTagsToSnapshot": true, - "DBInstanceClass": "db.t3.small", - "DBSubnetGroupName": { - "Ref": "PostgresReplicaSubnetGroup301B59DA" - }, - "PubliclyAccessible": false, - "SourceDBInstanceIdentifier": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":rds:", - { - "Ref": "AWS::Region" - }, - ":", - { - "Ref": "AWS::AccountId" - }, - ":db:", - { - "Ref": "PostgresSourceEB66BFC9" - } - ] - ] - }, - "StorageType": "gp2", - "VPCSecurityGroups": [ - { - "Fn::GetAtt": ["PostgresReplicaSecurityGroup5385C4C2", "GroupId"] - } - ] - }, - "UpdateReplacePolicy": "Snapshot", - "DeletionPolicy": "Snapshot" + "TargetId": { + "Ref": "MysqlSource9A10350C" }, - "MysqlSourceSubnetGroup213E979B": { - "Type": "AWS::RDS::DBSubnetGroup", - "Properties": { - "DBSubnetGroupDescription": "Subnet group for MysqlSource database", - "SubnetIds": [ - { - "Ref": "VpcisolatedSubnet1SubnetE62B1B9B" - }, - { - "Ref": "VpcisolatedSubnet2Subnet39217055" - } - ] - } + "TargetType": "AWS::RDS::DBInstance" + } + }, + "MysqlSource9A10350C": { + "Type": "AWS::RDS::DBInstance", + "Properties": { + "AllocatedStorage": "100", + "BackupRetentionPeriod": 5, + "CopyTagsToSnapshot": true, + "DBInstanceClass": "db.t3.small", + "DBSubnetGroupName": { + "Ref": "MysqlSourceSubnetGroup213E979B" }, - "MysqlSourceSecurityGroupC691E169": { - "Type": "AWS::EC2::SecurityGroup", - "Properties": { - "GroupDescription": "Security group for MysqlSource database", - "SecurityGroupEgress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow all outbound traffic by default", - "IpProtocol": "-1" - } - ], - "VpcId": { - "Ref": "Vpc8378EB38" - } - } + "Engine": "mysql", + "EngineVersion": "8.0", + "MasterUserPassword": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "MysqlSourceSecretB727C3F2" + }, + ":SecretString:password::}}" + ] + ] }, - "MysqlSourceSecretB727C3F2": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "Description": { - "Fn::Join": [ - "", - [ - "Generated by the CDK for stack: ", - { - "Ref": "AWS::StackName" - } - ] - ] - }, - "GenerateSecretString": { - "ExcludeCharacters": " %+~`#$&*()|[]{}:;<>?!'/@\"\\", - "GenerateStringKey": "password", - "PasswordLength": 30, - "SecretStringTemplate": "{\"username\":\"admin\"}" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" + "MasterUsername": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "MysqlSourceSecretB727C3F2" + }, + ":SecretString:username::}}" + ] + ] }, - "MysqlSourceSecretAttachment5E4EDF73": { - "Type": "AWS::SecretsManager::SecretTargetAttachment", - "Properties": { - "SecretId": { - "Ref": "MysqlSourceSecretB727C3F2" - }, - "TargetId": { - "Ref": "MysqlSource9A10350C" - }, - "TargetType": "AWS::RDS::DBInstance" - } + "PubliclyAccessible": false, + "StorageType": "gp2", + "VPCSecurityGroups": [ + { + "Fn::GetAtt": [ + "MysqlSourceSecurityGroupC691E169", + "GroupId" + ] + } + ] + }, + "UpdateReplacePolicy": "Snapshot", + "DeletionPolicy": "Snapshot" + }, + "ReplicaParameterGroup4BE5EE70": { + "Type": "AWS::RDS::DBParameterGroup", + "Properties": { + "Description": "Parameter group for mysql8.0", + "Family": "mysql8.0", + "Parameters": { + "wait_timeout": "86400" + } + } + }, + "MysqlReplicaSubnetGroup79E1F72A": { + "Type": "AWS::RDS::DBSubnetGroup", + "Properties": { + "DBSubnetGroupDescription": "Subnet group for MysqlReplica database", + "SubnetIds": [ + { + "Ref": "VpcisolatedSubnet1SubnetE62B1B9B" + }, + { + "Ref": "VpcisolatedSubnet2Subnet39217055" + } + ] + } + }, + "MysqlReplicaSecurityGroup169FAFAA": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Security group for MysqlReplica database", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "MysqlReplica87D29F78": { + "Type": "AWS::RDS::DBInstance", + "Properties": { + "BackupRetentionPeriod": 3, + "CopyTagsToSnapshot": true, + "DBInstanceClass": "db.t3.small", + "DBParameterGroupName": { + "Ref": "ReplicaParameterGroup4BE5EE70" }, - "MysqlSource9A10350C": { - "Type": "AWS::RDS::DBInstance", - "Properties": { - "AllocatedStorage": "100", - "BackupRetentionPeriod": 5, - "CopyTagsToSnapshot": true, - "DBInstanceClass": "db.t3.small", - "DBSubnetGroupName": { - "Ref": "MysqlSourceSubnetGroup213E979B" - }, - "Engine": "mysql", - "EngineVersion": "8.0", - "MasterUserPassword": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "MysqlSourceSecretB727C3F2" - }, - ":SecretString:password::}}" - ] - ] - }, - "MasterUsername": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "MysqlSourceSecretB727C3F2" - }, - ":SecretString:username::}}" - ] - ] - }, - "PubliclyAccessible": false, - "StorageType": "gp2", - "VPCSecurityGroups": [ - { - "Fn::GetAtt": ["MysqlSourceSecurityGroupC691E169", "GroupId"] - } - ] - }, - "UpdateReplacePolicy": "Snapshot", - "DeletionPolicy": "Snapshot" + "DBSubnetGroupName": { + "Ref": "MysqlReplicaSubnetGroup79E1F72A" + }, + "EnableIAMDatabaseAuthentication": true, + "PubliclyAccessible": false, + "SourceDBInstanceIdentifier": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":rds:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":db:", + { + "Ref": "MysqlSource9A10350C" + } + ] + ] }, - "ReplicaParameterGroup4BE5EE70": { - "Type": "AWS::RDS::DBParameterGroup", - "Properties": { - "Description": "Parameter group for mysql8.0", - "Family": "mysql8.0", - "Parameters": { - "wait_timeout": "86400" + "StorageType": "gp2", + "VPCSecurityGroups": [ + { + "Fn::GetAtt": [ + "MysqlReplicaSecurityGroup169FAFAA", + "GroupId" + ] + } + ] + }, + "UpdateReplacePolicy": "Snapshot", + "DeletionPolicy": "Snapshot" + }, + "DBRole890CB76D": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] } + } } - }, - "MysqlReplicaSubnetGroup79E1F72A": { - "Type": "AWS::RDS::DBSubnetGroup", - "Properties": { - "DBSubnetGroupDescription": "Subnet group for MysqlReplica database", - "SubnetIds": [ + ], + "Version": "2012-10-17" + } + } + }, + "DBRoleDefaultPolicyDBB64848": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "rds-db:connect", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", { - "Ref": "VpcisolatedSubnet1SubnetE62B1B9B" + "Ref": "AWS::Partition" }, + ":rds-db:", { - "Ref": "VpcisolatedSubnet2Subnet39217055" - } - ] - } - }, - "MysqlReplicaSecurityGroup169FAFAA": { - "Type": "AWS::EC2::SecurityGroup", - "Properties": { - "GroupDescription": "Security group for MysqlReplica database", - "SecurityGroupEgress": [ + "Ref": "AWS::Region" + }, + ":", { - "CidrIp": "0.0.0.0/0", - "Description": "Allow all outbound traffic by default", - "IpProtocol": "-1" - } - ], - "VpcId": { - "Ref": "Vpc8378EB38" - } - } - }, - "MysqlReplica87D29F78": { - "Type": "AWS::RDS::DBInstance", - "Properties": { - "BackupRetentionPeriod": 3, - "CopyTagsToSnapshot": true, - "DBInstanceClass": "db.t3.small", - "DBParameterGroupName": { - "Ref": "ReplicaParameterGroup4BE5EE70" - }, - "DBSubnetGroupName": { - "Ref": "MysqlReplicaSubnetGroup79E1F72A" - }, - "PubliclyAccessible": false, - "SourceDBInstanceIdentifier": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":rds:", - { - "Ref": "AWS::Region" - }, - ":", - { - "Ref": "AWS::AccountId" - }, - ":db:", - { - "Ref": "MysqlSource9A10350C" - } - ] - ] - }, - "StorageType": "gp2", - "VPCSecurityGroups": [ + "Ref": "AWS::AccountId" + }, + ":dbuser:", { - "Fn::GetAtt": ["MysqlReplicaSecurityGroup169FAFAA", "GroupId"] + "Fn::GetAtt": [ + "MysqlReplica87D29F78", + "DbiResourceId" + ] + }, + "/", + { + "Ref": "DBUser03089649" } + ] ] - }, - "UpdateReplacePolicy": "Snapshot", - "DeletionPolicy": "Snapshot" - } - }, - "Parameters": { - "BootstrapVersion": { - "Type": "AWS::SSM::Parameter::Value", - "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" - } + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "DBRoleDefaultPolicyDBB64848", + "Roles": [ + { + "Ref": "DBRole890CB76D" + } + ] + } }, - "Rules": { - "CheckBootstrapVersion": { - "Assertions": [ - { - "Assert": { - "Fn::Not": [ - { - "Fn::Contains": [ - ["1", "2", "3", "4", "5"], - { - "Ref": "BootstrapVersion" - } - ] - } - ] - }, - "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." - } + "DBUser03089649": { + "Type": "AWS::IAM::User", + "Properties": { + "UserName": "dbuser" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." } + ] } -} + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/manifest.json index 0b85dfb715800..c71d552142c54 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/manifest.json @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/3a230c6ac4fd9d5aa1c50b3d259d306931b243a5d23f9dfd23bff0ebd01ad9a2.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/4f2dcd7b7c7528c9dc40a786b8e94ed681d7edf1f42b9ca16d0d3e6ab419c019.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -178,6 +178,24 @@ "data": "MysqlReplica87D29F78" } ], + "/cdk-rds-read-replica/DBRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DBRole890CB76D" + } + ], + "/cdk-rds-read-replica/DBRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DBRoleDefaultPolicyDBB64848" + } + ], + "/cdk-rds-read-replica/DBUser/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DBUser03089649" + } + ], "/cdk-rds-read-replica/BootstrapVersion": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/tree.json index c39576d3a9cf4..89f4ebe910036 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.js.snapshot/tree.json @@ -393,7 +393,7 @@ "Ref": "PostgresSourceSubnetGroupBEEB1740" }, "engine": "postgres", - "EngineVersion": "16.3", + "engineVersion": "16.3", "masterUsername": { "Fn::Join": [ "", @@ -883,6 +883,7 @@ "dbSubnetGroupName": { "Ref": "MysqlReplicaSubnetGroup79E1F72A" }, + "enableIamDatabaseAuthentication": true, "publiclyAccessible": false, "sourceDbInstanceIdentifier": { "Fn::Join": [ @@ -929,6 +930,156 @@ "version": "0.0.0" } }, + "DBRole": { + "id": "DBRole", + "path": "cdk-rds-read-replica/DBRole", + "children": { + "ImportDBRole": { + "id": "ImportDBRole", + "path": "cdk-rds-read-replica/DBRole/ImportDBRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "cdk-rds-read-replica/DBRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "cdk-rds-read-replica/DBRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "cdk-rds-read-replica/DBRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "rds-db:connect", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":rds-db:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":dbuser:", + { + "Fn::GetAtt": [ + "MysqlReplica87D29F78", + "DbiResourceId" + ] + }, + "/", + { + "Ref": "DBUser03089649" + } + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "DBRoleDefaultPolicyDBB64848", + "roles": [ + { + "Ref": "DBRole890CB76D" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "DBUser": { + "id": "DBUser", + "path": "cdk-rds-read-replica/DBUser", + "children": { + "Resource": { + "id": "Resource", + "path": "cdk-rds-read-replica/DBUser/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::User", + "aws:cdk:cloudformation:props": { + "userName": "dbuser" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnUser", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.User", + "version": "0.0.0" + } + }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "cdk-rds-read-replica/BootstrapVersion", @@ -1019,4 +1170,4 @@ "version": "0.0.0" } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.ts index c9134de077f26..1767638ff0bab 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.read-replica.ts @@ -1,6 +1,7 @@ import { InstanceClass, InstanceSize, InstanceType, SubnetSelection, SubnetType, Vpc } from 'aws-cdk-lib/aws-ec2'; import { App, Duration, Stack, StackProps } from 'aws-cdk-lib'; import { Construct } from 'constructs'; +import * as iam from 'aws-cdk-lib/aws-iam'; import * as rds from 'aws-cdk-lib/aws-rds'; import { IntegTest } from '@aws-cdk/integ-tests-alpha'; @@ -53,7 +54,7 @@ class TestStack extends Stack { }, }); - new rds.DatabaseInstanceReadReplica(this, 'MysqlReplica', { + const mysqlReadReplicaInstance = new rds.DatabaseInstanceReadReplica(this, 'MysqlReplica', { sourceDatabaseInstance: mysqlSource, backupRetention: Duration.days(3), instanceType, @@ -61,6 +62,16 @@ class TestStack extends Stack { vpcSubnets, parameterGroup, }); + + const role = new iam.Role(this, 'DBRole', { + assumedBy: new iam.AccountPrincipal(this.account), + }); + + const user = new iam.User(this, 'DBUser', { + userName: 'dbuser', + }); + + mysqlReadReplicaInstance.grantConnect(role, user.userName); } } diff --git a/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md b/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md index fdc3e50d23051..c321f86ef21e3 100644 --- a/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md +++ b/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md @@ -73,6 +73,7 @@ Flags come in three types: | [@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault](#aws-cdkcustom-resourceslogapiresponsedatapropertytruedefault) | When enabled, the custom resource used for `AwsCustomResource` will configure the `logApiResponseData` property as true by default | 2.145.0 | (fix) | | [@aws-cdk/aws-s3:keepNotificationInImportedBucket](#aws-cdkaws-s3keepnotificationinimportedbucket) | When enabled, Adding notifications to a bucket in the current stack will not remove notification from imported stack. | 2.155.0 | (fix) | | [@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask](#aws-cdkaws-stepfunctions-tasksusenews3uriparametersforbedrockinvokemodeltask) | When enabled, use new props for S3 URI field in task definition of state machine for bedrock invoke model. | V2NEXT | (fix) | +| [@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId](#aws-rds-setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId) | When enabled, the value of property `instanceResourceId` in construct `DatabaseInstanceReadReplica` will be set to the correct value which is `DbiResourceId` instead of currently `DbInstanceArn` | V2NEXT | (fix) | @@ -135,7 +136,9 @@ The following json shows the current recommended set of flags, as `cdk init` wou "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true, "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false, "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false, - "@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask": true + "@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask": true, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false, + "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true } } ``` @@ -1376,4 +1379,21 @@ When this feature flag is enabled, specify newly introduced props 's3InputUri' a **Compatibility with old behavior:** Disable the feature flag to use input and output path fields for s3 URI + +### @aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId + +*When enabled, the value of property `instanceResourceId` in construct `DatabaseInstanceReadReplica` will be set to the correct value which is `DbiResourceId` instead of currently `DbInstanceArn`* (fix) + +Currently, the value of the property `instanceResourceId` in construct `DatabaseInstanceReadReplica` is not correct, and set to `DbInstanceArn` which is not correct when it is used to create the IAM Policy in the grantConnect method. + +When this feature flag is enabled, the value of that property will be as expected set to `DbiResourceId` attribute, and that will fix the grantConnect method. + + +| Since | Default | Recommended | +| ----- |---------|-------------| +| (not in v1) | | | +| V2NEXT | `true` | `true` | + +**Compatibility with old behavior:** Disable the feature flag to use `DbInstanceArn` as value for property `instanceResourceId` + diff --git a/packages/aws-cdk-lib/aws-rds/lib/instance.ts b/packages/aws-cdk-lib/aws-rds/lib/instance.ts index 65a4e45c939eb..cfd41de9e680c 100644 --- a/packages/aws-cdk-lib/aws-rds/lib/instance.ts +++ b/packages/aws-cdk-lib/aws-rds/lib/instance.ts @@ -1333,6 +1333,13 @@ export class DatabaseInstanceReadReplica extends DatabaseInstanceNew implements public readonly instanceIdentifier: string; public readonly dbInstanceEndpointAddress: string; public readonly dbInstanceEndpointPort: string; + + /** + * The AWS Region-unique, immutable identifier for the DB instance. + * This identifier is found in AWS CloudTrail log entries whenever the AWS KMS key for the DB instance is accessed. + * + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-dbinstance.html#aws-resource-rds-dbinstance-return-values + */ public readonly instanceResourceId?: string; public readonly instanceEndpoint: Endpoint; public readonly engine?: IInstanceEngine = undefined; @@ -1366,7 +1373,9 @@ export class DatabaseInstanceReadReplica extends DatabaseInstanceNew implements this.instanceIdentifier = instance.ref; this.dbInstanceEndpointAddress = instance.attrEndpointAddress; this.dbInstanceEndpointPort = instance.attrEndpointPort; - this.instanceResourceId = instance.attrDbInstanceArn; + + this.instanceResourceId = FeatureFlags.of(this).isEnabled(cxapi.USE_CORRECT_VALUE_FOR_INSTANCE_RESOURCE_ID_PROPERTY) ? + instance.attrDbiResourceId : instance.attrDbInstanceArn; // create a number token that represents the port of the instance const portAttribute = Token.asNumber(instance.attrEndpointPort); diff --git a/packages/aws-cdk-lib/aws-rds/test/instance.test.ts b/packages/aws-cdk-lib/aws-rds/test/instance.test.ts index 84a303309b597..5c311a3523e84 100644 --- a/packages/aws-cdk-lib/aws-rds/test/instance.test.ts +++ b/packages/aws-cdk-lib/aws-rds/test/instance.test.ts @@ -7,6 +7,7 @@ import * as lambda from '../../aws-lambda'; import * as logs from '../../aws-logs'; import * as s3 from '../../aws-s3'; import * as cdk from '../../core'; +import * as cxapi from '../../cx-api'; import * as rds from '../lib'; let stack: cdk.Stack; @@ -1358,6 +1359,130 @@ describe('instance', () => { expect(() => { instance.grantConnect(role); }).toThrow(/Cannot grant connect when IAM authentication is disabled/); }); + test('createGrant - creates IAM policy for instance replica when the USE_CORRECT_VALUE_FOR_INSTANCE_RESOURCE_ID_PROPERTY feature flag is enabled by default', () => { + const cloudwatchTraceLog = 'trace'; + const sourceInstance = new rds.DatabaseInstance(stack, 'Instance', { + engine: rds.DatabaseInstanceEngine.MYSQL, + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + vpc, + }); + + const role = new Role(stack, 'DBRole', { + assumedBy: new AccountPrincipal(stack.account), + }); + + const replicaInstance = new rds.DatabaseInstanceReadReplica(stack, 'ReadReplica', { + sourceDatabaseInstance: sourceInstance, + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.LARGE), + vpc, + }); + + // WHEN + replicaInstance.grantConnect(role, 'my-user'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [{ + Effect: 'Allow', + Action: 'rds-db:connect', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':rds-db:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':dbuser:', + { + 'Fn::GetAtt': [ + 'ReadReplicaDA01B356', + 'DbiResourceId', + ], + }, + '/my-user', + ], + ], + }, + }], + Version: '2012-10-17', + }, + }); + }); + + test('createGrant - creates IAM policy for instance replica when the USE_CORRECT_VALUE_FOR_INSTANCE_RESOURCE_ID_PROPERTY feature flag is disabled', () => { + const cloudwatchTraceLog = 'trace'; + const app = new cdk.App({ context: { [cxapi.USE_CORRECT_VALUE_FOR_INSTANCE_RESOURCE_ID_PROPERTY]: false } }); + stack = new cdk.Stack(app); + vpc = new ec2.Vpc( stack, 'VPC' ); + const sourceInstance = new rds.DatabaseInstance(stack, 'Instance', { + engine: rds.DatabaseInstanceEngine.MYSQL, + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + vpc, + }); + + const role = new Role(stack, 'DBRole', { + assumedBy: new AccountPrincipal(stack.account), + }); + + const replicaInstance = new rds.DatabaseInstanceReadReplica(stack, 'ReadReplica', { + sourceDatabaseInstance: sourceInstance, + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.LARGE), + vpc, + }); + + // WHEN + replicaInstance.grantConnect(role, 'my-user'); + + // THEN + app.synth(); + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [{ + Effect: 'Allow', + Action: 'rds-db:connect', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':rds-db:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':dbuser:', + { + 'Fn::GetAtt': [ + 'ReadReplicaDA01B356', + 'DBInstanceArn', + ], + }, + '/my-user', + ], + ], + }, + }], + Version: '2012-10-17', + }, + }); + }); + test('domain - sets domain property', () => { const domain = 'd-90670a8d36'; diff --git a/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md b/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md index 634630f6e9b41..13d37bc2da2d1 100644 --- a/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md +++ b/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md @@ -73,6 +73,7 @@ Flags come in three types: | [@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault](#aws-cdkcustom-resourceslogapiresponsedatapropertytruedefault) | When enabled, the custom resource used for `AwsCustomResource` will configure the `logApiResponseData` property as true by default | 2.145.0 | (fix) | | [@aws-cdk/aws-s3:keepNotificationInImportedBucket](#aws-cdkaws-s3keepnotificationinimportedbucket) | When enabled, Adding notifications to a bucket in the current stack will not remove notification from imported stack. | 2.155.0 | (fix) | | [@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask](#aws-cdkaws-stepfunctions-tasksusenews3uriparametersforbedrockinvokemodeltask) | When enabled, use new props for S3 URI field in task definition of state machine for bedrock invoke model. | 2.156.0 | (fix) | +| [@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId](#aws-cdkaws-rdssetcorrectvaluefordatabaseinstancereadreplicainstanceresourceid) | When enabled, the value of property `instanceResourceId` in construct `DatabaseInstanceReadReplica` will be set to the correct value which is `DbiResourceId` instead of currently `DbInstanceArn` | V2NEXT | (fix) | @@ -179,6 +180,7 @@ are migrating a v1 CDK project to v2, explicitly set any of these flags which do | [@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2\_2021](#aws-cdkaws-cloudfrontdefaultsecuritypolicytlsv12_2021) | Enable this feature flag to have cloudfront distributions use the security policy TLSv1.2_2021 by default. | (fix) | 1.117.0 | `false` | `true` | | [@aws-cdk/pipelines:reduceAssetRoleTrustScope](#aws-cdkpipelinesreduceassetroletrustscope) | Remove the root account principal from PipelineAssetsFileRole trust policy | (default) | | `false` | `true` | | [@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask](#aws-cdkaws-stepfunctions-tasksusenews3uriparametersforbedrockinvokemodeltask) | When enabled, use new props for S3 URI field in task definition of state machine for bedrock invoke model. | (fix) | | `false` | `true` | +| [@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId](#aws-cdkaws-rdssetcorrectvaluefordatabaseinstancereadreplicainstanceresourceid) | When enabled, the value of property `instanceResourceId` in construct `DatabaseInstanceReadReplica` will be set to the correct value which is `DbiResourceId` instead of currently `DbInstanceArn` | (fix) | | `false` | `true` | @@ -195,7 +197,8 @@ Here is an example of a `cdk.json` file that restores v1 behavior for these flag "@aws-cdk/aws-lambda:recognizeVersionProps": false, "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": false, "@aws-cdk/pipelines:reduceAssetRoleTrustScope": false, - "@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask": false + "@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask": false, + "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": false } } ``` @@ -1378,4 +1381,21 @@ When this feature flag is enabled, specify newly introduced props 's3InputUri' a **Compatibility with old behavior:** Disable the feature flag to use input and output path fields for s3 URI +### @aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId + +*When enabled, the value of property `instanceResourceId` in construct `DatabaseInstanceReadReplica` will be set to the correct value which is `DbiResourceId` instead of currently `DbInstanceArn`* (fix) + +Currently, the value of the property 'instanceResourceId' in construct 'DatabaseInstanceReadReplica' is not correct, and set to 'DbInstanceArn' which is not correct when it is used to create the IAM Policy in the grantConnect method. + +When this feature flag is enabled, the value of that property will be as expected set to 'DbiResourceId' attribute, and that will fix the grantConnect method. + + +| Since | Default | Recommended | +| ----- | ----- | ----- | +| (not in v1) | | | +| V2NEXT | `true` | `true` | + +**Compatibility with old behavior:** Disable the feature flag to use `DbInstanceArn` as value for property `instanceResourceId` + + diff --git a/packages/aws-cdk-lib/cx-api/README.md b/packages/aws-cdk-lib/cx-api/README.md index d094fd410d235..ace4cd6237a73 100644 --- a/packages/aws-cdk-lib/cx-api/README.md +++ b/packages/aws-cdk-lib/cx-api/README.md @@ -391,4 +391,20 @@ _cdk.json_ "@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask": true } } -``` \ No newline at end of file +``` + +* `@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId` + +When enabled, the value of property `instanceResourceId` in construct `DatabaseInstanceReadReplica` will be set to the correct value which is `DbiResourceId` instead of currently `DbInstanceArn`* (fix) + +When this feature flag is enabled, the value of that property will be as expected set to `DbiResourceId` attribute, and that will fix the grantConnect method. + +_cdk.json_ + +```json +{ + "context": { + "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true + } +} +``` diff --git a/packages/aws-cdk-lib/cx-api/lib/features.ts b/packages/aws-cdk-lib/cx-api/lib/features.ts index 2c3155bcf8b6c..d88b2a5cb4370 100644 --- a/packages/aws-cdk-lib/cx-api/lib/features.ts +++ b/packages/aws-cdk-lib/cx-api/lib/features.ts @@ -107,6 +107,7 @@ export const ECS_REMOVE_DEFAULT_DEPLOYMENT_ALARM = '@aws-cdk/aws-ecs:removeDefau export const LOG_API_RESPONSE_DATA_PROPERTY_TRUE_DEFAULT = '@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault'; export const S3_KEEP_NOTIFICATION_IN_IMPORTED_BUCKET = '@aws-cdk/aws-s3:keepNotificationInImportedBucket'; export const USE_NEW_S3URI_PARAMETERS_FOR_BEDROCK_INVOKE_MODEL_TASK = '@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask'; +export const USE_CORRECT_VALUE_FOR_INSTANCE_RESOURCE_ID_PROPERTY = '@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId'; export const FLAGS: Record = { ////////////////////////////////////////////////////////////////////// @@ -1126,6 +1127,21 @@ export const FLAGS: Record = { recommendedValue: true, compatibilityWithOldBehaviorMd: 'Disable the feature flag to use input and output path fields for s3 URI', }, + + ////////////////////////////////////////////////////////////////////// + [USE_CORRECT_VALUE_FOR_INSTANCE_RESOURCE_ID_PROPERTY]: { + type: FlagType.BugFix, + summary: 'When enabled, the value of property `instanceResourceId` in construct `DatabaseInstanceReadReplica` will be set to the correct value which is `DbiResourceId` instead of currently `DbInstanceArn`', + detailsMd: ` + Currently, the value of the property 'instanceResourceId' in construct 'DatabaseInstanceReadReplica' is not correct, and set to 'DbInstanceArn' which is not correct when it is used to create the IAM Policy in the grantConnect method. + + When this feature flag is enabled, the value of that property will be as expected set to 'DbiResourceId' attribute, and that will fix the grantConnect method. + `, + introducedIn: { v2: 'V2NEXT' }, + defaults: { v2: true }, + recommendedValue: true, + compatibilityWithOldBehaviorMd: 'Disable the feature flag to use `DbInstanceArn` as value for property `instanceResourceId`', + }, }; const CURRENT_MV = 'v2'; diff --git a/packages/aws-cdk-lib/cx-api/test/features.test.ts b/packages/aws-cdk-lib/cx-api/test/features.test.ts index 470b2644ba2a6..80db0e4ece40f 100644 --- a/packages/aws-cdk-lib/cx-api/test/features.test.ts +++ b/packages/aws-cdk-lib/cx-api/test/features.test.ts @@ -37,6 +37,7 @@ test('feature flag defaults may not be changed anymore', () => { [feats.EFS_DEFAULT_ENCRYPTION_AT_REST]: true, [feats.LAMBDA_RECOGNIZE_VERSION_PROPS]: true, [feats.CLOUDFRONT_DEFAULT_SECURITY_POLICY_TLS_V1_2_2021]: true, + [feats.USE_CORRECT_VALUE_FOR_INSTANCE_RESOURCE_ID_PROPERTY]: true, [feats.PIPELINE_REDUCE_ASSET_ROLE_TRUST_SCOPE]: true, [feats.USE_NEW_S3URI_PARAMETERS_FOR_BEDROCK_INVOKE_MODEL_TASK]: true, // Add new disabling feature flags below this line