允许 AWS Lambda 访问 RDS 数据库

Allow AWS Lambda to access RDS Database

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

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

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

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

您可以使用 Lambda 管理控制台启用此功能。 Select 需要访问 RDS 实例的 Lambda 函数,然后转到配置 -> 高级设置和 select 您需要它访问的 VPC(您的 RDS 实例所在的位置)。

在这里了解更多 http://docs.aws.amazon.com/lambda/latest/dg/vpc.html

这是我做的

我为 Lambda 和 RDS 服务分配了相同的子网和 VPC。 现在我创建了一个选择子网之一的 NAT 网关,以便 Lambda 可以使用该 NAT 网关与外界交互。

最后一件事是在附加到 RDS 和 Lambda 函数的安全组中添加入站条目。白名单数据库端口 5432 在我的例子中用于 postgresql 并在源中添加安全组名称。

安全组通过在入站规则中添加条目以某种方式将自己列入白名单。

这对我来说效果很好。

对于搜索更详细解决方案或通过 AWS SAM/Cloudformation 提供的 lambda 配置的任何其他人,对我有用的是:

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

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

更多详情:

Lambda SG:

Direction    Protocol    Port     Source
Outbound     TCP         5432     ALL

RDS 新加坡:

Direction    Protocol    Port     Source
Inbound      TCP         5432     Lambda SG
Outbound     TCP         5432     ALL

SAM template.yaml 用于配置您可能需要的主要资源,包括:一个 RDS 集群(Aurora Postgres serverless 以最小化 运行 成本显示在这个例子中),一个 Postgres 主用户密码存储在秘密管理器中,一个 lambda,一个应用于 lambda 的 SG,允许端口 5432 上的出站流量,一个应用于引用 lambda SG 的 RDS 集群的 SG(锁定到 lambda 的流量),我也有选择地显示您可能希望如何通过堡垒(例如附加了 EIP 的 nano EC2 实例)使​​用桌面数据库客户端(例如 DBeaver)通过 SSH 隧道从本地桌面计算机连接到 RDS,这样它就可以停止并且所有配置保持不变) 从您的本地计算机管理 RDS。

(请注意,对于生产系统,您可能希望将 RDS 配置到私有子网中以确保安全。为简洁起见,此处未涵盖子网的配置)

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