SangminKim
SangminKim

Reputation: 9166

Lambda can not access RDS though those are in the same VPC

I have created VPC and RDS with the below CloudFormation.

Resources:
  TestVpc:
    Type: "AWS::EC2::VPC"
    Properties:
      CidrBlock: "10.0.0.0/16"
      EnableDnsSupport: true
      EnableDnsHostnames: true
  TestSubnetA:
    Type: "AWS::EC2::Subnet"
    Properties:
      AvailabilityZone: "ap-northeast-1a"
      CidrBlock: "10.0.0.0/20"
      VpcId: !Ref TestVpc
  TestSubnetB:
    Type: "AWS::EC2::Subnet"
    Properties:
      AvailabilityZone: "ap-northeast-1d"
      CidrBlock: "10.0.16.0/20"
      VpcId: !Ref TestVpc
  TestSubnetC:
    Type: "AWS::EC2::Subnet"
    Properties:
      AvailabilityZone: "ap-northeast-1c"
      CidrBlock: "10.0.32.0/20"
      VpcId: !Ref TestVpc
  TestSecurityGroup:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      GroupDescription: "Test security group with cloduformation"
      SecurityGroupIngress:
        - CidrIp: "10.0.0.0/16"
          IpProtocol: "tcp"
          FromPort: 0
          ToPort: 65535
      SecurityGroupEgress:
        - CidrIp: "0.0.0.0/0"
          FromPort: 0
          ToPort: 65535
          IpProtocol: "tcp"
      VpcId: !Ref TestVpc

  TestSubnetGroup:
    Type: "AWS::RDS::DBSubnetGroup"
    Properties:
      DBSubnetGroupDescription: "TestSubnetGroupDesc"
      SubnetIds:
        - !Ref TestSubnetA
        - !Ref TestSubnetB
        - !Ref TestSubnetC

  TestRDS:
    Type: "AWS::RDS::DBInstance"
    Properties:
      DBInstanceClass: "db.t2.micro"
      DBInstanceIdentifier: "rekog-moderation"
      DBName: "rekog"

      Engine: "postgres"
      EngineVersion: "10.4"

      MasterUsername: "rekog"
      MasterUserPassword: "passwd"
      AllocatedStorage: "20"

      DBSubnetGroupName: !Ref TestSubnetGroup
      VPCSecurityGroups:
        - !Ref TestSecurityGroup

The result of RDS

enter image description here


Lambda setting

enter image description here


When Lambda try to access with Domain name rekog-moderation.cokqwd6ixsnc.ap-northeast-1.rds.amazonaws.com, it returns timeout error while making a connection to RDS.

What do I miss?

Upvotes: 2

Views: 1458

Answers (2)

Caldazar
Caldazar

Reputation: 3802

you need to add security group self-reference in ingress rule, in order to allow all members of security group to communicate with each other. Something like:

"TestSecurityGroupIngress": {
  "Type": "AWS::EC2::SecurityGroupIngress",
  "Properties": {
    "GroupId": { "Ref": "TestSecurityGroup" },
    "IpProtocol": "tcp",
    "FromPort": "0",
    "ToPort": "65535",
    "SourceSecurityGroupId": { "Ref": "TestSecurityGroup" }
  }
}

You can find more info on self referencing security group in CF on AWS forum

Upvotes: 3

T.Chmelevskij
T.Chmelevskij

Reputation: 2139

Besides of @caldazar answer:

I had similar issue while using mysql npm package. In the process of debugging I've tried to see what ip address does the hostname resolve to with:

const { lookup: lc } = require('dns');
const { promisify } = require('util');

const lookup = promisify(lc);
const { address } = await lookup('<my-hostname.com>');

Then I've checked that IP address was in the range specified for the RDS instance and subnets and it matched availability zone.

Problem was that mysql was trying to resolve the hostname from public DNS probably. So rather than passing the hostname I've just passed the resolved IP address into the initialization of mysql and it worked.

Upvotes: 0

Related Questions