【问题标题】:Terraform: Create url path parameter for AWS API Gateway that invokes Lambda?Terraform:为调用 Lambda 的 AWS API Gateway 创建 url 路径参数?
【发布时间】:2019-10-28 12:29:18
【问题描述】:

我正在编写 Terraform 来部署具有 AWS Lambda 集成的 AWS API 网关。我想在我可以从 lambda 引用的 url 中指定一个可选的路径参数。我不知道如何在 AWS API Gateway terraform 中指定它。

我能找到的关于路径变量的唯一信息是这个 SO 帖子:In Terraform, how do you specify an API Gateway endpoint with a variable in the request path?

其中,答案指定了 aws_api_gateway_integration 函数的 uri 字段中的路径变量:

resource "aws_api_gateway_integration" "get-account-integration" {
    rest_api_id             = "${var.gateway_id}"
    resource_id             = "${var.resource_id}"
    http_method             = "${aws_api_gateway_method.get-account.http_method}"
    type                    = "HTTP"
    integration_http_method = "GET"
    uri                     = "/integration/accounts/{id}" # <--
    passthrough_behavior    = "WHEN_NO_MATCH"

    request_parameters {
        "integration.request.path.id" = "method.request.path.accountId"
    }
}

不幸的是,AWS Lambda 集成使用该 uri 字段作为 lambda 的 ARN。以下是我在集成中引用 lambda 的方式:

resource "aws_api_gateway_integration" "books_lambda" {
  rest_api_id             = "${var.gateway.id}"
  resource_id             = "${var.resource_id}"
  http_method             = "${aws_api_gateway_method.books.http_method}"
  type                    = "AWS_PROXY"
  integration_http_method = "POST"
  uri                     = "${var.books_invoke_arn}" # <--
  credentials             = "${aws_iam_role.books_gateway.arn}"

  request_parameters {
    "integration.request.path.id" = "method.request.path.bookId"
  }
}

因为arn是在uri字段的地方,所以不知道在哪里定义path参数的放置。

我尝试将路径变量附加到 uri 字段 (${var.books_invoke_arn}/{bookId}),但这只会产生错误。当uri字段被lambda arn占用时,在哪里可以指定路径变量?

其次,是否可以使该变量成为可选变量,或者我必须拥有第二组 terraform(一个带变量,一个不带)?

谢谢!

【问题讨论】:

  • 您解决了这个问题吗?

标签: lambda aws-api-gateway terraform terraform-provider-aws


【解决方案1】:

这是一个老问题,但它出现在我的一次搜索中。我认为事情可能在此期间发生了变化,但目前的一种方法是通过在 route_key 中的花括号中指定您的变量,如我们代码中的此示例所示:

resource "aws_apigatewayv2_route" "room-recommendations-ng" {
  api_id             = aws_apigatewayv2_api.this.id
  route_key          = "GET /rooms/{room}/recommendations"
  target             = "integrations/${aws_apigatewayv2_integration.room-recommendations.id}"
}

【讨论】:

    【解决方案2】:

    由于类型是 AWS_PROXY,因此 URI 必须是根据 RFC-3986 规范的完整格式、编码的 HTTP(S) URL。对于 AWS 集成,URI 的格式应为 arn:aws:apigateway:{region}:{subdomain.service|service}:{path|action}/{service_api}。

    试试下面的代码(我假设是 us-east-1 区域):

    resource "aws_api_gateway_integration" "books_lambda" {
      rest_api_id             = var.gateway.id
      resource_id             = var.resource_id
      http_method             = aws_api_gateway_method.books.http_method
      type                    = "AWS_PROXY"
      integration_http_method = "POST"
      uri                     = "arn:aws:apigateway:us-east-1:lambda:path/integration/accounts/{id}"
      credentials             = aws_iam_role.books_gateway.arn
    
      request_parameters      = {
        "integration.request.path.id" = "method.request.path.bookId"
      }
    }
    

    更多信息请见Resource: aws_api_gateway_integration

    【讨论】:

      【解决方案3】:

      terraform document 已经给出了答案。

      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                     = "arn:aws:apigateway:${var.myregion}:lambda:path/2015-03-31/functions/${aws_lambda_function.lambda.arn}/invocations"
      }
      

      对于第二个问题,我需要详细信息,对于当前的描述,您可以考虑使用count 来管理它。

      参考:

      https://www.terraform.io/intro/examples/count.html

      https://www.terraform.io/docs/configuration/resources.html#count-multiple-resource-instances

      更新

      由于您没有粘贴有关如何管理 lambda 函数的代码。如果您确实管理它,您可以将其引用为${aws_lambda_function.lambda.arn}

      resource "aws_lambda_function" "lambda" {
        filename      = "lambda_function_payload.zip"
        function_name = "lambda_function_name"
        ...
      }
      

      如果存在 lambda 函数,您可以通过其数据源获取其详细信息

      data "aws_lambda_function" "existing_lambda" {
        function_name = "${var.function_name}"
      }
      

      您可以将其引用为data.aws_lambda_function.existing_lambda.arn

      【讨论】:

      • 感谢您的回复,宝马。我花了很多时间处理您链接的 terraform 文档,但我没有看到答案。您是说路径参数需要成为 lambda arn 的一部分吗?如果是这样,我应该在 arn 中的哪个位置放置路径参数?
      • 感谢您花时间更新您的答案,但我相信我们之间有些混淆。我可以毫无问题地引用 lambda。我从我的 lambda terraform 导出 lambda arn,并将其插入 aws_api_gateway_integration 的 uri 字段(您可以在上面的第二个代码块中看到我的代码)。不清楚的是如何在上面的集成 terraform 中指定路径参数。 uri 字段通常是那个地方,但是由于 uri 字段有 lambda arn,我不知道如何或在哪里指定路径参数的位置。
      • @user2233394 你只需要添加lamba arn而不是路径本身。您也不需要在集成设置中的 request_parameters 中添加映射。通过资源设置路径参数后,它们将在您的 Lambda 事件中显示为pathParameters
      猜你喜欢
      • 2020-05-28
      • 1970-01-01
      • 2018-02-25
      • 1970-01-01
      • 1970-01-01
      • 2018-02-02
      • 2022-06-30
      • 2016-02-06
      • 2017-12-07
      相关资源
      最近更新 更多