Question
从面向公众的AWS网络中的API网关到VPC子网中的Lambda函数,流量经过哪里?
推出 Amazon API Gateway 私有终端节点 https://aws.amazon.com/blogs/compute/introducing-amazon-api-gateway-private-endpoints/
With this launch, you could build API-based services that did not require a publicly available endpoint. They could still interact with private services, such as databases, inside your VPC.
背景
当 lambda 不在 VPC 中(在 AWS 面向公众的网络中)时,流量将通过 Internet。但不确定 lambda 何时位于 VPC 中。
我从 AWS 控制台在 VPC 中创建了一个 lambda 函数,并确认 API 网关(不在 VPC 中)可以使用 VPC 中的 lambda。
由于 lambda 位于 VPC 中的子网中,因此它没有公共 IP,因此它不应该通过 Internet。但是,没有用于从 API 网关连接到 VPC 中的 NLB 的 VPC 专用链接,如中所述API网关私有集成 https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-private-integration.html.
因此我不知道交通经过哪里。
地形
地形aws_api_gateway_integration https://www.terraform.io/docs/providers/aws/r/api_gateway_integration.html资源,连接类型 says:
(可选)集成输入的连接类型。有效值为INTERNET(默认通过公共可路由互联网进行连接)和 VPC_LINK(用于 API 网关与 VPC 中的网络负载均衡器之间的专用连接)。
因此,它看起来可能会通过 Internet,因为 connection_type 默认为 INTERNET,而 VPC_LINK 目前用于 API 网关与 NLB 的私有集成。
# Variables
variable "myregion" {
default = "us-east-2"
}
variable "accountId" {
default = var.account_id
}
# API Gateway
resource "aws_api_gateway_rest_api" "api" {
name = "api-lambda-vpc-test"
}
resource "aws_api_gateway_resource" "resource" {
path_part = "resource"
parent_id = "${aws_api_gateway_rest_api.api.root_resource_id}"
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
}
resource "aws_api_gateway_method" "method" {
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
resource_id = "${aws_api_gateway_resource.resource.id}"
http_method = "GET"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "integration" {
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
resource_id = "${aws_api_gateway_resource.resource.id}"
http_method = "${aws_api_gateway_method.method.http_method}"
integration_http_method = "POST"
type = "AWS_PROXY"
uri = "${aws_lambda_function.lambda.invoke_arn}"
}
# Lambda
resource "aws_lambda_permission" "apigw_lambda" {
statement_id = "AllowExecutionFromAPIGateway"
action = "lambda:InvokeFunction"
function_name = "${aws_lambda_function.lambda.function_name}"
principal = "apigateway.amazonaws.com"
# More: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-control-access-using-iam-policies-to-invoke-api.html
source_arn = "arn:aws:execute-api:${var.myregion}:${var.accountId}:${aws_api_gateway_rest_api.api.id}/*/${aws_api_gateway_method.method.http_method}${aws_api_gateway_resource.resource.path}"
}
resource "aws_lambda_function" "lambda" {
filename = "lambda.zip"
function_name = "mylambda"
role = "${aws_iam_role.role.arn}"
handler = "lambda.lambda_handler"
runtime = "python3.6"
vpc_config {
security_group_ids = var.sg_ids
subnet_ids = var.subnet_ids
}
# The filebase64sha256() function is available in Terraform 0.11.12 and later
# For Terraform 0.11.11 and earlier, use the base64sha256() function and the file() function:
# source_code_hash = "${base64sha256(file("lambda.zip"))}"
source_code_hash = "${filebase64sha256("lambda.zip")}"
}
# IAM
resource "aws_iam_role" "role" {
name = "myrole"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
POLICY
}
data "aws_iam_policy" "admin" {
arn = "arn:aws:iam::aws:policy/AdministratorAccess"
}
resource "aws_iam_role_policy_attachment" "admin" {
role = "${aws_iam_role.role.id}"
policy_arn = "${data.aws_iam_policy.admin.arn}"
}