有谁知道是否可以在同一 VPC 中通过隔离子网(其中两个资源位于同一子网中)将 Lambda 连接到 RDS?我已经摆弄和搜索了几天了。连GPT也搞不定。这更多的是“它实际上可以这样工作吗”,而不是一种固定的方法。
我试图避免使用 NAT 网关来规避每小时 0.045 美分的成本,而只使用免费的 RDS 实例进行开发。添加具有公共子网的 NAT 网关并具有私有的出口子网是可行的。但我想知道这对于没有 NAT 网关的完全隔离的子网是否可行。
这就是我现在的位置:
这是 VPC 和安全组的 CDK 的样子。您可以看到 create lambda 函数相应地附加了它们。
非常感谢任何帮助。为了让它连接起来,我快把自己逼疯了。
# Create VPC non NAT Gateways & only private isolated subnets
vpc = ec2.Vpc(
self,
"VPCNoNat",
cidr="10.0.0.0/24",
nat_gateways=0, # No NAT gateways
subnet_configuration=[
ec2.SubnetConfiguration(
name="PrivateSubnetNoNat",
subnet_type=ec2.SubnetType.PRIVATE_ISOLATED,
cidr_mask=26,
),
],
)
# Create a Security Group for the RDS Cluster and Lambda
security_group = ec2.SecurityGroup(
self,
"cdk-securitygroupNoNat",
vpc=vpc,
security_group_name="cdk-security-group-no-nat",
)
# Allow traffic on port 5432 from within the VPC for RDS
security_group.add_ingress_rule(ec2.Peer.ipv4(vpc.vpc_cidr_block), ec2.Port.tcp(5432))
# Create a subnet group
subnet_group = rds.SubnetGroup(
self,
"cdkSubnetGroupNoNat",
description="Subnet group for cdk no nat",
vpc=vpc,
vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_ISOLATED),
)
db_instance = rds.DatabaseInstance(
self,
"PostgresInstance1NoNat",
engine=rds.DatabaseInstanceEngine.POSTGRES,
instance_type=ec2.InstanceType.of(
ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.MICRO
),
credentials=rds.Credentials.from_generated_secret("postgres"),
vpc=vpc,
security_groups=[security_group],
subnet_group=subnet_group,
publicly_accessible=False,
)
# Create a Lambda function
def create_lambda_function(
stack,
lambda_id,
handler,
layers,
vpc,
security_group,
role,
runtime=_lambda.Runtime.PYTHON_3_9,
timeout=Duration.seconds(15),
extra_env_vars=None,
):
# Default environment variables
default_env_vars = {
"SECRET_ARN": db_instance.secret.secret_arn,
"DB_HOST": db_instance.db_instance_endpoint_address,
}
# Merge extra environment variables with the default ones
environment_vars = {**default_env_vars, **(extra_env_vars or {})}
return _lambda.Function(
stack,
lambda_id,
handler=handler,
runtime=runtime,
environment=environment_vars,
code=_lambda.Code.from_asset(handler),
role=role,
layers=layers,
vpc=vpc,
security_groups=[security_group],
vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_ISOLATED),
timeout=timeout,
)
我强烈建议不要直接与安全组打交道。
上的 CDK 文档:可以通过 addIngressRule 和 addEgressRule 直接操作安全组,但建议通过 .connections 对象进行更改。如果您以这种方式将两个构造与安全组对等,则将在两者中创建适当的规则。
它会大大简化你的代码:
vpc = ec2.Vpc(
self,
"VPCNoNat",
cidr="10.0.0.0/24",
nat_gateways=0, # No NAT gateways
subnet_configuration=ec2.Vpc.DEFAULT_SUBNETS_NO_NAT,
)
db_instance = rds.DatabaseInstance(
self,
"PostgresInstance1NoNat",
engine=rds.DatabaseInstanceEngine.POSTGRES,
instance_type=ec2.InstanceType.of(
ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.MICRO
),
credentials=rds.Credentials.from_generated_secret("postgres"),
vpc=vpc,
publicly_accessible=False,
)
function = _lambda.Function(
self,
"MyFunction",
handler=handler,
runtime=runtime,
environment=environment_vars,
code=_lambda.Code.from_asset(handler),
layers=layers,
vpc=vpc,
)
function.connections.allow_to_default_port(db_instance)
Connections.allow_to_default_port
将负责安全组规则。您不必自己创建安全组或子网组。
也就是说,如果您从函数内进行任何 AWS API 调用,则需要为您在 VPC 中使用的每个服务创建一个 VPC 终端节点。