Lambda 无法访问 RDS,尽管它们位于同一 VPC 中
Lambda can not access RDS though those are in the same VPC
我用下面的 CloudFormation
创建了 VPC
和 RDS
。
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
时出现 returns 超时错误。
我错过了什么?
您需要在入口规则中添加安全组自引用,以允许安全组中的所有成员相互通信。类似于:
"TestSecurityGroupIngress": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"GroupId": { "Ref": "TestSecurityGroup" },
"IpProtocol": "tcp",
"FromPort": "0",
"ToPort": "65535",
"SourceSecurityGroupId": { "Ref": "TestSecurityGroup" }
}
}
您可以在 AWS forum
上找到有关 CF 中自引用安全组的更多信息
除了@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
可能试图从 public DNS 解析主机名。因此,我没有传递主机名,而是将已解析的 IP 地址传递给 mysql 的初始化并且它起作用了。
我用下面的 CloudFormation
创建了 VPC
和 RDS
。
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
时出现 returns 超时错误。
我错过了什么?
您需要在入口规则中添加安全组自引用,以允许安全组中的所有成员相互通信。类似于:
"TestSecurityGroupIngress": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"GroupId": { "Ref": "TestSecurityGroup" },
"IpProtocol": "tcp",
"FromPort": "0",
"ToPort": "65535",
"SourceSecurityGroupId": { "Ref": "TestSecurityGroup" }
}
}
您可以在 AWS forum
上找到有关 CF 中自引用安全组的更多信息除了@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
可能试图从 public DNS 解析主机名。因此,我没有传递主机名,而是将已解析的 IP 地址传递给 mysql 的初始化并且它起作用了。