使用 CloudFormation 在 VPC 中维护 Lambda 的互联网访问和对 RDS 的远程访问

问题描述 投票:0回答:1

我正在使用 AWS CloudFormation 模板来部署无服务器应用程序,该应用程序需要具有 Internet 访问权限的 Lambda 函数和我需要远程访问以进行管理的 PostgreSQL RDS 实例。在修改我的子网和路由表关联以增强安全性后,我的 Lambda 失去了互联网访问权限,并且我无法远程连接到我的 RDS 实例。我正在寻找有关如何调整 CloudFormation 模板以满足这些要求的指导。

我的要求: AWS Lambda 函数需要访问 Internet 才能发出出站请求。 需要从我的本地计算机访问以进行管理的 PostgreSQL RDS 实例。

下面是我的 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
      EnableDnsHostnames: true

  MyInternetGateway:
    Type: 'AWS::EC2::InternetGateway'
    DependsOn: "MyVPC"

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

  MyRouteTable:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref MyVPC

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

  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

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

  MySecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      VpcId: !Ref MyVPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 5433
          ToPort: 5433
          CidrIp: 10.0.0.0/16 # VPC internal
        - IpProtocol: tcp
          FromPort: 5433
          ToPort: 5433
          CidrIp: 'X.X.X.X/32' # MYLOCALIP

  MyDBInstance:
    Type: 'AWS::RDS::DBInstance'
    Properties:
      Engine: postgres
      Port: '5433'
      DBSubnetGroupName: !Ref MyDBSubnetGroup
      VPCSecurityGroups:
        - !Ref MySecurityGroup
      PubliclyAccessible: true

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

  MyPublicSubnet:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: '10.0.3.0/24'
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true

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

  MyPrivateRouteTable:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref MyVPC

  PrivateRoute:
    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 MyRouteTable

  SenderFunction:
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Image
      VpcConfig:
        SubnetIds:
          - !Ref MySubnetA
          - !Ref MySubnetB
        SecurityGroupIds:
          - !Ref MySecurityGroup

问题: 我的 Lambda 具有外部内部访问权限,但我无法从本地主机访问我的 RDS。

我尝试切换协会:

  SubnetARouteTableAssociation:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref MySubnetA
      RouteTableId: !Ref MyRouteTable

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

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

结果是我可以远程访问我的 RDS,但随后我在 Lambda 中失去了互联网访问权限。

我也尝试询问ChatGPT,但他没有成功帮助! :D

我的问题: 如何调整我的 CloudFormation 模板以确保我的 Lambda 函数可以访问互联网,同时还保持对我的 RDS 实例的远程访问?

任何有关如何构建我的 VPC、子网、路由表或任何其他配置以实现这些目标的建议,我们将不胜感激。

amazon-web-services aws-lambda aws-cloudformation amazon-rds amazon-vpc
1个回答
0
投票

您需要创建公共子网(具有到 Internet 网关的路由的子网)来放置 RDS 实例。RDS 实例必须位于公共子网中,以便您可以直接从本地主机访问它。 NAT 网关还需要位于公共子网中。

Lambda 函数必须位于私有子网(具有到 NAT 网关的路由的子网)中。

因此,您需要至少两个公有子网(用于 RDS)和至少两个私有子网(用于 Lambda 函数)。

这样配置后,Lambda函数将能够访问VPC中的所有资源(例如RDS实例)以及Internet上的资源(通过NAT网关)。

© www.soinside.com 2019 - 2024. All rights reserved.