skip to Main Content

I basically just want to add a Compute Resource (EC2 instance) to an RDS DB cluster with the AWS CDK as described here. https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/ec2-rds-connect.html. But I can’t find any examples online or in the CDK Docs (https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_rds.DatabaseCluster.html).

I can manually add compute resources from the AWS console no problem but I want to do it programmatically with AWS CDK. How would I do this, or what are my options?

Here is my current AWS CDK code for RDS. Here I am trying to add an EC2 instance resource that I created in another stack called my_ec2_stack.my_ec2 as a compute resource for my_rds_cluster. But if this is a wrong approach or you know a different way to do this, let me know. Examples would be appreciated as well.

Additional details: The rds DB cluster below and my EC2 instance that I want to add as a Compute Resource are in the same VPC and subnet.

my_rds_cluster = rds.DatabaseCluster(self, "MyRDSDatabaseCluster",
            cluster_identifier="my-postgres",
            engine=rds.DatabaseClusterEngine.aurora_postgres(
                version=rds.AuroraPostgresEngineVersion.VER_11_18
            ),
            instance_props=rds.InstanceProps(
                vpc=shared_vpc_stack.vpc,
                instance_type=ec2.InstanceType.of(ec2.InstanceClass.R6G, ec2.InstanceSize.XLARGE2),
                vpc_subnets=ec2.SubnetSelection(
                   availability_zones=["us-west-2a", "us-west-2b", "us-west-2c", "us-west-2d"],
                   subnets=[private_subnet_a, private_subnet_b, private_subnet_c, private_subnet_d],
                ),
                auto_minor_version_upgrade=True,
                enable_performance_insights=True,
                publicly_accessible=False,
                security_groups=[my_rds_security_group, my_ec2_stack.searchy_security_group, my_ec2_stack.soary_security_group],
            ),
            backup=rds.BackupProps(
                retention=Duration.days(7),
            ),
      )

# My failed attempt to add compute resources EC2. (No error it just doesn't do anything)

        my_rds_connections = my_rds_cluster.connections.allow_from(
            other=my_ec2_stack.my_ec2,
            port_range=ec2.Port.tcp(5432),
            description="My RDS connection to My EC2"
        )

Screenshot below shows what it looks like in the AWS RDS Console when a compute resource is connected:

enter image description here

2

Answers


  1. All the RDS "Connected Compute Resources" feature does is generate some security group rules for you. It is a convenience method in the AWS web console mainly there for people that don’t understand how to create security group rules correctly themselves.

    When using Infrastrucre as Code (IaC) tools such as the AWS CDK/CloudFormation/Terraform/etc. you would just create those security groups in the normal way. The security groups you create via IaC will not show up under the RDS "Connected Compute Resources" list, because that list only shows you the security groups that RDS created for you via the web console.

    Per the documentation for the RDS "Connected Compute Resources" feature (emphasis mine):

    You can use the AWS Management Console to view the compute resources that are connected to an RDS database. The resources shown include compute resource connections that were set up automatically.

    The listed compute resources don’t include ones that were connected to the database manually. For example, you can allow a compute resource to access a database manually by adding a rule to the VPC security group associated with the database.

    Your code here:

            my_rds_connections = my_rds_cluster.connections.allow_from(
                other=my_ec2_stack.my_ec2,
                port_range=ec2.Port.tcp(5432),
                description="My RDS connection to My EC2"
            )
    

    Is doing exactly what the RDS "Connected Compute Resources" feature is doing. It is just never going to show up in the RDS "Connected Compute Resources" web UI, because you did this yourself instead of having RDS do it through the web UI.


    It looks like there is a naming convention that the RDS "Connected Compute Resources" feature uses, that you may be able to replicate in order to get your resources to show up in the Web UI. You would have to name your EC2 instance’s security group like:

    ec2-rds-n (where n is a number).

    And your RDS instance’s security group like:

    rds-ec2-n (where n is a number)

    Again I would point out that this is purely accomplishing a visual thing in the web UI, and not necessary at all for your CDK code to allow your EC2 instance to actually communicate with your RDS instance.

    Login or Signup to reply.
  2. As Mark B. pointed out above, the "Connected compute resources" window shown in the pic is just visible when you do it through the AWS console management (or UI). This option is there for those who don’t want to configure security groups inbound and outbound rules by themselves (Is there any resource to connect compute resource on AWS RDS using terraform). Indeed, I have deployed in a very similar cdk to yours a RDS cluster and this is just setting the correct Inbound and Outbound Security groups in the generated CloudFormation template.
    See the respective cdk chunk:

            # Test Cluster
            rds_cluster = rds.DatabaseCluster(self, "MyRDSCluster",
                engine=rds.DatabaseClusterEngine.aurora_mysql(version=rds.AuroraMysqlEngineVersion.VER_3_01_0),
                instance_props=rds.InstanceProps(
                    instance_type=ec2.InstanceType.of(ec2.InstanceClass.R6G, ec2.InstanceSize.LARGE),
                    vpc=existing_vpc,
                    vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_WITH_NAT),
                ),
                default_database_name="mydb",
                removal_policy=cdk.RemovalPolicy.DESTROY,
            )
    
            rds_cluster.connections.allow_default_port_from(ec2_instance, "Allow RDS access from EC2")
    

    And this is the Cloud Formation generated template by the cdk:

      ...
      "MyRDSClusterSecurityGroup72902BD7": {
       "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": "vpc-XXXXXXXXXXXXX"
       }, ...
      },
      "MyRDSClusterSecurityGroupfromTestCdkMyEC2InstanceInstanceSecurityGroup1B3C5B4EIndirectPort4CA6D4DD": {
       "Type": "AWS::EC2::SecurityGroupIngress",
       "Properties": {
        "Description": "Allow RDS access from EC2",
        "FromPort": {
         "Fn::GetAtt": [
          "MyRDSClusterDA407818",
          "Endpoint.Port"
         ]
        },
        "GroupId": {
         "Fn::GetAtt": [
          "MyRDSClusterSecurityGroup72902BD7",
          "GroupId"
         ]
        },
        "IpProtocol": "tcp",
        "SourceSecurityGroupId": {
         "Fn::GetAtt": [
          "MyEC2InstanceInstanceSecurityGroup06C6622F",
          "GroupId"
         ]
        },
        "ToPort": {
         "Fn::GetAtt": [
          "MyRDSClusterDA407818",
          "Endpoint.Port"
         ]
        }
       }, ...
      },
    ...
    "MyEC2InstanceInstanceSecurityGroup06C6622F": {
       "Type": "AWS::EC2::SecurityGroup",
       "Properties": {
        "GroupDescription": "TestCdk/MyEC2Instance/InstanceSecurityGroup",
        "SecurityGroupEgress": [
         {
          "CidrIp": "0.0.0.0/0",
          "Description": "Allow all outbound traffic by default",
          "IpProtocol": "-1"
         }
        ],
        "Tags": [
         {
          "Key": "Name",
          "Value": "TestCdk/MyEC2Instance"
         }
        ],
        "VpcId": "vpc-XXXXXXXXXX"
       }, ...
      }, ...
    

    If you did set the security groups correctly. You should be able to connect to the RDS database (need to install mysql):

    mysql -h <RDS_ENDPOINT> -P <PORT> -u <USERNAME> -p
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search