AWS - 从公共 API 网关路由到 VPC 内的 lambda

mon*_*mon 6 amazon-web-services aws-lambda aws-api-gateway

从面向公众的 AWS 网络中的 API 网关到 VPC 子网中的 Lambda 函数,流量从哪里经过?

推出 Amazon API Gateway 私有终端节点

通过此次发布,您可以构建不需要公开可用端点的基于 API 的服务。他们仍然可以与您的 VPC 内的私有服务(例如数据库)进行交互。 在此处输入图片说明

背景

当 lambda 不在 VPC 中(在面向 AWS 的公共网络中)时,流量通过 Internet。但不确定 lambda 何时在 VPC 中。

在 AWS 控制台中,我在 VPC 中创建了一个 lambda 函数,并确认 API 网关(不在 VPC 中)可以访问 VPC 中的 lambda。

由于 lambda 在 VPC 的子网中,它没有公网 IP,所以它不应该通过 Internet。但是,如API Gateway Private Integration中所述,没有用于从 API Gateway 连接到 VPC 中的 NLB 的 VPC 私有链接。

因此,我不知道流量从哪里经过。

在此处输入图片说明

地形

Terraform aws_api_gateway_integration资源,connection_type说:

(可选)集成输入的 connectionType。有效值为INTERNET(默认用于通过公共可路由互联网的连接)和 VPC_LINK(用于 API 网关和 VPC 中的网络负载均衡器之间的专用连接)。

因此,它看起来可能会通过 Internet,因为 connection_type 默认是 INTERNET,而 VPC_LINK 目前用于 API Gateway Private Integration with 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}"
}
Run Code Online (Sandbox Code Playgroud)

mon*_*mon 7

正如@Marcin 所回答,它通过 AWS 内部网络。

目前我对 API Gateway 集成的理解(如果错误,请纠正我)。

希望其他人不必通过同样的努力来弄清楚它们。

在此处输入图片说明

更新

根据API Gateway 如何与 Firehose VPC 端点通信,目前的理解是 API 网关与 AWS 服务进行通信,这些服务不在 VPC 中,在 AWS 网络内部,而不是通过 Internet。

在此处输入图片说明 在此处输入图片说明

  • 没有公开证据表明需要特殊的背板,而且类似的东西实际上是必要的,甚至是有益的。单独的神奇路径会引入潜在的漏洞和不必要/无益的复杂性。API Gateway 的后端使用“Invoke”请求调用 Lambda 服务 API,从 Lambda 服务的角度来看,该请求与从控制台发出的测试调用完全相同。服务到服务的交互通过 HTTPS 进行,请求/响应标头/正文序列化为 JSON(这就是原始二进制负载需要 Base64 序列化的原因)。 (3认同)
  • API Gateway 将对 AWS Lambda 端点(而非特定函数)进行 API 调用。然后,Lambda 服务将触发 Lambda 函数。只有 Lambda 函数内的代码才会与 VPC 进行通信,而不是调用该函数的操作。 (2认同)
  • API Gateway 和 Lambda 之间的通信很可能是通过加入服务的“背板”进行的,但我还没有看到任何有关此的信息。 (2认同)