我在 VPC 的子网中部署了一些 ECS 任务。来自私有子网的所有流量都被路由到公共子网中的 NAT,而来自公共子网的所有流量都被路由到互联网网关。通过这种方式,ECS 任务可以访问互联网,包括调用一些不在 VPC 中的 Lambda 函数。
我了解到使用VPC接口端点可以避免通过互联网的流量,但是VPC中的资源通过端点调用AWS服务。所以我在 this documentation 之后创建了一个。特别是,我将端点与我的私有子网和 VPC 的默认安全组相关联。
在我看来似乎ECS任务仍然通过旧方式调用Lambda函数。为了检查它,我在端点中创建了以下策略,拒绝对 lambda 的所有调用,但 ECS 任务仍然可以调用 lambda,所以我假设他们是通过 NAT-igw 方式这样做的。
{
"Statement":[
{
"Principal":"*",
"Effect":"Deny",
"Action":[
"lambda:InvokeFunction"
],
"Resource": [
"arn:aws:lambda:us-east-2:123456789012:function:my-function",
"arn:aws:lambda:us-east-2:123456789012:function:my-function:*"
]
}
]
}
我是否需要以某种方式显式添加一条路由到我的私有子网的路由表,以将针对公共 Lambda 端点的流量路由到我的 VPC 端点?这就是 S3 服务的 VPC 网关端点的工作方式(它将路由自动添加到与 VPC 网关端点关联的路由表中)。要配置接口端点,我被要求将其与子网/安全组而不是路由表相关联。而且我没有看到有人说这是需要的。
回答我自己(感谢@mark-b给我指出正确的方向):
与网关端点不同,接口端点只是每个子网的一个 ENI 和指向它们的 DNS。要使用它来调用外部 Lambda,内部资源可以在调用时将此 DSN 指定为 Lambda 服务端点,这将替换 default 服务端点。例如,我的 ECS 任务使用 Python SDK,所以我可以做类似的事情
lambda_client = boto3.client("lambda", endpoint_url="vpce-123456abcde-abcdef.lambda.us-east-2.vpce.amazonaws.com")
lambda_client.invoke(FunctionName="my_lambda_function")
如果我不指定
endpoint_url="xxxxxxxx"
,SDK会为我们选择默认的,这就是为什么我的ECS任务仍然使用公网路径调用函数的原因。
或者,正如this answer所指出的,我们还可以为端点打开“私有DNS名称”(这需要为VPC打开“DNS主机名”)。这使您的内部资源将默认 DNS(例如,
lambda.us-east-2.amazonaws.com
)解析为您的 VPC 端点而不是公共端点。所以你不需要指定一个特殊的端点 URL。