Home > other >  Terraform: API Gateway Lambda - No integration defined for method
Terraform: API Gateway Lambda - No integration defined for method

Time:12-31

I am trying to create an API Gateway with Lambda integration but got stuck in an error:

│ Error: Error creating API Gateway Deployment: BadRequestException: No integration defined for method
│ 
│   with aws_api_gateway_deployment.api-gw,
│   on main.tf line 35, in resource "aws_api_gateway_deployment" "api-gw":
│   35: resource "aws_api_gateway_deployment" "api-gw" {

│ I made some online research and noticed that I needed to have an explicit dependency between the deployment resource and the integration / method, which I did but it is still not working.

Here you can find my code:

data "template_file" "aws_api_swagger" {
  template = file("${path.module}/openapi.yaml")

  vars = {
   version      = "0.1"
   title        = "Whatever"
   url          = "https://api.example.com"
  }
}

resource "aws_api_gateway_rest_api" "api-gw" {
  body = "${data.template_file.aws_api_swagger.rendered}"
  name = "Whatever"
  endpoint_configuration {
    types = ["REGIONAL"]
  }
}

resource "aws_api_gateway_deployment" "api-gw" {
  rest_api_id = aws_api_gateway_rest_api.api-gw.id

  triggers = {
    redeployment = sha1(jsonencode(aws_api_gateway_rest_api.api-gw.body))
  }

  lifecycle {
    create_before_destroy = true
  }

  depends_on = [
      aws_api_gateway_integration.api-gw,
      aws_api_gateway_method.api-gw
      ]
}

resource "aws_api_gateway_stage" "example" {
  deployment_id = aws_api_gateway_deployment.api-gw.id
  rest_api_id   = aws_api_gateway_rest_api.api-gw.id
  stage_name    = "prod"
}

resource "aws_api_gateway_resource" "api-gw" {
  path_part   = "destinations"
  parent_id   = aws_api_gateway_rest_api.api-gw.root_resource_id
  rest_api_id = aws_api_gateway_rest_api.api-gw.id
}

resource "aws_api_gateway_method" "api-gw" {
  rest_api_id   = aws_api_gateway_rest_api.api-gw.id
  resource_id   = aws_api_gateway_resource.api-gw.id
  http_method   = "GET"
  authorization = "NONE"
}

resource "aws_api_gateway_integration" "api-gw" {
  rest_api_id             = aws_api_gateway_rest_api.api-gw.id
  resource_id             = aws_api_gateway_resource.api-gw.id
  http_method             = aws_api_gateway_method.api-gw.http_method
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = "arn:aws:apigateway:<MYREGION>:lambda:path/2015-03-31/functions/arn:aws:lambda:<MYREGION>:<MYACCOUNT>:function:<WHATEVER>/invocations"
}

resource "aws_lambda_permission" "apigw_lambda" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = var.lambda_function
  principal     = "apigateway.amazonaws.com"
  source_arn    = "arn:aws:execute-api:<MYREGION>:<MYACCOUNT>:<ID>/*/GET/destinations"
  //source_arn = "arn:aws:execute-api:${var.region}:${var.account}:${aws_api_gateway_rest_api.api-gw.id}/*/${aws_api_gateway_method.api-gw.http_method}${aws_api_gateway_resource.api-gw.path}"
}

Here you can find the OPENAPI definition:

openapi: "3.0.2"

info:
  title: ${title}
  version: ${version}

servers:
  - url: ${url}

paths:
  /flyto:
    get:
      description: Returns a list of destinations JetAir flies to. 
      parameters:
          - name: iata
            in: query
            description: IATA code of the departure city. If no code is provided, it returns all cities.
            schema:
              type: string
            allowEmptyValue: true
      responses:
        "200":
          description: Successfully returned a list of destinations.
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  required:
                    - username
                  properties:
                    id:
                      type: integer
                      example: 5
                    location:
                      type: string
                      example: "Sao Paulo"
                    coordinates:
                      type: object
                      properties:
                        lat:
                          type: number
                          format: double
                          example: -23.45
                        lng:
                          type: number
                          format: double
                          example: -46.53
                    destinations:
                      type: array
                      items:
                        type: number
                        example: [1, 2, 4, 6]
                    visible:
                      type: boolean
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: "Your request could not be completed"

Another thing I can't get done with Terraform is to integrate a path defined through OpenAPI with a Lambda Integration.

Thank you very much!

CodePudding user response:

Based on the comments.

An attempt to replicate the issue showed that the code provided is correct. Further investigation relieved was OPENAPI file was commented in the actual code used by the OP.

  • Related