api-gateway integration response settings are removed after second terraform apply with same code

Viewed 876

I'm trying to create REST API in AWS API Gateway with terraform.

To enable CORS, option methods and related integration settings are prepared in my tf code. It works well when I did "terraform plan" -> "terraform apply" for the first time. Checking from AWS management console, I found an option method was created as I wrote.

However, when I did "terraform plan" -> "terraform apply" second time without any change of API Gateway, Integration Response settings for Option method was removed even though the apply was completed.("removed" means all Integration response disappears from management console).

Is this usual behaviors? Do I need additional settings to my terraform code?

My present code is following:

resource "aws_api_gateway_resource" "my_api_resource" {
  rest_api_id = "${aws_api_gateway_rest_api.my_api.id}"
  parent_id   = "${aws_api_gateway_rest_api.my_api.root_resource_id}"
  path_part   = "my_api_resource"
}

resource "aws_api_gateway_method" "my_api_method" {
  rest_api_id   = "${aws_api_gateway_rest_api.my_api.id}"
  resource_id   = "${aws_api_gateway_resource.my_api_resource.id}"
  http_method   = "GET"
  authorization = "NONE"
}

resource "aws_api_gateway_integration" "integration_request" {
  rest_api_id             = "${aws_api_gateway_rest_api.my_api.id}"
  resource_id             = "${aws_api_gateway_resource.my_api_resource.id}"
  http_method             = "${aws_api_gateway_method.my_api_method.http_method}"
  integration_http_method = "POST"
  type                    = "AWS"
  uri                     = "${var.my_lambda_invocation_arn}"
}

resource "aws_api_gateway_method_response" "http_status_value" {
  rest_api_id = "${aws_api_gateway_rest_api.my_api.id}"
  resource_id = "${aws_api_gateway_resource.my_api_resource.id}"
  http_method = "${aws_api_gateway_method.my_api_method.http_method}"
  status_code = "200"

  response_models = {
    "application/json" = "Empty"
  }

  response_parameters = {
    "method.response.header.Access-Control-Allow-Origin" = true
  }
}

resource "aws_api_gateway_integration_response" "integration_response" {
  rest_api_id = "${aws_api_gateway_rest_api.my_api.id}"
  resource_id = "${aws_api_gateway_resource.my_api_resource.id}"
  http_method = "${aws_api_gateway_method.my_api_method.http_method}"
  status_code = "${aws_api_gateway_method_response.http_status_value.status_code}"

  response_templates = {
    "application/json" = ""
  }

  response_parameters = {
    "method.response.header.Access-Control-Allow-Origin" = "'*'"
  }
}

### enable cors ###
resource "aws_api_gateway_method" "my_api_method_opt" {
  rest_api_id      = "${aws_api_gateway_rest_api.my_api.id}"
  resource_id      = "${aws_api_gateway_resource.my_api_resource.id}"
  http_method      = "OPTIONS"
  authorization    = "NONE"
  api_key_required = false
}

resource "aws_api_gateway_integration" "integration_request_opt" {
  depends_on = ["aws_api_gateway_method.my_api_method_opt"]
  rest_api_id             = "${aws_api_gateway_rest_api.my_api.id}"
  resource_id             = "${aws_api_gateway_resource.my_api_resource.id}"
  http_method             = "${aws_api_gateway_method.my_api_method_opt.http_method}"
  integration_http_method = "OPTIONS"
  type                    = "MOCK"
  request_templates = {
    "application/json" = "${file("./temp.txt")}"
  }
}

resource "aws_api_gateway_method_response" "method_response_opt_200" {
  rest_api_id = "${aws_api_gateway_rest_api.my_api.id}"
  resource_id = "${aws_api_gateway_resource.my_api_resource.id}"
  http_method = "${aws_api_gateway_method.my_api_method_opt.http_method}"
  status_code = "200"

  response_models = {
    "application/json" = "Empty"
  }

  response_parameters = {
    "method.response.header.Access-Control-Allow-Headers" = true,
    "method.response.header.Access-Control-Allow-Methods" = true,
    "method.response.header.Access-Control-Allow-Origin"  = true
  }
  depends_on = ["aws_api_gateway_method.my_api_method_opt"]
}

resource "aws_api_gateway_integration_response" "integration_response_opt_200" {
  depends_on = ["aws_api_gateway_method.my_api_method_opt", "aws_api_gateway_method_response.method_response_opt_200"]
  rest_api_id       = "${aws_api_gateway_rest_api.my_api.id}"
  resource_id       = "${aws_api_gateway_resource.my_api_resource.id}"
  http_method       = "${aws_api_gateway_method.my_api_method_opt.http_method}"
  status_code       = "${aws_api_gateway_method_response.method_response_opt_200.status_code}"

  response_templates = {
    "application/json" = ""
  }

  response_parameters = {
    "method.response.header.Access-Control-Allow-Headers" = "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
    "method.response.header.Access-Control-Allow-Methods" = "'GET,OPTIONS'",
    "method.response.header.Access-Control-Allow-Origin"  = "'*'"
  }
}

resource "aws_api_gateway_deployment" "my_api_deploy" {
  depends_on  = ["aws_api_gateway_integration_response.integration_response","aws_api_gateway_integration.integration_request", "aws_api_gateway_integration.integration_request_opt","aws_api_gateway_integration_response.integration_response_opt_200"]
  rest_api_id = "${aws_api_gateway_rest_api.my_api.id}"
  stage_name  = "dev"
}

I don't know if it's crucial to this problem, I'm using s3 bucket and dynamoDB for saving tfstate and state lock.

1 Answers

It seems having integration_request_method on a MOCK integration causes some form of conflict, try removing that field as it isn't required

Related