Terraform-provider-aws: aws_api_gateway fail creating API Gateway integration type AWS_PROXY with ANY Method

Created on 13 Jun 2017  ·  9Comments  ·  Source: hashicorp/terraform-provider-aws

_This issue was originally opened by @andrleite as hashicorp/terraform#14963. It was migrated here as part of the provider split. The original body of the issue is below._


I'm trying to create an integration PROXY with lambda but I got this NotFoundException: Invalid Method identifier specified because integration can't be created.

Terraform Version

v0.9.6

Affected Resource(s)

  • aws_api_gateway
  • aws_api_gateway_integration

Terraform Configuration Files

resource "aws_lambda_function" "josh" {
  filename         = "josh.zip"
  function_name    = "josh"
  role             = "${aws_iam_role.josh_lambda_role.arn}"
  handler          = "scheduler.lambda_handler"
  source_code_hash = "${base64sha256(file("josh.zip"))}"
  runtime          = "python3.6"
  memory_size      = 1024
  timeout          = 10

  environment {
    variables = {
      IMAGE_ID = "ami-a8b320c8"
    }
  }
}
resource "aws_api_gateway_rest_api" "joshAPI" {
  name        = "joshAPI"
  description = "This is Job Scheduler API"
}

resource "aws_api_gateway_resource" "joshResource" {
  rest_api_id = "${aws_api_gateway_rest_api.joshAPI.id}"
  parent_id   = "${aws_api_gateway_rest_api.joshAPI.root_resource_id}"
  path_part   = "schedulers"
}

resource "aws_api_gateway_method" "joshAnyMethod" {
  rest_api_id   = "${aws_api_gateway_rest_api.joshAPI.id}"
  resource_id   = "${aws_api_gateway_resource.joshResource.id}"
  http_method   = "ANY"
  authorization = "NONE"
}

