diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/aws-cdk-rds-cluster-lookup.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/aws-cdk-rds-cluster-lookup.assets.json new file mode 100644 index 0000000000000..e6d6015395853 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/aws-cdk-rds-cluster-lookup.assets.json @@ -0,0 +1,21 @@ +{ + "version": "44.0.0", + "files": { + "3bcd33e34603726e169ff4992b9678ec0884d78fef8095e40d73af38bf81fe04": { + "displayName": "aws-cdk-rds-cluster-lookup Template", + "source": { + "path": "aws-cdk-rds-cluster-lookup.template.json", + "packaging": "file" + }, + "destinations": { + "12345678-test-region": { + "bucketName": "cdk-hnb659fds-assets-12345678-test-region", + "objectKey": "3bcd33e34603726e169ff4992b9678ec0884d78fef8095e40d73af38bf81fe04.json", + "region": "test-region", + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-file-publishing-role-12345678-test-region" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/aws-cdk-rds-cluster-lookup.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/aws-cdk-rds-cluster-lookup.template.json new file mode 100644 index 0000000000000..a6deb496aef8c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/aws-cdk-rds-cluster-lookup.template.json @@ -0,0 +1,217 @@ +{ + "Outputs": { + "LookedUpClusterEndpoint": { + "Value": "TESTADDRESS:5432" + }, + "LookedUpClusterReadEndpoint": { + "Value": "TESTREADERADDRESS:5432" + }, + "LookedUpClusterIdentifier": { + "Value": "test-cluster-lookup" + }, + "LookedUpClusterResourceIdentifier": { + "Value": "TESTID" + }, + "LookedUpClusterArn": { + "Value": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":rds:test-region:12345678:cluster:test-cluster-lookup" + ] + ] + } + }, + "SecurityGroupIds": { + "Value": "" + } + }, + "Resources": { + "DbAccessRole408BD73D": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "Description": "Role for accessing the Aurora cluster via IAM authentication" + } + }, + "DbAccessRoleDefaultPolicy8020DC70": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "rds-db:connect", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":rds-db:test-region:12345678:dbuser:TESTID/admin" + ] + ] + } + }, + { + "Action": [ + "rds-data:BatchExecuteStatement", + "rds-data:BeginTransaction", + "rds-data:CommitTransaction", + "rds-data:ExecuteStatement", + "rds-data:RollbackTransaction" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":rds:test-region:12345678:cluster:test-cluster-lookup" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "DbAccessRoleDefaultPolicy8020DC70", + "Roles": [ + { + "Ref": "DbAccessRole408BD73D" + } + ] + } + }, + "HighConnectionsAlarm3E20B33C": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "AlarmDescription": "Database has high number of connections", + "ComparisonOperator": "GreaterThanThreshold", + "Dimensions": [ + { + "Name": "DBClusterIdentifier", + "Value": "test-cluster-lookup" + } + ], + "EvaluationPeriods": 3, + "MetricName": "DatabaseConnections", + "Namespace": "AWS/RDS", + "Period": 300, + "Statistic": "Average", + "Threshold": 100 + } + }, + "HighCPUAlarm56BE6E7D": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "AlarmDescription": "Database CPU utilization is high", + "ComparisonOperator": "GreaterThanThreshold", + "Dimensions": [ + { + "Name": "DBClusterIdentifier", + "Value": "test-cluster-lookup" + } + ], + "EvaluationPeriods": 3, + "MetricName": "CPUUtilization", + "Namespace": "AWS/RDS", + "Period": 300, + "Statistic": "Average", + "Threshold": 90 + } + }, + "LowMemoryAlarmD9E02E14": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "AlarmDescription": "Database is running low on memory", + "ComparisonOperator": "LessThanThreshold", + "Dimensions": [ + { + "Name": "DBClusterIdentifier", + "Value": "test-cluster-lookup" + } + ], + "EvaluationPeriods": 3, + "MetricName": "FreeableMemory", + "Namespace": "AWS/RDS", + "Period": 300, + "Statistic": "Average", + "Threshold": 104857600 + } + }, + "DeadlockAlarmC7257573": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "AlarmDescription": "Database has deadlocks", + "ComparisonOperator": "GreaterThanThreshold", + "Dimensions": [ + { + "Name": "DBClusterIdentifier", + "Value": "test-cluster-lookup" + } + ], + "EvaluationPeriods": 2, + "MetricName": "Deadlocks", + "Namespace": "AWS/RDS", + "Period": 300, + "Statistic": "Average", + "Threshold": 5 + } + } + }, + "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.cluster-lookup.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/cdk.out new file mode 100644 index 0000000000000..b3a26d44a5f73 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"44.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/integ.json new file mode 100644 index 0000000000000..453657c13a503 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/integ.json @@ -0,0 +1,26 @@ +{ + "enableLookups": true, + "version": "44.0.0", + "testCases": { + "integ-rds-cluster-from-lookup/DefaultTest": { + "stacks": [ + "aws-cdk-rds-cluster-lookup" + ], + "hooks": { + "preDeploy": [ + "aws rds create-db-cluster --db-cluster-identifier test-cluster-lookup --engine aurora-mysql --engine-version 8.0.mysql_aurora.3.09.0 --master-username admin --master-user-password Admin1234 --enable-http-endpoint --enable-iam-database-authentication --region us-east-1", + "aws rds create-db-instance --db-instance-identifier test-cluster-lookup-instance --db-cluster-identifier test-cluster-lookup --engine aurora-mysql --db-instance-class db.r5.large --region us-east-1", + "aws rds wait db-instance-available --db-instance-identifier test-cluster-lookup-instance --region us-east-1" + ], + "postDeploy": [ + "aws rds delete-db-instance --db-instance-identifier test-cluster-lookup-instance --skip-final-snapshot --region us-east-1", + "aws rds delete-db-cluster --db-cluster-identifier test-cluster-lookup --skip-final-snapshot --region us-east-1" + ] + }, + "stackUpdateWorkflow": false, + "assertionStack": "integ-rds-cluster-from-lookup/DefaultTest/DeployAssert", + "assertionStackName": "integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886" + } + }, + "minimumCliVersion": "2.1019.2" +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886.assets.json new file mode 100644 index 0000000000000..853c784dae94c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886.assets.json @@ -0,0 +1,20 @@ +{ + "version": "44.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "displayName": "integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886 Template", + "source": { + "path": "integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886.template.json @@ -0,0 +1,36 @@ +{ + "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.cluster-lookup.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/manifest.json new file mode 100644 index 0000000000000..75fc805a4a695 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/manifest.json @@ -0,0 +1,384 @@ +{ + "version": "44.0.0", + "artifacts": { + "aws-cdk-rds-cluster-lookup.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-cdk-rds-cluster-lookup.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-cdk-rds-cluster-lookup": { + "type": "aws:cloudformation:stack", + "environment": "aws://12345678/test-region", + "properties": { + "templateFile": "aws-cdk-rds-cluster-lookup.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-deploy-role-12345678-test-region", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-cfn-exec-role-12345678-test-region", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-12345678-test-region/3bcd33e34603726e169ff4992b9678ec0884d78fef8095e40d73af38bf81fe04.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-cdk-rds-cluster-lookup.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-lookup-role-12345678-test-region", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-cdk-rds-cluster-lookup.assets" + ], + "metadata": { + "/aws-cdk-rds-cluster-lookup/LookedUpCluster": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + } + ], + "/aws-cdk-rds-cluster-lookup/LookedUpClusterEndpoint": [ + { + "type": "aws:cdk:logicalId", + "data": "LookedUpClusterEndpoint" + } + ], + "/aws-cdk-rds-cluster-lookup/LookedUpClusterReadEndpoint": [ + { + "type": "aws:cdk:logicalId", + "data": "LookedUpClusterReadEndpoint" + } + ], + "/aws-cdk-rds-cluster-lookup/LookedUpClusterIdentifier": [ + { + "type": "aws:cdk:logicalId", + "data": "LookedUpClusterIdentifier" + } + ], + "/aws-cdk-rds-cluster-lookup/LookedUpClusterResourceIdentifier": [ + { + "type": "aws:cdk:logicalId", + "data": "LookedUpClusterResourceIdentifier" + } + ], + "/aws-cdk-rds-cluster-lookup/LookedUpClusterArn": [ + { + "type": "aws:cdk:logicalId", + "data": "LookedUpClusterArn" + } + ], + "/aws-cdk-rds-cluster-lookup/SecurityGroupIds": [ + { + "type": "aws:cdk:logicalId", + "data": "SecurityGroupIds" + } + ], + "/aws-cdk-rds-cluster-lookup/DbAccessRole": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "assumedBy": { + "principalAccount": "*", + "assumeRoleAction": "*" + }, + "description": "*" + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addToPrincipalPolicy": [ + {} + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachInlinePolicy": [ + "*" + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachInlinePolicy": [ + "*" + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addToPrincipalPolicy": [ + {} + ] + } + } + ], + "/aws-cdk-rds-cluster-lookup/DbAccessRole/ImportDbAccessRole": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + } + ], + "/aws-cdk-rds-cluster-lookup/DbAccessRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DbAccessRole408BD73D" + } + ], + "/aws-cdk-rds-cluster-lookup/DbAccessRole/DefaultPolicy": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachToRole": [ + "*" + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachToRole": [ + "*" + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addStatements": [ + {} + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addStatements": [ + {} + ] + } + } + ], + "/aws-cdk-rds-cluster-lookup/DbAccessRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DbAccessRoleDefaultPolicy8020DC70" + } + ], + "/aws-cdk-rds-cluster-lookup/HighConnectionsAlarm": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "metric": { + "warnings": "*" + }, + "alarmName": "*", + "alarmDescription": "*", + "comparisonOperator": "*", + "datapointsToAlarm": "*", + "threshold": "*", + "evaluationPeriods": "*", + "evaluateLowSampleCountPercentile": "*", + "treatMissingData": "*", + "actionsEnabled": "*" + } + } + ], + "/aws-cdk-rds-cluster-lookup/HighConnectionsAlarm/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "HighConnectionsAlarm3E20B33C" + } + ], + "/aws-cdk-rds-cluster-lookup/HighCPUAlarm": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "metric": { + "warnings": "*" + }, + "alarmName": "*", + "alarmDescription": "*", + "comparisonOperator": "*", + "datapointsToAlarm": "*", + "threshold": "*", + "evaluationPeriods": "*", + "evaluateLowSampleCountPercentile": "*", + "treatMissingData": "*", + "actionsEnabled": "*" + } + } + ], + "/aws-cdk-rds-cluster-lookup/HighCPUAlarm/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "HighCPUAlarm56BE6E7D" + } + ], + "/aws-cdk-rds-cluster-lookup/LowMemoryAlarm": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "metric": { + "warnings": "*" + }, + "alarmName": "*", + "alarmDescription": "*", + "comparisonOperator": "*", + "datapointsToAlarm": "*", + "threshold": "*", + "evaluationPeriods": "*", + "evaluateLowSampleCountPercentile": "*", + "treatMissingData": "*", + "actionsEnabled": "*" + } + } + ], + "/aws-cdk-rds-cluster-lookup/LowMemoryAlarm/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LowMemoryAlarmD9E02E14" + } + ], + "/aws-cdk-rds-cluster-lookup/DeadlockAlarm": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "metric": { + "warnings": "*" + }, + "alarmName": "*", + "alarmDescription": "*", + "comparisonOperator": "*", + "datapointsToAlarm": "*", + "threshold": "*", + "evaluationPeriods": "*", + "evaluateLowSampleCountPercentile": "*", + "treatMissingData": "*", + "actionsEnabled": "*" + } + } + ], + "/aws-cdk-rds-cluster-lookup/DeadlockAlarm/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DeadlockAlarmC7257573" + } + ], + "/aws-cdk-rds-cluster-lookup/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-rds-cluster-lookup/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-rds-cluster-lookup" + }, + "integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886.template.json", + "terminationProtection": false, + "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}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "integrdsclusterfromlookupDefaultTestDeployAssert0EEE7886.assets" + ], + "metadata": { + "/integ-rds-cluster-from-lookup/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-rds-cluster-from-lookup/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integ-rds-cluster-from-lookup/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + }, + "missing": [ + { + "key": "cc-api-provider:account=12345678:exactIdentifier=test-cluster-lookup:propertiesToReturn.0=DBClusterArn:propertiesToReturn.1=Endpoint.Address:propertiesToReturn.2=Endpoint.Port:propertiesToReturn.3=ReadEndpoint.Address:propertiesToReturn.4=DBClusterResourceId:propertiesToReturn.5=VpcSecurityGroupIds:propertiesToReturn.6=EnableHttpEndpoint:region=test-region:typeName=AWS$:$:RDS$:$:DBCluster", + "provider": "cc-api-provider", + "props": { + "dummyValue": [ + { + "Identifier": "TEST", + "DBClusterArn": "TESTARN", + "Endpoint.Address": "TESTADDRESS", + "Endpoint.Port": "5432", + "ReadEndpoint.Address": "TESTREADERADDRESS", + "DBClusterResourceId": "TESTID", + "VpcSecurityGroupIds": [], + "EnableHttpEndpoint": true + } + ], + "account": "12345678", + "region": "test-region", + "typeName": "AWS::RDS::DBCluster", + "exactIdentifier": "test-cluster-lookup", + "propertiesToReturn": [ + "DBClusterArn", + "Endpoint.Address", + "Endpoint.Port", + "ReadEndpoint.Address", + "DBClusterResourceId", + "VpcSecurityGroupIds", + "EnableHttpEndpoint" + ], + "lookupRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-lookup-role-12345678-test-region" + } + } + ], + "minimumCliVersion": "2.1019.2" +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/tree.json new file mode 100644 index 0000000000000..c6929cca23abf --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.js.snapshot/tree.json @@ -0,0 +1 @@ +{"version":"tree-0.1","tree":{"id":"App","path":"","constructInfo":{"fqn":"aws-cdk-lib.App","version":"0.0.0"},"children":{"aws-cdk-rds-cluster-lookup":{"id":"aws-cdk-rds-cluster-lookup","path":"aws-cdk-rds-cluster-lookup","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"LookedUpCluster":{"id":"LookedUpCluster","path":"aws-cdk-rds-cluster-lookup/LookedUpCluster","constructInfo":{"fqn":"aws-cdk-lib.aws_rds.DatabaseClusterBase","version":"0.0.0","metadata":["*"]}},"LookedUpClusterEndpoint":{"id":"LookedUpClusterEndpoint","path":"aws-cdk-rds-cluster-lookup/LookedUpClusterEndpoint","constructInfo":{"fqn":"aws-cdk-lib.CfnOutput","version":"0.0.0"}},"LookedUpClusterReadEndpoint":{"id":"LookedUpClusterReadEndpoint","path":"aws-cdk-rds-cluster-lookup/LookedUpClusterReadEndpoint","constructInfo":{"fqn":"aws-cdk-lib.CfnOutput","version":"0.0.0"}},"LookedUpClusterIdentifier":{"id":"LookedUpClusterIdentifier","path":"aws-cdk-rds-cluster-lookup/LookedUpClusterIdentifier","constructInfo":{"fqn":"aws-cdk-lib.CfnOutput","version":"0.0.0"}},"LookedUpClusterResourceIdentifier":{"id":"LookedUpClusterResourceIdentifier","path":"aws-cdk-rds-cluster-lookup/LookedUpClusterResourceIdentifier","constructInfo":{"fqn":"aws-cdk-lib.CfnOutput","version":"0.0.0"}},"LookedUpClusterArn":{"id":"LookedUpClusterArn","path":"aws-cdk-rds-cluster-lookup/LookedUpClusterArn","constructInfo":{"fqn":"aws-cdk-lib.CfnOutput","version":"0.0.0"}},"SecurityGroupIds":{"id":"SecurityGroupIds","path":"aws-cdk-rds-cluster-lookup/SecurityGroupIds","constructInfo":{"fqn":"aws-cdk-lib.CfnOutput","version":"0.0.0"}},"DbAccessRole":{"id":"DbAccessRole","path":"aws-cdk-rds-cluster-lookup/DbAccessRole","constructInfo":{"fqn":"aws-cdk-lib.aws_iam.Role","version":"0.0.0","metadata":[{"assumedBy":{"principalAccount":"*","assumeRoleAction":"*"},"description":"*"},{"addToPrincipalPolicy":[{}]},{"attachInlinePolicy":["*"]},{"attachInlinePolicy":["*"]},{"addToPrincipalPolicy":[{}]}]},"children":{"ImportDbAccessRole":{"id":"ImportDbAccessRole","path":"aws-cdk-rds-cluster-lookup/DbAccessRole/ImportDbAccessRole","constructInfo":{"fqn":"aws-cdk-lib.Resource","version":"0.0.0","metadata":["*"]}},"Resource":{"id":"Resource","path":"aws-cdk-rds-cluster-lookup/DbAccessRole/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_iam.CfnRole","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::IAM::Role","aws:cdk:cloudformation:props":{"assumeRolePolicyDocument":{"Statement":[{"Action":"sts:AssumeRole","Effect":"Allow","Principal":{"Service":"ec2.amazonaws.com"}}],"Version":"2012-10-17"},"description":"Role for accessing the Aurora cluster via IAM authentication"}}},"DefaultPolicy":{"id":"DefaultPolicy","path":"aws-cdk-rds-cluster-lookup/DbAccessRole/DefaultPolicy","constructInfo":{"fqn":"aws-cdk-lib.aws_iam.Policy","version":"0.0.0","metadata":["*",{"attachToRole":["*"]},{"attachToRole":["*"]},{"addStatements":[{}]},{"addStatements":[{}]}]},"children":{"Resource":{"id":"Resource","path":"aws-cdk-rds-cluster-lookup/DbAccessRole/DefaultPolicy/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_iam.CfnPolicy","version":"0.0.0"},"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:test-region:12345678:dbuser:TESTID/admin"]]}},{"Action":["rds-data:BatchExecuteStatement","rds-data:BeginTransaction","rds-data:CommitTransaction","rds-data:ExecuteStatement","rds-data:RollbackTransaction"],"Effect":"Allow","Resource":{"Fn::Join":["",["arn:",{"Ref":"AWS::Partition"},":rds:test-region:12345678:cluster:test-cluster-lookup"]]}}],"Version":"2012-10-17"},"policyName":"DbAccessRoleDefaultPolicy8020DC70","roles":[{"Ref":"DbAccessRole408BD73D"}]}}}}}}},"HighConnectionsAlarm":{"id":"HighConnectionsAlarm","path":"aws-cdk-rds-cluster-lookup/HighConnectionsAlarm","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.Alarm","version":"0.0.0","metadata":[{"metric":{"warnings":"*"},"alarmName":"*","alarmDescription":"*","comparisonOperator":"*","datapointsToAlarm":"*","threshold":"*","evaluationPeriods":"*","evaluateLowSampleCountPercentile":"*","treatMissingData":"*","actionsEnabled":"*"}]},"children":{"Resource":{"id":"Resource","path":"aws-cdk-rds-cluster-lookup/HighConnectionsAlarm/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.CfnAlarm","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::CloudWatch::Alarm","aws:cdk:cloudformation:props":{"alarmDescription":"Database has high number of connections","comparisonOperator":"GreaterThanThreshold","dimensions":[{"name":"DBClusterIdentifier","value":"test-cluster-lookup"}],"evaluationPeriods":3,"metricName":"DatabaseConnections","namespace":"AWS/RDS","period":300,"statistic":"Average","threshold":100}}}}},"HighCPUAlarm":{"id":"HighCPUAlarm","path":"aws-cdk-rds-cluster-lookup/HighCPUAlarm","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.Alarm","version":"0.0.0","metadata":[{"metric":{"warnings":"*"},"alarmName":"*","alarmDescription":"*","comparisonOperator":"*","datapointsToAlarm":"*","threshold":"*","evaluationPeriods":"*","evaluateLowSampleCountPercentile":"*","treatMissingData":"*","actionsEnabled":"*"}]},"children":{"Resource":{"id":"Resource","path":"aws-cdk-rds-cluster-lookup/HighCPUAlarm/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.CfnAlarm","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::CloudWatch::Alarm","aws:cdk:cloudformation:props":{"alarmDescription":"Database CPU utilization is high","comparisonOperator":"GreaterThanThreshold","dimensions":[{"name":"DBClusterIdentifier","value":"test-cluster-lookup"}],"evaluationPeriods":3,"metricName":"CPUUtilization","namespace":"AWS/RDS","period":300,"statistic":"Average","threshold":90}}}}},"LowMemoryAlarm":{"id":"LowMemoryAlarm","path":"aws-cdk-rds-cluster-lookup/LowMemoryAlarm","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.Alarm","version":"0.0.0","metadata":[{"metric":{"warnings":"*"},"alarmName":"*","alarmDescription":"*","comparisonOperator":"*","datapointsToAlarm":"*","threshold":"*","evaluationPeriods":"*","evaluateLowSampleCountPercentile":"*","treatMissingData":"*","actionsEnabled":"*"}]},"children":{"Resource":{"id":"Resource","path":"aws-cdk-rds-cluster-lookup/LowMemoryAlarm/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.CfnAlarm","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::CloudWatch::Alarm","aws:cdk:cloudformation:props":{"alarmDescription":"Database is running low on memory","comparisonOperator":"LessThanThreshold","dimensions":[{"name":"DBClusterIdentifier","value":"test-cluster-lookup"}],"evaluationPeriods":3,"metricName":"FreeableMemory","namespace":"AWS/RDS","period":300,"statistic":"Average","threshold":104857600}}}}},"DeadlockAlarm":{"id":"DeadlockAlarm","path":"aws-cdk-rds-cluster-lookup/DeadlockAlarm","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.Alarm","version":"0.0.0","metadata":[{"metric":{"warnings":"*"},"alarmName":"*","alarmDescription":"*","comparisonOperator":"*","datapointsToAlarm":"*","threshold":"*","evaluationPeriods":"*","evaluateLowSampleCountPercentile":"*","treatMissingData":"*","actionsEnabled":"*"}]},"children":{"Resource":{"id":"Resource","path":"aws-cdk-rds-cluster-lookup/DeadlockAlarm/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.CfnAlarm","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::CloudWatch::Alarm","aws:cdk:cloudformation:props":{"alarmDescription":"Database has deadlocks","comparisonOperator":"GreaterThanThreshold","dimensions":[{"name":"DBClusterIdentifier","value":"test-cluster-lookup"}],"evaluationPeriods":2,"metricName":"Deadlocks","namespace":"AWS/RDS","period":300,"statistic":"Average","threshold":5}}}}},"BootstrapVersion":{"id":"BootstrapVersion","path":"aws-cdk-rds-cluster-lookup/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"aws-cdk-rds-cluster-lookup/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}},"integ-rds-cluster-from-lookup":{"id":"integ-rds-cluster-from-lookup","path":"integ-rds-cluster-from-lookup","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTest","version":"0.0.0"},"children":{"DefaultTest":{"id":"DefaultTest","path":"integ-rds-cluster-from-lookup/DefaultTest","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTestCase","version":"0.0.0"},"children":{"Default":{"id":"Default","path":"integ-rds-cluster-from-lookup/DefaultTest/Default","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"DeployAssert":{"id":"DeployAssert","path":"integ-rds-cluster-from-lookup/DefaultTest/DeployAssert","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"BootstrapVersion":{"id":"BootstrapVersion","path":"integ-rds-cluster-from-lookup/DefaultTest/DeployAssert/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"integ-rds-cluster-from-lookup/DefaultTest/DeployAssert/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}}}}}},"Tree":{"id":"Tree","path":"Tree","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}}}} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.ts new file mode 100644 index 0000000000000..6ac36e08cc020 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-lookup.ts @@ -0,0 +1,100 @@ +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import { App, CfnOutput, Stack } from 'aws-cdk-lib'; +import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch'; +import * as iam from 'aws-cdk-lib/aws-iam'; +import * as rds from 'aws-cdk-lib/aws-rds'; + +const app = new App(); +const clusterIdentifier = 'test-cluster-lookup'; + +const stackLookup = new Stack(app, 'aws-cdk-rds-cluster-lookup', { + env: { + account: process.env.CDK_INTEG_ACCOUNT ?? process.env.CDK_DEFAULT_ACCOUNT, + region: process.env.CDK_INTEG_REGION ?? process.env.CDK_DEFAULT_REGION, + }, +}); + +// Lookup the existing cluster created by the preDeploy hook +const lookedUpCluster = rds.DatabaseCluster.fromLookup(stackLookup, 'LookedUpCluster', { + clusterIdentifier, +}); + +new CfnOutput(stackLookup, 'LookedUpClusterEndpoint', { + value: lookedUpCluster.clusterEndpoint.socketAddress, +}); + +new CfnOutput(stackLookup, 'LookedUpClusterReadEndpoint', { + value: lookedUpCluster.clusterReadEndpoint.socketAddress, +}); + +new CfnOutput(stackLookup, 'LookedUpClusterIdentifier', { + value: lookedUpCluster.clusterIdentifier, +}); + +new CfnOutput(stackLookup, 'LookedUpClusterResourceIdentifier', { + value: lookedUpCluster.clusterResourceIdentifier, +}); + +new CfnOutput(stackLookup, 'LookedUpClusterArn', { + value: lookedUpCluster.clusterArn, +}); + +new CfnOutput(stackLookup, 'SecurityGroupIds', { + value: lookedUpCluster.connections.securityGroups.map(sg => sg.securityGroupId).join(','), +}); + +// test grant +const dbAccessRole = new iam.Role(stackLookup, 'DbAccessRole', { + assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'), + description: 'Role for accessing the Aurora cluster via IAM authentication', +}); + +lookedUpCluster.grantConnect(dbAccessRole, 'admin'); +lookedUpCluster.grantDataApiAccess(dbAccessRole); + +// test metric +lookedUpCluster.metricDatabaseConnections().createAlarm(stackLookup, 'HighConnectionsAlarm', { + threshold: 100, + evaluationPeriods: 3, + alarmDescription: 'Database has high number of connections', + comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD, +}); + +lookedUpCluster.metricCPUUtilization().createAlarm(stackLookup, 'HighCPUAlarm', { + threshold: 90, + evaluationPeriods: 3, + alarmDescription: 'Database CPU utilization is high', + comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD, +}); + +lookedUpCluster.metricFreeableMemory().createAlarm(stackLookup, 'LowMemoryAlarm', { + threshold: 100 * 1024 * 1024, + evaluationPeriods: 3, + alarmDescription: 'Database is running low on memory', + comparisonOperator: cloudwatch.ComparisonOperator.LESS_THAN_THRESHOLD, +}); + +lookedUpCluster.metricDeadlocks().createAlarm(stackLookup, 'DeadlockAlarm', { + threshold: 5, + evaluationPeriods: 2, + alarmDescription: 'Database has deadlocks', + comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD, +}); + +new IntegTest(app, 'integ-rds-cluster-from-lookup', { + testCases: [stackLookup], + enableLookups: true, + stackUpdateWorkflow: false, + // Create Aurora cluster before the test and delete it after + hooks: { + preDeploy: [ + `aws rds create-db-cluster --db-cluster-identifier ${clusterIdentifier} --engine aurora-mysql --engine-version 8.0.mysql_aurora.3.09.0 --master-username admin --master-user-password Admin1234 --enable-http-endpoint --enable-iam-database-authentication --region us-east-1`, + `aws rds create-db-instance --db-instance-identifier ${clusterIdentifier}-instance --db-cluster-identifier ${clusterIdentifier} --engine aurora-mysql --db-instance-class db.r5.large --region us-east-1`, + `aws rds wait db-instance-available --db-instance-identifier ${clusterIdentifier}-instance --region us-east-1`, + ], + postDeploy: [ + `aws rds delete-db-instance --db-instance-identifier ${clusterIdentifier}-instance --skip-final-snapshot --region us-east-1`, + `aws rds delete-db-cluster --db-cluster-identifier ${clusterIdentifier} --skip-final-snapshot --region us-east-1`, + ], + }, +}); diff --git a/packages/aws-cdk-lib/aws-rds/README.md b/packages/aws-cdk-lib/aws-rds/README.md index f12158f4bc273..9eb737e7c638d 100644 --- a/packages/aws-cdk-lib/aws-rds/README.md +++ b/packages/aws-cdk-lib/aws-rds/README.md @@ -1605,6 +1605,25 @@ const dbFromLookup = rds.DatabaseInstance.fromLookup(this, 'dbFromLookup', { dbFromLookup.grantConnect(myUserRole, 'my-user-id'); ``` +## Importing existing DatabaseCluster + +### Lookup DatabaseCluster by clusterIdentifier + +You can lookup an existing DatabaseCluster by its clusterIdentifier using `DatabaseCluster.fromLookup()`. This method returns an `IDatabaseCluster`. + +Here's how `DatabaseCluster.fromLookup()` can be used: + +```ts +declare const myUserRole: iam.Role; + +const clusterFromLookup = rds.DatabaseCluster.fromLookup(this, 'ClusterFromLookup', { + clusterIdentifier: 'my-cluster-id', +}); + +// Grant a connection +clusterFromLookup.grantConnect(myUserRole, 'my-user-id'); +``` + ## Limitless Database Cluster Amazon Aurora [PostgreSQL Limitless Database](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/limitless.html) provides automated horizontal scaling to process millions of write transactions per second and manages petabytes of data while maintaining the simplicity of operating inside a single database. diff --git a/packages/aws-cdk-lib/aws-rds/lib/cluster.ts b/packages/aws-cdk-lib/aws-rds/lib/cluster.ts index 9d565522027ed..4fe6a1f9c3d09 100644 --- a/packages/aws-cdk-lib/aws-rds/lib/cluster.ts +++ b/packages/aws-cdk-lib/aws-rds/lib/cluster.ts @@ -20,8 +20,9 @@ import * as kms from '../../aws-kms'; import * as logs from '../../aws-logs'; import * as s3 from '../../aws-s3'; import * as secretsmanager from '../../aws-secretsmanager'; -import { Annotations, ArnFormat, Duration, FeatureFlags, Lazy, RemovalPolicy, Resource, Stack, Token, TokenComparison } from '../../core'; -import { ValidationError } from '../../core/lib/errors'; +import * as cxschema from '../../cloud-assembly-schema'; +import { Annotations, ArnFormat, ContextProvider, Duration, FeatureFlags, Lazy, RemovalPolicy, Resource, Stack, Token, TokenComparison } from '../../core'; +import { UnscopedValidationError, ValidationError } from '../../core/lib/errors'; import { addConstructMetadata } from '../../core/lib/metadata-resource'; import { propertyInjectable } from '../../core/lib/prop-injectable'; import * as cxapi from '../../cx-api'; @@ -586,6 +587,16 @@ export enum DatabaseInsightsMode { ADVANCED = 'advanced', } +/** + * Properties for looking up an existing DatabaseCluster. + */ +export interface DatabaseClusterLookupOptions { + /** + * The cluster identifier of the DatabaseCluster + */ + readonly clusterIdentifier: string; +} + /** * A new or imported clustered database. */ @@ -1335,6 +1346,69 @@ export class DatabaseCluster extends DatabaseClusterNew { */ public static readonly PROPERTY_INJECTION_ID: string = 'aws-cdk-lib.aws-rds.DatabaseCluster'; + /** + * Lookup an existing DatabaseCluster using clusterIdentifier. + */ + public static fromLookup(scope: Construct, id: string, options: DatabaseClusterLookupOptions): IDatabaseCluster { + if (Token.isUnresolved(options.clusterIdentifier)) { + throw new UnscopedValidationError('Cannot look up a cluster with a tokenized cluster identifier.'); + } + const response: {[key: string]: any}[] = ContextProvider.getValue(scope, { + provider: cxschema.ContextProvider.CC_API_PROVIDER, + props: { + typeName: 'AWS::RDS::DBCluster', + exactIdentifier: options.clusterIdentifier, + propertiesToReturn: [ + 'DBClusterArn', + 'Endpoint.Address', + 'Endpoint.Port', + 'ReadEndpoint.Address', + 'DBClusterResourceId', + 'VpcSecurityGroupIds', + 'EnableHttpEndpoint', + ], + } as cxschema.CcApiContextQuery, + dummyValue: [ + { + 'Identifier': 'TEST', + 'DBClusterArn': 'TESTARN', + 'Endpoint.Address': 'TESTADDRESS', + 'Endpoint.Port': '5432', + 'ReadEndpoint.Address': 'TESTREADERADDRESS', + 'DBClusterResourceId': 'TESTID', + 'VpcSecurityGroupIds': [], + 'EnableHttpEndpoint': true, + }, + ], + }).value; + + // getValue returns a list of result objects. We are expecting 1 result or Error. + const cluster = response[0]; + + // Get ISecurityGroup from securityGroupId + let securityGroups: ec2.ISecurityGroup[] = []; + const dbsg: string[] = cluster.VpcSecurityGroupIds; + if (dbsg) { + securityGroups = dbsg.map((securityGroupId) => { + return ec2.SecurityGroup.fromSecurityGroupId( + scope, + `LSG-${securityGroupId}`, + securityGroupId, + ); + }); + } + + return this.fromDatabaseClusterAttributes(scope, id, { + clusterIdentifier: options.clusterIdentifier, + clusterEndpointAddress: cluster['Endpoint.Address'], + readerEndpointAddress: cluster['ReadEndpoint.Address'], + port: Number(cluster['Endpoint.Port']), + clusterResourceIdentifier: cluster.DBClusterResourceId, + securityGroups: securityGroups, + dataApiEnabled: cluster.EnableHttpEndpoint, + }); + } + /** * Import an existing DatabaseCluster from properties */ diff --git a/packages/aws-cdk-lib/aws-rds/test/cluster.from-lookup.test.ts b/packages/aws-cdk-lib/aws-rds/test/cluster.from-lookup.test.ts new file mode 100644 index 0000000000000..e3781ae94cabb --- /dev/null +++ b/packages/aws-cdk-lib/aws-rds/test/cluster.from-lookup.test.ts @@ -0,0 +1,151 @@ +import * as cxschema from '../../cloud-assembly-schema'; +import { CfnParameter, ContextProvider, Stack } from '../../core'; +import * as rds from '../lib'; + +/* eslint-disable */ +describe('DatabaseCluster from lookup', () => { + test('return correct cluster info', () => { + // GIVEN + const resultObjs = [ + { + 'DBClusterArn': 'arn:aws:rds:us-east-1:123456789012:cluster:cluster-1', + 'Endpoint.Address': 'cluster-1.cluster-testserver.us-east-1.rds.amazonaws.com', + 'Endpoint.Port': '5432', + 'ReadEndpoint.Address': 'cluster-1.cluster-ro-testserver.us-east-1.rds.amazonaws.com', + 'DBClusterResourceId': 'cluster-ABCDEFGHI', + 'VpcSecurityGroupIds': [], + 'Identifier': 'cluster-1', + }, + ]; + const value = { + value: resultObjs, + }; + const mock = jest.spyOn(ContextProvider, 'getValue').mockReturnValue(value); + + // WHEN + const stack = new Stack(undefined, undefined, { env: { region: 'us-east-1', account: '123456789012' } }); + const cluster = rds.DatabaseCluster.fromLookup(stack, 'MyCluster', { + clusterIdentifier: 'cluster-1', + }); + + // THEN + expect(cluster.clusterIdentifier).toEqual('cluster-1'); + expect(cluster.clusterEndpoint.hostname).toEqual('cluster-1.cluster-testserver.us-east-1.rds.amazonaws.com'); + expect(cluster.clusterEndpoint.port).toEqual(5432); + expect(cluster.clusterReadEndpoint.hostname).toEqual('cluster-1.cluster-ro-testserver.us-east-1.rds.amazonaws.com'); + expect(cluster.clusterResourceIdentifier).toEqual('cluster-ABCDEFGHI'); + expect(cluster.connections.securityGroups.length).toEqual(0); + + expect(mock).toHaveBeenCalledWith(stack, { + provider: cxschema.ContextProvider.CC_API_PROVIDER, + props: { + typeName: 'AWS::RDS::DBCluster', + exactIdentifier: 'cluster-1', + propertiesToReturn: [ + 'DBClusterArn', + 'Endpoint.Address', + 'Endpoint.Port', + 'ReadEndpoint.Address', + 'DBClusterResourceId', + 'VpcSecurityGroupIds', + 'EnableHttpEndpoint', + ], + }, + dummyValue: [ + { + 'Identifier': 'TEST', + 'DBClusterArn': 'TESTARN', + 'Endpoint.Address': 'TESTADDRESS', + 'Endpoint.Port': '5432', + 'ReadEndpoint.Address': 'TESTREADERADDRESS', + 'DBClusterResourceId': 'TESTID', + 'VpcSecurityGroupIds': [], + 'EnableHttpEndpoint': true, + }, + ], + }); + + mock.mockRestore(); + }); +}); + +describe('DatabaseCluster from lookup with security groups', () => { + test('return correct cluster info with security groups', () => { + // GIVEN + const resultObjs = [ + { + 'DBClusterArn': 'arn:aws:rds:us-east-1:123456789012:cluster:cluster-1', + 'Endpoint.Address': 'cluster-1.cluster-testserver.us-east-1.rds.amazonaws.com', + 'Endpoint.Port': '5432', + 'ReadEndpoint.Address': 'cluster-1.cluster-ro-testserver.us-east-1.rds.amazonaws.com', + 'DBClusterResourceId': 'cluster-ABCDEFGHI', + 'VpcSecurityGroupIds': ['sg-1', 'sg-2'], + 'Identifier': 'cluster-1', + }, + ]; + const value = { + value: resultObjs, + }; + const mock = jest.spyOn(ContextProvider, 'getValue').mockReturnValue(value); + + // WHEN + const stack = new Stack(undefined, undefined, { env: { region: 'us-east-1', account: '123456789012' } }); + const cluster = rds.DatabaseCluster.fromLookup(stack, 'MyCluster', { + clusterIdentifier: 'cluster-1', + }); + + // THEN + expect(cluster.clusterIdentifier).toEqual('cluster-1'); + expect(cluster.clusterEndpoint.hostname).toEqual('cluster-1.cluster-testserver.us-east-1.rds.amazonaws.com'); + expect(cluster.clusterEndpoint.port).toEqual(5432); + expect(cluster.clusterReadEndpoint.hostname).toEqual('cluster-1.cluster-ro-testserver.us-east-1.rds.amazonaws.com'); + expect(cluster.clusterResourceIdentifier).toEqual('cluster-ABCDEFGHI'); + expect(cluster.connections.securityGroups.length).toEqual(2); + expect(cluster.connections.securityGroups[0].securityGroupId).toEqual('sg-1'); + expect(cluster.connections.securityGroups[1].securityGroupId).toEqual('sg-2'); + + expect(mock).toHaveBeenCalledWith(stack, { + provider: cxschema.ContextProvider.CC_API_PROVIDER, + props: { + typeName: 'AWS::RDS::DBCluster', + exactIdentifier: 'cluster-1', + propertiesToReturn: [ + 'DBClusterArn', + 'Endpoint.Address', + 'Endpoint.Port', + 'ReadEndpoint.Address', + 'DBClusterResourceId', + 'VpcSecurityGroupIds', + 'EnableHttpEndpoint', + ], + }, + dummyValue: [ + { + 'Identifier': 'TEST', + 'DBClusterArn': 'TESTARN', + 'Endpoint.Address': 'TESTADDRESS', + 'Endpoint.Port': '5432', + 'ReadEndpoint.Address': 'TESTREADERADDRESS', + 'DBClusterResourceId': 'TESTID', + 'VpcSecurityGroupIds': [], + 'EnableHttpEndpoint': true, + }, + ], + }); + + mock.mockRestore(); + }); +}); +/* eslint-enable */ + +describe('Validation test', () => { + test('throw error if cluster identifier is a token', () => { + // GIVEN + const stack = new Stack(undefined, undefined, { env: { region: 'us-east-1', account: '123456789012' } }); + const tokenClusterIdentifier = new CfnParameter(stack, 'ClusterIdentifier'); + + expect(() => rds.DatabaseCluster.fromLookup(stack, 'MyCluster', { + clusterIdentifier: tokenClusterIdentifier.valueAsString, + })).toThrow('Cannot look up a cluster with a tokenized cluster identifier.'); + }); +});