允许AWS Lambda访问RDS数据库

giò*_*giò 23 amazon-web-services amazon-vpc aws-lambda aws-security-group

我正在尝试从AWS Lambda(Java)连接到RDS数据库.

我应该从RDS安全组规则中启用哪个IP?

Mar*_*k B 42

您无法通过IP启用此功能.首先,您需要为Lambda函数启用VPC访问,在此期间您将为其分配一个安全组.然后,在分配给RDS实例的安全组内,您将启用对分配给Lambda函数的安全组的访问.

  • 由于我需要从AWS Lambda访问互联网,我将不得不创建一个带有NAT网关子网的VPC ......这只是连接到RDS的大量开销 (12认同)
  • 这太愚蠢了。您本质上需要支付 NAT 网关的费用,以便您可以遵循安全最佳实践。我买不起 NAT 网关,因此我需要向整个互联网开放 RDS,以便我的 lambda 函数可以使用它。 (6认同)
  • 您注意到您的RDS实例不公开(虽然您出于某种原因删除了它),因此访问它的唯一方法是通过VPC,这意味着您还需要在VPC中创建NAT网关以允许Internet访问Lambda函数. (3认同)
  • 好的,所以唯一的解决办法就是为这个AWS Lambda创建一个VPC子网,为它分配一个NAT网关(这个成本)并拥有一个从RDS启用的安全组 (2认同)
  • @m01010011 没有“更好”的架构 - 现状保持不变。 (2认同)

Lei*_*son 13

对于其他正在寻找更详细的解决方案或通过 AWS SAM / Cloudformation 配置的 lambda 配置的人来说,对我有用的是:

我。创建一个安全组 (SG),允许您想要连接的所需端口上的出站流量(例如:5432 或 3306。注意,入站规则目前对 lambda 没有影响)将该 SG 应用于您的 lambda。

二. 创建一个 SG,允许引用 lambda SG 的同一端口(例如 5432 或 3306)上的入站流量,因此流量仅锁定到 lambda。并在同一端口(5432 或 3306)上出站。将该 SG 应用于您的 RDS 实例。

更多细节:

拉姆达SG:

Direction    Protocol    Port     Source
Outbound     TCP         5432     ALL
Run Code Online (Sandbox Code Playgroud)

RDS SG:

Direction    Protocol    Port     Source
Inbound      TCP         5432     Lambda SG
Outbound     TCP         5432     ALL
Run Code Online (Sandbox Code Playgroud)

SAM template.yaml 用于配置您可能需要的主要资源,包括:RDS 集群(本示例中显示了用于最大限度降低运行成本的 Aurora Postgres 无服务器)、存储在机密管理器中的 Postgres 主用户密码、lambda、SG应用于允许端口 5432 上出站流量的 lambda,该 SG 应用于引用 lambda SG 的 RDS 集群(锁定到 lambda 的流量),并且我还选择性地展示了您可能希望如何从您的设备连接到 RDS本地桌面计算机通过堡垒(例如附加 EIP 的 Nano EC2 实例,以便可以停止且所有配置保持不变)通过 SSH 隧道使用桌面数据库客户端(例如 DBeaver),从本地计算机管理 RDS。

(请注意,对于生产系统,您可能希望将 RDS 配置到私有子网中以确保安全。为简洁起见,此处未介绍子网的配置。另请注意,对于生产系统,将安全密钥作为环境变量传递并不是最佳实践lambda 每次都应该真正解析秘密 - 但为了简洁起见,显示为环境变量传递)

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Provisions stack with Aurora Serverless

Parameters:
  AppName:
    Description: "Application Name"
    Type: String
    Default: RDS-example-stack
  DBClusterName:
    Description: "Aurora RDS cluster name"
    Type: String
    Default: rdsexamplecluster
  DatabaseName:
    Description: "Aurora RDS database name"
    Type: String
    Default: examplerdsdbname
  DBMasterUserName:
    AllowedPattern: "[a-zA-Z0-9_]+"
    ConstraintDescription: must be between 1 to 16 alphanumeric characters.
    Description: The database admin account user name, between 1 to 16 alphanumeric characters.
    MaxLength: '16'
    MinLength: '1'
    Type: String
    Default: aurora_admin_0

