首页 文章

Terraform - AWS - API网关依赖性难题

提问于
浏览
5

我正在尝试配置一些AWS资源,特别是连接到Lambda的API网关 . 我使用的是Terraform v0.8.8 .

我有一个模块,它提供Lambda并返回lambda函数ARN作为输出,然后我作为参数提供给以下API网关供应代码(基于the example in the TF docs):

provider "aws" {
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
  region     = "${var.region}"
}

# Variables
variable "myregion" { default = "eu-west-2" }
variable "accountId" { default = "" }
variable "lambdaArn" { default = "" }
variable "stageName" { default = "lab" }

# API Gateway
resource "aws_api_gateway_rest_api" "api" {
  name = "myapi"
}

resource "aws_api_gateway_method" "method" {
  rest_api_id   = "${aws_api_gateway_rest_api.api.id}"
  resource_id   = "${aws_api_gateway_rest_api.api.root_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_rest_api.api.root_resource_id}"
  http_method             = "${aws_api_gateway_method.method.http_method}"
  integration_http_method = "POST"
  type                    = "AWS"
  uri                     = "arn:aws:apigateway:${var.myregion}:lambda:path/2015-03-31/functions/${var.lambdaArn}/invocations"
}

# Lambda
resource "aws_lambda_permission" "apigw_lambda" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = "${var.lambdaArn}"
  principal     = "apigateway.amazonaws.com"
  source_arn    = "arn:aws:execute-api:${var.myregion}:${var.accountId}:${aws_api_gateway_rest_api.api.id}/*/${aws_api_gateway_method.method.http_method}/resourcepath/subresourcepath"
}

resource "aws_api_gateway_deployment" "deployment" {
  rest_api_id = "${aws_api_gateway_rest_api.api.id}"
  stage_name = "${var.stageName}"
}

当我从头开始运行上述内容时(即,当没有资源存在时),我收到以下错误:

Error applying plan:

1 error(s) occurred:

* aws_api_gateway_deployment.deployment: Error creating API Gateway Deployment: BadRequestException: No integration defined for method
    status code: 400, request id: 15604135-03f5-11e7-8321-f5a75dc2b0a3

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

如果我执行第二个TF应用程序它一直成功应用,但每次我销毁我然后在第一个应用程序时收到上述错误 .

这让我想知道是否存在我需要在某处显式声明的依赖关系,我发现#7486,它描述了一个类似的模式(尽管与 aws_api_gateway_integration_response 而不是 aws_api_gateway_deployment 有关) . 我尝试手动添加从 aws_api_gateway_deploymentaws_api_gateway_integration 的显式依赖项,但这没有任何效果 .

感谢任何想法,包括这可能确实是一个TF错误,在这种情况下我会在问题跟踪器中提出它 . 在我这样做之前,我想我会先与社区核实,以防我遗漏一些明显的东西 .

非常感谢,

埃德

附:我已经问了this question on the Terraform user group,但这似乎对答案的方式很少,我还没有找出问题的原因,因此现在问这里 .

1 回答

  • 9

    你是明确的依赖声明是正确的 .

    通常Terraform能够找出关系并相应地安排创建/更新/删除操作 - 这通常是因为引擎盖下的插值机制( ${resource_type.ref_name.attribute} ) . 您可以通过terraform graph在图表中显示影响此关系的关系 .

    不幸的是,在这个特定的情况下,'s no direct relationship between API Gateway Deployments and Integrations - meaning the API interface for managing API Gateway resources doesn' t要求您引用集成ID或类似的东西来创建部署,而 api_gateway_deployment 资源依次不需要 .

    documentation for aws_api_gateway_deployment确实在页面顶部提到了这个警告 . 不可否认,部署不仅要求方法存在,还要求集成 .

    以下是修改代码以解决问题的方法:

    resource "aws_api_gateway_deployment" "deployment" {
      rest_api_id = "${aws_api_gateway_rest_api.api.id}"
      stage_name = "${var.stageName}"
      depends_on = ["aws_api_gateway_method.method", "aws_api_gateway_integration.integration"]
    }
    

    从理论上讲, "aws_api_gateway_method.method" 是冗余的,因为集成已经引用了配置中的方法:

    http_method             = "${aws_api_gateway_method.method.http_method}"
    

    所以它将被安排在集成之前进行创建/更新,但是如果你要将其更改为类似的东西

    http_method             = "GET"
    

    那将是必要的 .

    我有submitted PR来相应地更新文档 .

相关问题