resource "aws_api_gateway_method_response" "josh-200" {
  rest_api_id = "${aws_api_gateway_rest_api.joshAPI.id}"
  resource_id = "${aws_api_gateway_resource.joshResource.id}"
  http_method = "${aws_api_gateway_method.joshAnyMethod.http_method}"
  status_code = "200"

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

resource "aws_api_gateway_deployment" "Deployment" {
  depends_on  = ["aws_api_gateway_method.joshAnyMethod"]
  rest_api_id = "${aws_api_gateway_rest_api.joshAPI.id}"
  stage_name  = "prod"
}

resource "aws_api_gateway_integration" "integration" {
  rest_api_id = "${aws_api_gateway_rest_api.joshAPI.id}"
  resource_id = "${aws_api_gateway_rest_api.joshAPI.root_resource_id}"
  http_method = "${aws_api_gateway_method.joshAnyMethod.http_method}"

  type                    = "AWS_PROXY"
  uri                     = "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/${aws_lambda_function.josh.arn}/invocations"
  integration_http_method = "POST"
}

resource "aws_api_gateway_integration_response" "joshIntegrationResponse" {
  rest_api_id = "${aws_api_gateway_rest_api.joshAPI.id}"
  resource_id = "${aws_api_gateway_resource.joshResource.id}"
  http_method = "${aws_api_gateway_method.joshAnyMethod.http_method}"

  status_code = "${aws_api_gateway_method_response.josh-200.status_code}"

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

Debug Output

```3 error(s) occurred:

  • aws_api_gateway_deployment.Deployment: 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: fc875e70-4605-11e7-b492-d30040cb2a25

  • aws_api_gateway_integration_response.joshIntegrationResponse: 1 error(s) occurred:

  • aws_api_gateway_integration_response.joshIntegrationResponse: Error creating API Gateway Integration Response: NotFoundException: No integration defined for method
    status code: 404, request id: fd98cdfb-4605-11e7-a6a8-5944826b1ee7

  • aws_api_gateway_integration.integration: 1 error(s) occurred:

  • aws_api_gateway_integration.integration: Error creating API Gateway Integration: NotFoundException: Invalid Method identifier specified
    status code: 404, request id: 1680fef9-4606-11e7-a1bf-ebe07caa2205
    ```

Expected Behavior

image

Actual Behavior

image

Steps to Reproduce

  1. terraform apply
bug servicapigateway

Most helpful comment

I believe there's a small hiccup in the examples trying to apply the integration to the root resource:

resource_id             = "${aws_api_gateway_rest_api.api_gateway.root_resource_id}"
# should be
resource_id             = "${aws_api_gateway_resource.resource.id}"

All 9 comments

I'm having similar issues with the GET call on v10.0, however I'm new to both AWS and terraform. Is anyone having this issue?

I have the same issue with a GET call (on version 0.9.11)

terraform {
    backend "s3" {
        bucket = "XXXX-terraform"
        key = "staging.tfstate"
    }
}

provider "aws" {}

resource "aws_iam_role" "iam_for_dev_lambda" {
  name = "iam_for_dev_lambda"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

resource "aws_lambda_function" "dev_get_health_lambda" {
  filename         = "backend/backend.jar"
  function_name    = "GetHealth"
  role             = "${aws_iam_role.iam_for_dev_lambda.arn}"
  handler          = "com.XXXX.backend.lambdas.GetHealthRequestHandler"
  source_code_hash = "${base64sha256(file("backend/backend.jar"))}"
  runtime          = "java8"
}

resource "aws_api_gateway_rest_api" "XXXX_api" {
  name = "XXXX_api"
}

resource "aws_api_gateway_method" "get_health" {
  rest_api_id   = "${aws_api_gateway_rest_api.XXXX_api.id}"
  resource_id   = "${aws_api_gateway_rest_api.XXXX_api.root_resource_id}"
  http_method   = "GET"
  authorization = "NONE"
}

resource "aws_api_gateway_resource" "get_health" {
  rest_api_id = "${aws_api_gateway_rest_api.XXXX_api.id}"
  parent_id   = "${aws_api_gateway_rest_api.XXXX_api.root_resource_id}"
  path_part   = "health"
}

variable "aws_region" {}

resource "aws_api_gateway_integration" "get_health_integration" {
  rest_api_id             = "${aws_api_gateway_rest_api.XXXX_api.id}"
  resource_id             = "${aws_api_gateway_rest_api.XXXX_api.root_resource_id}"
  http_method             = "${aws_api_gateway_method.get_health.http_method}"
  integration_http_method = "POST"
  type                    = "AWS"
  uri                     = "arn:aws:apigateway:${var.aws_region}:lambda:path/2015-03-31/functions/${aws_lambda_function.dev_get_health_lambda.arn}/invocations"
}

resource "aws_api_gateway_method_response" "get_health_200" {
  rest_api_id = "${aws_api_gateway_rest_api.XXXX_api.id}"
  resource_id = "${aws_api_gateway_resource.get_health.id}"
  http_method = "${aws_api_gateway_method.get_health.http_method}"
  status_code = "200"
}

resource "aws_lambda_permission" "apigw_get_health_lambda" {
  statement_id  = "AllowDevGetHealthExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = "${aws_lambda_function.dev_get_health_lambda.arn}"
  principal     = "apigateway.amazonaws.com"
}

resource "aws_api_gateway_deployment" "dev_get_health" {
  depends_on = ["aws_api_gateway_method.get_health", "aws_api_gateway_integration.get_health_integration"]

  rest_api_id = "${aws_api_gateway_rest_api.XXXX_api.id}"
  stage_name  = "dev"
}
aws_iam_role.iam_for_dev_lambda: Refreshing state... (ID: iam_for_dev_lambda)
aws_api_gateway_rest_api.XXXX_api: Refreshing state... (ID: uw8cjk5j0m)
aws_api_gateway_method.get_health: Refreshing state... (ID: agm-uw8cjk5j0m-pswa8a7hwb-GET)
aws_api_gateway_resource.get_health: Refreshing state... (ID: pf2ezp)
aws_lambda_function.dev_get_health_lambda: Refreshing state... (ID: GetHealth)
aws_api_gateway_integration.get_health_integration: Refreshing state... (ID: agi-uw8cjk5j0m-pswa8a7hwb-GET)
aws_lambda_permission.apigw_get_health_lambda: Refreshing state... (ID: AllowDevGetHealthExecutionFromAPIGateway)
aws_api_gateway_deployment.dev_get_health: Refreshing state... (ID: kzjmq0)
aws_api_gateway_integration.get_health_integration: Destroying... (ID: agi-uw8cjk5j0m-pswa8a7hwb-GET)
aws_api_gateway_method_response.get_health_200: Creating...
  http_method: "" => "GET"
  resource_id: "" => "pf2ezp"
  rest_api_id: "" => "uw8cjk5j0m"
  status_code: "" => "200"
aws_api_gateway_integration.get_health_integration: Destruction complete
aws_api_gateway_integration.get_health_integration: Creating...
  http_method:             "" => "GET"
  integration_http_method: "" => "GET"
  passthrough_behavior:    "" => "<computed>"
  resource_id:             "" => "pswa8a7hwb"
  rest_api_id:             "" => "uw8cjk5j0m"
  type:                    "" => "AWS"
  uri:                     "" => "arn:aws:apigateway:eu-central-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-central-1:081598652094:function:GetHealth/invocations"
aws_api_gateway_integration.get_health_integration: Creation complete (ID: agi-uw8cjk5j0m-pswa8a7hwb-GET)
Error applying plan:

1 error(s) occurred:

* aws_api_gateway_method_response.get_health_200: 1 error(s) occurred:

* aws_api_gateway_method_response.get_health_200: Error creating API Gateway Method Response: NotFoundException: Invalid Method identifier specified
        status code: 404, request id: 8ad110f0-84ba-11e7-a985-3f313f26c804

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.

Just seen this issue myself, however on rerunning it without changing anything a few moments later, it completed successfully. At a guess either terraform is not waiting for something to really be completed creating (aws_api_gateway_resource ?) or AWS is saying that something is completed creating when really it is not ready yet.

Looks like in our case we weren't explicitly having the integration depending on the method, only on the resource (given that the method is simply identified by being 'GET', 'PUT' etc) - we've hopefully reduced the chance of hitting this issue by referencing the http_method attribute of the aws_api_gateway_method resource rather than just putting 'GET'.

same issue here when trying to create integration based on the following:

resource "aws_api_gateway_method" "api_gateway_method" {
  rest_api_id      = "${aws_api_gateway_rest_api.api_gateway.id}"
  resource_id      = "${aws_api_gateway_resource.resource.id}"
  http_method      = "ANY"
  authorization    = "NONE"
}

resource "aws_api_gateway_integration" "integration" {
  rest_api_id             = "${aws_api_gateway_rest_api.api_gateway.id}"
  resource_id             = "${aws_api_gateway_rest_api.api_gateway.root_resource_id}"
  http_method             = "${aws_api_gateway_method.api_gateway_method.http_method}"
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = "${var.function_invoke_arn}"
}

this is resulting in a request PUT /restapis/{rest_api_id}/resources/{parent_id}/methods/ANY/integration

which returns

Invalid Method identifier specified

any help with this is highly appreceated

I believe there's a small hiccup in the examples trying to apply the integration to the root resource:

resource_id             = "${aws_api_gateway_rest_api.api_gateway.root_resource_id}"
# should be
resource_id             = "${aws_api_gateway_resource.resource.id}"

@mickhansen - Your suggested change seems to have resolved it in my situation... if it works for others, perhaps this is more a documentation bug than anything else

It looks like this was resolved awhile ago with #2022, but please create a new issue if something is still awry. 👍

I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

Was this page helpful?
0 / 5 - 0 ratings