You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过CloudFormation实现VPC内Lambda公网访问与RDS远程管理

解决方案:同时实现Lambda公网访问与PostgreSQL RDS远程管理

核心问题分析

你的两次配置尝试的问题根源:

  • 第一次配置:RDS部署在私有子网,虽开启PubliclyAccessible: true,但私有子网未关联带Internet Gateway(IGW)的路由表,AWS无法为RDS生成可路由的公网DNS解析路径,导致本地无法连接;而Lambda通过NAT网关正常访问公网。
  • 第二次配置:把私有子网关联到带IGW的路由表,RDS获得公网访问路径,但公有子网关联到私有路由表,NAT网关失去公网访问能力,导致Lambda无法通过NAT网关出站访问公网。

正确架构设计

要同时满足需求,需遵循VPC子网标准安全架构:

  • 私有子网(2个,跨可用区):部署Lambda和RDS,关联私有路由表(默认路由指向NAT网关,实现出站公网访问,无入站公网直接访问)
  • 公有子网(至少1个):部署NAT网关,关联公有路由表(默认路由指向IGW,为NAT网关提供公网访问能力)
  • RDS通过PubliclyAccessible: true获得公网DNS端点,配合安全组放行本地IP,实现远程管理;Lambda通过私有子网的NAT网关实现出站公网访问。

CloudFormation模板调整要点

以下是修正后的核心资源配置,关键修改已标注:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  MyVPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: '10.0.0.0/16'
      EnableDnsSupport: true # 必须开启,保证VPC内DNS解析
      EnableDnsHostnames: true # 必须开启,保证RDS能生成公网DNS

  MyInternetGateway:
    Type: 'AWS::EC2::InternetGateway'

  AttachGateway:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref MyVPC
      InternetGatewayId: !Ref MyInternetGateway

  # 公有路由表:关联公有子网,默认路由指向IGW
  MyPublicRouteTable:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref MyVPC

  MyPublicRoute:
    Type: 'AWS::EC2::Route'
    DependsOn: AttachGateway
    Properties:
      RouteTableId: !Ref MyPublicRouteTable
      DestinationCidrBlock: '0.0.0.0/0'
      GatewayId: !Ref MyInternetGateway

  # 私有子网A/B:Lambda和RDS部署在这里,无公网IP自动分配
  MySubnetA:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: '10.0.1.0/24'
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: false

  MySubnetB:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: '10.0.2.0/24'
      AvailabilityZone: !Select [1, !GetAZs '']
      MapPublicIpOnLaunch: false

  # 公有子网:部署NAT网关,自动分配公网IP
  MyPublicSubnet:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: '10.0.3.0/24'
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true

  MyDBSubnetGroup:
    Type: 'AWS::RDS::DBSubnetGroup'
    Properties:
      SubnetIds:
        - !Ref MySubnetA
        - !Ref MySubnetB

  # 安全组:补充出站规则确保Lambda能访问公网
  MySecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      VpcId: !Ref MyVPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 5433
          ToPort: 5433
          CidrIp: 10.0.0.0/16 # 允许VPC内Lambda访问RDS
        - IpProtocol: tcp
          FromPort: 5433
          ToPort: 5433
          CidrIp: 'X.X.X.X/32' # 替换为你的本地公网IP,允许远程管理RDS
      SecurityGroupEgress:
        - IpProtocol: '-1' # 允许所有出站流量(Lambda公网访问需求)
          CidrIp: '0.0.0.0/0'

  MyDBInstance:
    Type: 'AWS::RDS::DBInstance'
    Properties:
      Engine: postgres
      Port: '5433'
      DBSubnetGroupName: !Ref MyDBSubnetGroup
      VPCSecurityGroups:
        - !Ref MySecurityGroup
      PubliclyAccessible: true # 必须开启,生成公网DNS端点
      # 需补充:DBInstanceClass、MasterUsername、MasterUserPassword等必填配置

  MyEIP:
    Type: 'AWS::EC2::EIP'
    Properties:
      Domain: vpc

  MyNatGateway:
    Type: 'AWS::EC2::NatGateway'
    Properties:
      AllocationId: !GetAtt MyEIP.AllocationId
      SubnetId: !Ref MyPublicSubnet

  # 私有路由表:关联私有子网,默认路由指向NAT网关
  MyPrivateRouteTable:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref MyVPC

  MyPrivateRoute:
    Type: 'AWS::EC2::Route'
    DependsOn: MyNatGateway
    Properties:
      RouteTableId: !Ref MyPrivateRouteTable
      DestinationCidrBlock: '0.0.0.0/0'
      NatGatewayId: !Ref MyNatGateway

  # 子网与路由表正确绑定
  SubnetARouteTableAssociation:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref MySubnetA
      RouteTableId: !Ref MyPrivateRouteTable

  SubnetBRouteTableAssociation:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref MySubnetB
      RouteTableId: !Ref MyPrivateRouteTable

  PublicSubnetRouteTableAssociation:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref MyPublicSubnet
      RouteTableId: !Ref MyPublicRouteTable

  SenderFunction:
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Image
      VpcConfig:
        SubnetIds:
          - !Ref MySubnetA
          - !Ref MySubnetB
        SecurityGroupIds:
          - !Ref MySecurityGroup
      # 需补充:Timeout、MemorySize等配置

关键调整说明

  1. 路由表命名规范:将原有MyRouteTable改为MyPublicRouteTable,明确区分公有/私有路由表,避免混淆
  2. 安全组出站规则:添加全量出站规则,确保Lambda能发起公网请求
  3. 子网路由绑定:严格遵循:
    • 私有子网(A/B)绑定到私有路由表(走NAT网关出公网)
    • 公有子网绑定到公有路由表(走IGW出公网,为NAT网关提供公网能力)
  4. RDS配置确认:保留PubliclyAccessible: true,同时VPC开启DNS支持,确保RDS的公网DNS能被正确解析

验证步骤

  1. Lambda公网访问验证:在Lambda代码中添加访问公网API的逻辑(比如调用https://api.ipify.org获取公网IP),执行测试并确认返回结果正常
  2. RDS远程访问验证:在本地机器使用psql命令连接RDS的公网端点:
    psql -h <RDS公网端点> -p 5433 -U <数据库用户名> -d <数据库名>
    
    输入密码后确认能正常连接并执行SQL命令

内容的提问来源于stack exchange,提问作者Ilan Chemla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 15:34:52