【问题标题】:Lambda can not access RDS though those are in the same VPCLambda 无法访问 RDS,尽管它们在同一个 VPC 中
【发布时间】:2019-02-10 06:44:53
【问题描述】:

我用下面的CloudFormation 创建了VPCRDS

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

RDS 的结果


Lambda 设置


Lambda 尝试使用域名rekog-moderation.cokqwd6ixsnc.ap-northeast-1.rds.amazonaws.com 访问时,在与RDS 建立连接时返回超时错误。

我错过了什么?

【问题讨论】:

  • 在您的 Lambda 代码中添加调试语句到 resolve the DNS name of the Amazon RDS instance to an IP address。目的是属于10.x.x.x IP 范围,这意味着它将纯粹在 VPC 内进行通信。另外,您能否将相关的 Lambda 代码添加到您的问题中?
  • @John Rotenstein,非常感谢您再次发表评论,当我调试 lambda 代码时,这是因为在 VPC 中访问了 Rekognition。我应该为 lambda 设置 NAT gateway 以访问 VPC 之外的资源。

标签: amazon-web-services aws-lambda amazon-cloudformation amazon-rds


【解决方案1】:

您需要在入口规则中添加安全组自引用,以允许安全组的所有成员相互通信。比如:

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

您可以在AWS forum CF 中找到有关自引用安全组的更多信息

【讨论】:

  • 它不会让我只编辑一个错字,但最后一句应该是“你可以找到更多信息”。
【解决方案2】:

除了@caldazar 回答:

我在使用mysql npm 包时遇到了类似的问题。在调试过程中,我尝试查看主机名解析为哪个 IP 地址:

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

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

然后我检查了 IP 地址是否在为 RDS 实例和子网指定的范围内,并且它与可用区匹配。

问题是mysql 可能正在尝试从公共 DNS 解析主机名。因此,我没有传递主机名,而是将解析的 IP 地址传递到 mysql 的初始化中,并且它起作用了。

【讨论】:

    猜你喜欢
    • 2022-12-05
    • 2020-03-22
    • 2019-09-18
    • 2019-12-31
    • 2017-02-18
    • 2018-10-20
    • 2018-06-07
    • 1970-01-01
    • 2015-12-10
    相关资源
    最近更新 更多