我正在尝试从 AWS Lambda (Java) 连接到 RDS 数据库。
我应该从 RDS 安全组规则中启用哪个 IP?
我正在尝试从 AWS Lambda (Java) 连接到 RDS 数据库。
我应该从 RDS 安全组规则中启用哪个 IP?
您无法通过 IP 启用此功能。首先,您需要为 Lambda 函数启用 VPC 访问,在此期间您将为其分配一个安全组。然后,在分配给 RDS 实例的安全组中,您将为分配给 Lambda 函数的安全组启用访问权限。
您可以配置 Lambda 以访问您的 RDS 实例。
您可以使用 Lambda 管理控制台启用此功能。选择需要访问 RDS 实例的 Lambda 函数,然后转到配置 -> 高级设置并选择您需要访问的 VPC(即您的 RDS 实例所在的)。
在此处了解更多信息 http://docs.aws.amazon.com/lambda/latest/dg/vpc.html
对于寻找简洁解决方案或通过 SAM / Cloudformation 配置的 lambda 配置的其他任何人,对我有用的是:
一世。创建一个安全组 (SG),允许您想要连接的所需端口上的出站流量(例如:5432 或 3306。请注意,入站规则对 lambda 没有影响,我相信目前)将该 SG 应用于您的 lambda。
ii. 在引用 lambda SG 的同一端口(例如 5432 或 3306)上创建一个允许入站流量的 SG,因此流量被锁定为仅 lambda。并在同一端口(5432 或 3306)上出站。将该 SG 应用到您的 RDS 实例。
更多细节:
拉姆达SG:
Direction Protocol Port Source
Outbound TCP 5432 ALL
RDS SG:
Direction Protocol Port Source
Inbound TCP 5432 Lambda SG
Outbound TCP 5432 ALL
SAM template.yaml 来配置您可能需要的主要资源,包括:RDS 集群(本示例中显示了 Aurora Postgres 无服务器以最小化运行成本)、存储在 secrets manager 中的 Postgres 主用户密码、lambda、SG应用于 lambda 允许端口 5432 上的出站流量,该 SG 应用于引用 lambda SG 的 RDS 集群(将流量锁定到 lambda),我还可选地展示了您可能希望如何从您的本地桌面计算机使用桌面数据库客户端(例如 DBeaver)通过 SSH 隧道通过堡垒(例如,连接了 EIP 的 nano EC2 实例,因此可以停止并且所有配置保持不变)从本地计算机管理 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:
Variables:
# pgHost: some-cluster.cluster-ctmancpuhrmi.eu-west-1.rds.amazonaws.com
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: DBMasterUserName
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 # 6 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
这是我所做的
我为 Lambda 和 RDS 服务分配了相同的子网和 VPC。现在,我创建了一个选择子网之一的 NAT 网关,以便 Lambda 可以使用该 NAT 网关与外界交互。
最后一件事是在附加到 RDS 以及 Lambda 函数的安全组中添加入站条目。在我的情况下,将数据库端口 5432 列入 postgresql 的白名单,并在源中添加安全组名称。
安全组通过在入站规则中添加条目以某种方式将自己列入白名单。
这对我很有效。