Resources:
  # lambdas
  someLambda:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub '${AWS::StackName}-someLambda'
      # Role: !GetAtt ExecutionRole.Arn # if you require a custom execution role and permissions
      VpcConfig:
        SubnetIds: [subnet-90f79cd8, subnet-9743e6cd, subnet-8bf962ed]
        SecurityGroupIds: [!Ref lambdaOutboundSGToRDS]
      Handler: index.handler
      CodeUri: ./dist/someLambda
      Runtime: nodejs14.x
      Timeout: 5 # ensure matches your PG/ mySQL connection pool timeout
      ReservedConcurrentExecutions: 5
      MemorySize: 128
      Environment: # optional env vars useful for your DB connection
        Variables:
          pgDb: !Ref DatabaseName
          # dbUser: '{{resolve:secretsmanager:some-stackName-AuroraDBCreds:SecretString:username}}'
          # dbPw: '{{resolve:secretsmanager:some-stackName-AuroraDBCreds:SecretString:password}}'

  # SGs
  lambdaOutboundSGToRDS: # Outbound access for lambda to access Aurora Postgres DB
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: !Sub ${AWS::StackName} access to Aurora PG DB
      GroupName: !Sub ${AWS::StackName} lambda to Aurora access
      SecurityGroupEgress: 
        -
          CidrIp: '0.0.0.0/0'
          Description: lambda to Aurora access over 5432
          FromPort: 5432
          IpProtocol: TCP
          ToPort: 5432
      VpcId: vpc-f6c4ea91

  RDSSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: !Sub ${AWS::StackName} RDS ingress and egress
      SecurityGroupEgress: 
        -
          CidrIp: '0.0.0.0/0'
          Description: lambda RDS access over 5432
          FromPort: 5432
          IpProtocol: TCP
          ToPort: 5432
      SecurityGroupIngress: 
        -
          SourceSecurityGroupId: !Ref lambdaOutboundSGToRDS # ingress SG for lambda to access RDS
          Description: lambda to Aurora access over 5432
          FromPort: 5432
          IpProtocol: TCP
          ToPort: 5432
        - # optional
          CidrIp: '172.12.34.217/32' # private IP of your EIP/ bastion instance the EIP is assigned to. /32 ie a single IP address
          Description: EC2 bastion host providing access to Aurora RDS via SSH tunnel for DBeaver desktop access over 5432
          FromPort: 5432
          IpProtocol: TCP
          ToPort: 5432
      VpcId: vpc-f6c4ea91

  DBSubnetGroup: # just a logical grouping of subnets that you can apply as a group to your RDS
    Type: AWS::RDS::DBSubnetGroup
    Properties:
      DBSubnetGroupDescription: CloudFormation managed DB subnet group.
      SubnetIds:
        - subnet-80f79cd8
        - subnet-8743e6cd
        - subnet-9bf962ed

  AuroraDBCreds: # provisions a password for the DB master username, which we set in Parameters
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: !Sub ${AWS::StackName}-AuroraDBCreds
      Description: RDS database auto-generated user password
      GenerateSecretString:
        SecretStringTemplate: !Sub '{"username": "${DBMasterUserName}"}'
        GenerateStringKey: "password"
        PasswordLength: 30
        ExcludeCharacters: '"@/\'
      Tags:
        -
          Key: AppName
          Value: !Ref AppName

  RDSCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      DBClusterIdentifier: !Ref DBClusterName
      MasterUsername: !Join ['', ['{{resolve:secretsmanager:', !Ref AuroraDBCreds, ':SecretString:username}}' ]]
      MasterUserPassword: !Join ['', ['{{resolve:secretsmanager:', !Ref AuroraDBCreds, ':SecretString:password}}' ]]
      DatabaseName: !Ref DatabaseName
      Engine: aurora-postgresql
      EngineMode: serverless
      EngineVersion: '10' # currently provisions '10.serverless_14' 10.14
      EnableHttpEndpoint: true
      ScalingConfiguration:
        AutoPause: true
        MaxCapacity: 2
        MinCapacity: 2
        SecondsUntilAutoPause: 300 # 5 min
      DBSubnetGroupName:
        Ref: DBSubnetGroup
      VpcSecurityGroupIds:
        - !Ref RDSSG

# optional outputs useful for importing into another stack or viewing in the terminal on deploy
Outputs:
  StackName:
    Description: Aurora Stack Name
    Value: !Ref AWS::StackName
    Export:
      Name: !Sub ${AWS::StackName}-StackName

  DatabaseName:
    Description: Aurora Database Name
    Value: !Ref DatabaseName
    Export:
      Name: !Sub ${AWS::StackName}-DatabaseName

  DatabaseClusterArn:
    Description: Aurora Cluster ARN
    Value: !Sub arn:aws:rds:${AWS::Region}:${AWS::AccountId}:cluster:${DBClusterName}
    Export:
      Name: !Sub ${AWS::StackName}-DatabaseClusterArn

  DatabaseSecretArn:
    Description: Aurora Secret ARN
    Value: !Ref AuroraDBCreds
    Export:
      Name: !Sub ${AWS::StackName}-DatabaseSecretArn

  DatabaseClusterID:
    Description: Aurora Cluster ID
    Value: !Ref RDSCluster
    Export:
      Name: !Sub ${AWS::StackName}-DatabaseClusterID

  AuroraDbURL:
    Description: Aurora Database URL
    Value: !GetAtt RDSCluster.Endpoint.Address
    Export:
      Name: !Sub ${AWS::StackName}-DatabaseURL

  DatabaseMasterUserName:
    Description: Aurora Database User
    Value: !Ref DBMasterUserName
    Export:
      Name: !Sub ${AWS::StackName}-DatabaseMasterUserName
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以配置Lambda来访问您的RDS实例。

您可以使用Lambda管理控制台启用它。选择需要访问RDS实例的Lambda函数,然后转到“配置”->“高级设置”,然后选择您需要它访问的VPC(您的RDS实例所在的)。

在此处了解更多信息 http://docs.aws.amazon.com/lambda/latest/dg/vpc.html