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

Edd*_*ant 7 terraform aws-api-gateway

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

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

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}"
}
Run Code Online (Sandbox Code Playgroud)

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

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.
Run Code Online (Sandbox Code Playgroud)

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

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

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

非常感谢,

埃德

PS我在Terraform用户组上问过这个问题,但这似乎对回复的方式很少,我还没有找出问题的原因,因此现在问这里.

Rad*_*mko 13

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

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

不幸的是,在这种特定情况下,API网关部署与集成之间没有直接关系 - 这意味着用于管理API网关资源的API接口不需要您引用集成ID或类似的任何内容来创建部署,而api_gateway_deployment资源又不需要那个.

文档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"]
}
Run Code Online (Sandbox Code Playgroud)

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

http_method             = "${aws_api_gateway_method.method.http_method}"
Run Code Online (Sandbox Code Playgroud)

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

http_method             = "GET"
Run Code Online (Sandbox Code Playgroud)

那将是必要的.

我已提交PR以相应更新文档.