From a32436a5ea834b29faed19f37652fb4dae3fb1d7 Mon Sep 17 00:00:00 2001 From: "Kenta Goto (k.goto)" <24818752+go-to-k@users.noreply.github.com> Date: Sat, 19 Oct 2024 10:00:55 +0900 Subject: [PATCH] feat(rds): support local write forwarding for an aurora PostgreSQL cluster (#31803) ### Issue # (if applicable) Closes #31802. ### Reason for this change Amazon Aurora PostgreSQL now supports local write forwarding: Whats new: https://aws.amazon.com/about-aws/whats-new/2024/10/amazon-aurora-postgresql-local-write-forwarding/ Reference: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-postgresql-write-forwarding.html The current CDK L2 construct only supports MySQL, but PostgreSQL needs to be supported as well. ### Description of changes Remove the validation that engineType is either aurora or aurora-mysql, and modify docs. ### Description of how you validated changes Both unit tests and an integ test. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...calWriteForwardingClusterStack.assets.json | 6 +- ...lWriteForwardingClusterStack.template.json | 157 ++++++++++ ...efaultTestDeployAssertFA53AD26.assets.json | 2 +- .../cdk.out | 2 +- .../integ.json | 2 +- .../manifest.json | 54 +++- .../tree.json | 270 ++++++++++++++++++ ...g.cluster-enable-local-write-forwarding.ts | 10 + packages/aws-cdk-lib/aws-rds/README.md | 6 +- packages/aws-cdk-lib/aws-rds/lib/cluster.ts | 9 +- .../aws-cdk-lib/aws-rds/test/cluster.test.ts | 50 ++-- 11 files changed, 520 insertions(+), 48 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/EnableLocalWriteForwardingClusterStack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/EnableLocalWriteForwardingClusterStack.assets.json index 0330afd41f529..6782b1bbaaf5f 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/EnableLocalWriteForwardingClusterStack.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/EnableLocalWriteForwardingClusterStack.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.24", + "version": "38.0.1", "files": { "bde7b5c89cb43285f884c94f0b9e17cdb0f5eb5345005114dd60342e0b8a85a1": { "source": { @@ -14,7 +14,7 @@ } } }, - "94dba9d0100458f81b67c0096ade9a061f8abba8c7e0a7edee6c484a5f15304c": { + "da3d793672a3694b89d65ddb67cceda5a164d94127c21488abff49f99c682f0a": { "source": { "path": "EnableLocalWriteForwardingClusterStack.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "94dba9d0100458f81b67c0096ade9a061f8abba8c7e0a7edee6c484a5f15304c.json", + "objectKey": "da3d793672a3694b89d65ddb67cceda5a164d94127c21488abff49f99c682f0a.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.cluster-enable-local-write-forwarding.js.snapshot/EnableLocalWriteForwardingClusterStack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/EnableLocalWriteForwardingClusterStack.template.json index 52316fc257372..ab7e7722622e5 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/EnableLocalWriteForwardingClusterStack.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/EnableLocalWriteForwardingClusterStack.template.json @@ -670,6 +670,163 @@ ], "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" + }, + "DatabaseClusterPostgresqlSubnetsE0173DAA": { + "Type": "AWS::RDS::DBSubnetGroup", + "Properties": { + "DBSubnetGroupDescription": "Subnets for DatabaseClusterPostgresql database", + "SubnetIds": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ] + } + }, + "DatabaseClusterPostgresqlSecurityGroupEF4103D2": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "RDS security group", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "DatabaseClusterPostgresqlSecretD2D9C157": { + "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" + }, + "DatabaseClusterPostgresqlSecretAttachment09D32DC9": { + "Type": "AWS::SecretsManager::SecretTargetAttachment", + "Properties": { + "SecretId": { + "Ref": "DatabaseClusterPostgresqlSecretD2D9C157" + }, + "TargetId": { + "Ref": "DatabaseClusterPostgresql0775776E" + }, + "TargetType": "AWS::RDS::DBCluster" + } + }, + "DatabaseClusterPostgresql0775776E": { + "Type": "AWS::RDS::DBCluster", + "Properties": { + "CopyTagsToSnapshot": true, + "DBClusterParameterGroupName": "default.aurora-postgresql16", + "DBSubnetGroupName": { + "Ref": "DatabaseClusterPostgresqlSubnetsE0173DAA" + }, + "EnableLocalWriteForwarding": true, + "Engine": "aurora-postgresql", + "EngineVersion": "16.4", + "MasterUserPassword": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "DatabaseClusterPostgresqlSecretD2D9C157" + }, + ":SecretString:password::}}" + ] + ] + }, + "MasterUsername": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "DatabaseClusterPostgresqlSecretD2D9C157" + }, + ":SecretString:username::}}" + ] + ] + }, + "Port": 5432, + "ServerlessV2ScalingConfiguration": { + "MaxCapacity": 2, + "MinCapacity": 0.5 + }, + "VpcSecurityGroupIds": [ + { + "Fn::GetAtt": [ + "DatabaseClusterPostgresqlSecurityGroupEF4103D2", + "GroupId" + ] + } + ] + }, + "UpdateReplacePolicy": "Snapshot", + "DeletionPolicy": "Snapshot" + }, + "DatabaseClusterPostgresqlwriterInstanceB16652DD": { + "Type": "AWS::RDS::DBInstance", + "Properties": { + "DBClusterIdentifier": { + "Ref": "DatabaseClusterPostgresql0775776E" + }, + "DBInstanceClass": "db.serverless", + "Engine": "aurora-postgresql", + "PromotionTier": 0 + }, + "DependsOn": [ + "VPCPrivateSubnet1DefaultRouteAE1D6490", + "VPCPrivateSubnet1RouteTableAssociation347902D1", + "VPCPrivateSubnet2DefaultRouteF4F5CFD2", + "VPCPrivateSubnet2RouteTableAssociation0C73D413" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "DatabaseClusterPostgresqlreaderInstance10798C6B0": { + "Type": "AWS::RDS::DBInstance", + "Properties": { + "DBClusterIdentifier": { + "Ref": "DatabaseClusterPostgresql0775776E" + }, + "DBInstanceClass": "db.serverless", + "Engine": "aurora-postgresql", + "PromotionTier": 2 + }, + "DependsOn": [ + "DatabaseClusterPostgresqlwriterInstanceB16652DD", + "VPCPrivateSubnet1DefaultRouteAE1D6490", + "VPCPrivateSubnet1RouteTableAssociation347902D1", + "VPCPrivateSubnet2DefaultRouteF4F5CFD2", + "VPCPrivateSubnet2RouteTableAssociation0C73D413" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" } }, "Mappings": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/EnableLocalWriteForwardingClusterStackIntegDefaultTestDeployAssertFA53AD26.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/EnableLocalWriteForwardingClusterStackIntegDefaultTestDeployAssertFA53AD26.assets.json index 412b2018c9495..ecaca21c3219f 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/EnableLocalWriteForwardingClusterStackIntegDefaultTestDeployAssertFA53AD26.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/EnableLocalWriteForwardingClusterStackIntegDefaultTestDeployAssertFA53AD26.assets.json @@ -1,5 +1,5 @@ { - "version": "36.0.24", + "version": "38.0.1", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/cdk.out index 4efaa16f29af9..c6e612584e352 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"36.0.24"} \ No newline at end of file +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/integ.json index 9a072f0361b71..4ab4cc0ecd51e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "36.0.24", + "version": "38.0.1", "testCases": { "EnableLocalWriteForwardingClusterStackInteg/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/manifest.json index 1e7acf8035365..6b280bb4b4574 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "36.0.24", + "version": "38.0.1", "artifacts": { "EnableLocalWriteForwardingClusterStack.assets": { "type": "cdk:asset-manifest", @@ -16,9 +16,10 @@ "templateFile": "EnableLocalWriteForwardingClusterStack.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "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}/94dba9d0100458f81b67c0096ade9a061f8abba8c7e0a7edee6c484a5f15304c.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/da3d793672a3694b89d65ddb67cceda5a164d94127c21488abff49f99c682f0a.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -250,6 +251,54 @@ "data": "DatabaseClusterreaderInstance17277480B" } ], + "/EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql": [ + { + "type": "aws:cdk:warning", + "data": "Cluster DatabaseClusterPostgresql only has serverless readers and no reader is in promotion tier 0-1.Serverless readers in promotion tiers >= 2 will NOT scale with the writer, which can lead to availability issues if a failover event occurs. It is recommended that at least one reader has `scaleWithWriter` set to true [ack: @aws-cdk/aws-rds:noFailoverServerlessReaders]" + } + ], + "/EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/Subnets/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "DatabaseClusterPostgresqlSubnetsE0173DAA" + } + ], + "/EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/SecurityGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DatabaseClusterPostgresqlSecurityGroupEF4103D2" + } + ], + "/EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/Secret/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DatabaseClusterPostgresqlSecretD2D9C157" + } + ], + "/EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/Secret/Attachment/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DatabaseClusterPostgresqlSecretAttachment09D32DC9" + } + ], + "/EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DatabaseClusterPostgresql0775776E" + } + ], + "/EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/writerInstance/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DatabaseClusterPostgresqlwriterInstanceB16652DD" + } + ], + "/EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/readerInstance1/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DatabaseClusterPostgresqlreaderInstance10798C6B0" + } + ], "/EnableLocalWriteForwardingClusterStack/BootstrapVersion": [ { "type": "aws:cdk:logicalId", @@ -280,6 +329,7 @@ "templateFile": "EnableLocalWriteForwardingClusterStackIntegDefaultTestDeployAssertFA53AD26.template.json", "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "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}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/tree.json index 314d8de78118e..12fde79f29079 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.js.snapshot/tree.json @@ -980,6 +980,276 @@ "version": "10.3.0" } }, + "DatabaseClusterPostgresql": { + "id": "DatabaseClusterPostgresql", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql", + "children": { + "Subnets": { + "id": "Subnets", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/Subnets", + "children": { + "Default": { + "id": "Default", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/Subnets/Default", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::RDS::DBSubnetGroup", + "aws:cdk:cloudformation:props": { + "dbSubnetGroupDescription": "Subnets for DatabaseClusterPostgresql database", + "subnetIds": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "SecurityGroup": { + "id": "SecurityGroup", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/SecurityGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/SecurityGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "RDS security group", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "AuroraPostgreSqlDatabaseClusterEngineDefaultParameterGroup": { + "id": "AuroraPostgreSqlDatabaseClusterEngineDefaultParameterGroup", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/AuroraPostgreSqlDatabaseClusterEngineDefaultParameterGroup", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Secret": { + "id": "Secret", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/Secret", + "children": { + "Resource": { + "id": "Resource", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/Secret/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SecretsManager::Secret", + "aws:cdk:cloudformation:props": { + "description": { + "Fn::Join": [ + "", + [ + "Generated by the CDK for stack: ", + { + "Ref": "AWS::StackName" + } + ] + ] + }, + "generateSecretString": { + "passwordLength": 30, + "secretStringTemplate": "{\"username\":\"postgres\"}", + "generateStringKey": "password", + "excludeCharacters": " %+~`#$&*()|[]{}:;<>?!'/@\"\\" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Attachment": { + "id": "Attachment", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/Secret/Attachment", + "children": { + "Resource": { + "id": "Resource", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/Secret/Attachment/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SecretsManager::SecretTargetAttachment", + "aws:cdk:cloudformation:props": { + "secretId": { + "Ref": "DatabaseClusterPostgresqlSecretD2D9C157" + }, + "targetId": { + "Ref": "DatabaseClusterPostgresql0775776E" + }, + "targetType": "AWS::RDS::DBCluster" + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Resource": { + "id": "Resource", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::RDS::DBCluster", + "aws:cdk:cloudformation:props": { + "copyTagsToSnapshot": true, + "dbClusterParameterGroupName": "default.aurora-postgresql16", + "dbSubnetGroupName": { + "Ref": "DatabaseClusterPostgresqlSubnetsE0173DAA" + }, + "enableLocalWriteForwarding": true, + "engine": "aurora-postgresql", + "engineVersion": "16.4", + "masterUsername": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "DatabaseClusterPostgresqlSecretD2D9C157" + }, + ":SecretString:username::}}" + ] + ] + }, + "masterUserPassword": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "DatabaseClusterPostgresqlSecretD2D9C157" + }, + ":SecretString:password::}}" + ] + ] + }, + "port": 5432, + "serverlessV2ScalingConfiguration": { + "minCapacity": 0.5, + "maxCapacity": 2 + }, + "vpcSecurityGroupIds": [ + { + "Fn::GetAtt": [ + "DatabaseClusterPostgresqlSecurityGroupEF4103D2", + "GroupId" + ] + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "writerInstance": { + "id": "writerInstance", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/writerInstance", + "children": { + "Resource": { + "id": "Resource", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/writerInstance/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::RDS::DBInstance", + "aws:cdk:cloudformation:props": { + "dbClusterIdentifier": { + "Ref": "DatabaseClusterPostgresql0775776E" + }, + "dbInstanceClass": "db.serverless", + "engine": "aurora-postgresql", + "promotionTier": 0 + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "readerInstance1": { + "id": "readerInstance1", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/readerInstance1", + "children": { + "Resource": { + "id": "Resource", + "path": "EnableLocalWriteForwardingClusterStack/DatabaseClusterPostgresql/readerInstance1/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::RDS::DBInstance", + "aws:cdk:cloudformation:props": { + "dbClusterIdentifier": { + "Ref": "DatabaseClusterPostgresql0775776E" + }, + "dbInstanceClass": "db.serverless", + "engine": "aurora-postgresql", + "promotionTier": 2 + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "EnableLocalWriteForwardingClusterStack/BootstrapVersion", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.ts index b1aeb1e2933bd..08cad402491aa 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-enable-local-write-forwarding.ts @@ -18,6 +18,16 @@ new rds.DatabaseCluster(stack, 'DatabaseCluster', { enableLocalWriteForwarding: true, }); +new rds.DatabaseCluster(stack, 'DatabaseClusterPostgresql', { + engine: rds.DatabaseClusterEngine.auroraPostgres({ version: rds.AuroraPostgresEngineVersion.VER_16_4 }), + writer: rds.ClusterInstance.serverlessV2('writerInstance'), + readers: [ + rds.ClusterInstance.serverlessV2('readerInstance1'), + ], + vpc, + enableLocalWriteForwarding: true, +}); + new integ.IntegTest(app, 'EnableLocalWriteForwardingClusterStackInteg', { testCases: [stack], }); diff --git a/packages/aws-cdk-lib/aws-rds/README.md b/packages/aws-cdk-lib/aws-rds/README.md index fa356709f6bea..0119f877a3526 100644 --- a/packages/aws-cdk-lib/aws-rds/README.md +++ b/packages/aws-cdk-lib/aws-rds/README.md @@ -83,7 +83,8 @@ const cluster = new rds.DatabaseCluster(this, 'Database', { For more information about dual-stack mode, see [Working with a DB cluster in a VPC](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html). -If you want to issue read/write transactions directly on an Aurora Replica, you can use [local write forwarding](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-mysql-write-forwarding.html). +If you want to issue read/write transactions directly on an Aurora Replica, you can use local write forwarding on [Aurora MySQL](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-mysql-write-forwarding.html) +and [Aurora PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-postgresql-write-forwarding.html). Local write forwarding allows read replicas to accept write transactions and forward them to the writer DB instance to be committed. To enable local write forwarding, set the `enableLocalWriteForwarding` property to `true`: @@ -102,7 +103,8 @@ new rds.DatabaseCluster(this, 'DatabaseCluster', { }); ``` -**Note**: Local write forwarding is only supported for Aurora MySQL 3.04 and higher. +**Note**: Local write forwarding is supported only for Aurora MySQL 3.04 or higher, and for Aurora PostgreSQL +16.4 or higher (for version 16), 15.8 or higher (for version 15), and 14.13 or higher (for version 14). Use `DatabaseClusterFromSnapshot` to create a cluster from a snapshot: diff --git a/packages/aws-cdk-lib/aws-rds/lib/cluster.ts b/packages/aws-cdk-lib/aws-rds/lib/cluster.ts index 54f47062b3eb6..497447811fbad 100644 --- a/packages/aws-cdk-lib/aws-rds/lib/cluster.ts +++ b/packages/aws-cdk-lib/aws-rds/lib/cluster.ts @@ -389,9 +389,11 @@ interface DatabaseClusterBaseProps { /** * Whether read replicas can forward write operations to the writer DB instance in the DB cluster. * - * This setting can only be enabled for Aurora MySQL 3.04 and higher clusters. + * This setting can only be enabled for Aurora MySQL 3.04 or higher, and for Aurora PostgreSQL 16.4 + * or higher (for version 16), 15.8 or higher (for version 15), and 14.13 or higher (for version 14). * * @see https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-mysql-write-forwarding.html + * @see https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-postgresql-write-forwarding.html * * @default false */ @@ -737,11 +739,6 @@ abstract class DatabaseClusterNew extends DatabaseClusterBase { }); } - // enableLocalWriteForwarding cannot be configured, including false, on Aurora clusters other than MySQL. - if (props.enableLocalWriteForwarding !== undefined && !['aurora', 'aurora-mysql'].includes(props.engine.engineType)) { - throw new Error(`\'enableLocalWriteForwarding\' is only supported for Aurora Mysql cluster engine type, got: ${props.engine.engineType}`); - } - const enablePerformanceInsights = props.enablePerformanceInsights || props.performanceInsightRetention !== undefined || props.performanceInsightEncryptionKey !== undefined; if (enablePerformanceInsights && props.enablePerformanceInsights === false) { diff --git a/packages/aws-cdk-lib/aws-rds/test/cluster.test.ts b/packages/aws-cdk-lib/aws-rds/test/cluster.test.ts index abf1deb1382f3..a76cbb8ffcb7f 100644 --- a/packages/aws-cdk-lib/aws-rds/test/cluster.test.ts +++ b/packages/aws-cdk-lib/aws-rds/test/cluster.test.ts @@ -16,6 +16,7 @@ import { AuroraEngineVersion, AuroraMysqlEngineVersion, AuroraPostgresEngineVersion, CfnDBCluster, Credentials, DatabaseCluster, DatabaseClusterEngine, DatabaseClusterFromSnapshot, ParameterGroup, PerformanceInsightRetention, SubnetGroup, DatabaseSecret, DatabaseInstanceEngine, SqlServerEngineVersion, SnapshotCredentials, InstanceUpdateBehaviour, NetworkType, ClusterInstance, CaCertificate, + IClusterEngine, } from '../lib'; describe('cluster new api', () => { @@ -176,41 +177,26 @@ describe('cluster new api', () => { }); }); - describe('enableLocalWriteForwarding', () => { - test('set enableLocalWriteForwarding', () => { - // GIVEN - const stack = testStack(); - const vpc = new ec2.Vpc(stack, 'VPC'); - - // WHEN - new DatabaseCluster(stack, 'Database', { - engine: DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_3_07_0 }), - vpc, - enableLocalWriteForwarding: true, - writer: ClusterInstance.serverlessV2('writer'), - }); + test.each([ + ['MySQL', DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_3_07_0 })], + ['PostgreSQL', DatabaseClusterEngine.auroraPostgres({ version: AuroraPostgresEngineVersion.VER_16_4 })], + ])('set enableLocalWriteForwarding for aurora %s', (type: string, engine: IClusterEngine) => { + // GIVEN + const stack = testStack(); + const vpc = new ec2.Vpc(stack, 'VPC'); - // THEN - const template = Template.fromStack(stack); - template.hasResourceProperties('AWS::RDS::DBCluster', { - EnableLocalWriteForwarding: true, - }); + // WHEN + new DatabaseCluster(stack, type, { + engine, + vpc, + enableLocalWriteForwarding: true, + writer: ClusterInstance.serverlessV2('writer'), }); - test.each([true, false])('throw error for enableLocalWriteForwarding with aurora postgresql cluster', (enableLocalWriteForwarding) => { - // GIVEN - const stack = testStack(); - const vpc = new ec2.Vpc(stack, 'VPC'); - - // WHEN - expect(() => { - new DatabaseCluster(stack, 'Database', { - engine: DatabaseClusterEngine.auroraPostgres({ version: AuroraPostgresEngineVersion.VER_16_3 }), - vpc, - enableLocalWriteForwarding, - writer: ClusterInstance.serverlessV2('writer'), - }); - }).toThrow('\'enableLocalWriteForwarding\' is only supported for Aurora Mysql cluster engine type, got: aurora-postgresql'); + // THEN + const template = Template.fromStack(stack); + template.hasResourceProperties('AWS::RDS::DBCluster', { + EnableLocalWriteForwarding: true, }); });