CloudFormation,RDS 和 Lambda 的网络问题

CloudFormation,RDS 和 Lambda 的网络问题

一直在尝试让启用 HTTP 的 Lambda 连接到 RDS 数据库,获取结果并返回给调用者。我遇到了各种超时问题,这让我抓狂不已。我从未真正处理过基础设施方面的问题,所以我所说的一些内容可能没有切中要害。

当我尝试在没有任何 VPC 的情况下创建 Lambda 和 Postgres 数据库时,Lambda 无法连接到 Postgres - 那里超时了。

当我尝试创建一个基本 VPC 并将 Lambda 和数据库放入其中时,Lambda 连接并获取行,但 Lambda 本身无法退出 VPC 并超时。

我尝试通过 CloudFormation 执行此操作,这样我就不必太担心回溯我的步骤。到目前为止,我有这个。它应该会创建

  • 一个 VPC
  • 我所在地区的三个子网
  • 我的数据库的子网
  • 我的功能的安全组
  • 我的数据库的安全组

我认为我需要以某种方式将这些功能的群组公开,但我不知道该怎么做。有人能给我指点迷津吗?

ServerlessVPC:
  Type: AWS::EC2::VPC
  Properties:
    CidrBlock: "10.0.0.0/16"
ServerlessSubnetA:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::Subnet
  Properties:
    VpcId:
      Ref: ServerlessVPC
    AvailabilityZone: ${self:provider.region}a
    CidrBlock: "10.0.0.0/24"
ServerlessSubnetB:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::Subnet
  Properties:
    VpcId:
      Ref: ServerlessVPC
    AvailabilityZone: ${self:provider.region}b
    CidrBlock: "10.0.1.0/24"
ServerlessSubnetC:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::Subnet
  Properties:
    VpcId:
      Ref: ServerlessVPC
    AvailabilityZone: ${self:provider.region}c
    CidrBlock: "10.0.2.0/24"
ServerlessSecurityGroup:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: SecurityGroup for Serverless Functions
    VpcId:
      Ref: ServerlessVPC
ServerlessStorageSecurityGroup:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: Ingress for RDS Instance
    VpcId:
      Ref: ServerlessVPC
    SecurityGroupIngress:
    - IpProtocol: tcp
      FromPort: '5432'
      ToPort: '5432'
      SourceSecurityGroupId:
        Ref: ServerlessSecurityGroup
    - IpProtocol: tcp
      FromPort: '11211'
      ToPort: '11211'
      SourceSecurityGroupId:
        Ref: ServerlessSecurityGroup
    SecurityGroupEgress:
ServerlessRDSSubnetGroup:
  Type: AWS::RDS::DBSubnetGroup
  Properties:
    DBSubnetGroupDescription: "RDS Subnet Group"
    SubnetIds:
    - Ref: ServerlessSubnetA
    - Ref: ServerlessSubnetB
    - Ref: ServerlessSubnetC
ServerlessRDSCluster: 
  DependsOn: ServerlessStorageSecurityGroup
  Type: "AWS::RDS::DBInstance"
  Properties: 
    DBName: ${self:custom.database_name}
    AllocatedStorage: 10
    DBInstanceClass: "db.t2.micro"
    Engine: "postgres"
    EngineVersion: "9.6.2"
    MasterUsername: ${self:custom.env.DATABASE_USER}
    MasterUserPassword: ${self:custom.env.DATABASE_PASSWORD}
    VPCSecurityGroups:
    - "Fn::GetAtt": ServerlessStorageSecurityGroup.GroupId
    DBSubnetGroupName:
      Ref: ServerlessRDSSubnetGroup
  DeletionPolicy: "Snapshot"    

答案1

为了使您的 Lambda 函数能够 (a) 访问您的 RDS 实例,以及 (b) 访问外部世界,您需要将您的 Lambda 函数放在您的 VPC 中,并向您的 VPC 添加 NAT 以供外部世界访问。

请执行下列操作:

  1. 将您的 Lambda 函数放入私人的您的 VPC 中的子网。
  2. 民众子网。
  3. 确保您的私有子网的路由表允许访问 RDS 实例。
  4. 确保您的私有子网的路由表将出站流量引导至 NAT。
  5. 如果 Lambda 函数支持安全组,请确保您的 RDS 实例的安全组允许访问您的 Lambda 函数的安全组。如果 Lambda 函数不支持安全组,请确保您的 RDS 实例的安全组允许从您的私有子网或 VPC 的 CIDR 块进行访问。

答案2

在您的 cloudformation 模板中,我没有看到任何公共子网,也没有看到 Internet 或 NAT 网关。我不使用 CloudFormation 或 Lambda,因此它们中可能存在一些神奇之处,使其变得不必要,但对于 VPC 而言,如果您希望私有子网中的某些东西能够与外界通信,则需要一个 NAT 网关(最好每个 AZ 一个)、一个 NAT 网关所在的公共子网、一个 NAT 网关用于通信的 Internet 网关,以及通过 NAT 网关在您的私有子网中建立默认路由。

如果您查看帐户中的默认 VPC,并追踪其附加的所有位,您将看到需要设置的结构类型。

相关内容