Terraform:为调用 Lambda 的 AWS API Gateway 创建 url 路径参数?

Posted

技术标签:

【中文标题】Terraform:为调用 Lambda 的 AWS API Gateway 创建 url 路径参数?【英文标题】:Terraform: Create url path parameter for AWS API Gateway that invokes Lambda? 【发布时间】: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(一个带变量,一个不带)?

谢谢!

【问题讨论】:

您解决了这个问题吗? 【参考方案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

以上是关于Terraform:为调用 Lambda 的 AWS API Gateway 创建 url 路径参数?的主要内容,如果未能解决你的问题,请参考以下文章

从 API Gateway 获取 terraform 中 AWS lambda 的端点

Terraform:通知 SNS 的 CloudWatch 事件

Terraform 错误 EntityAlreadyExists:名称为 iam_for_lambda 的角色已存在

使用 terraform 部署多个 lambda 函数

如何在 Terraform 中配置 CloudWatch Lambda Insights

使用包含多个文件的 terraform 部署 lambda?