Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deploy api gateway with terraform based on a swagger file

I want to deploy my api gateway with terraform using a swagger file to describe my api. The swagger.yaml looks like this:

swagger: '2.0'
info:
  version: '1.0'
  title: "CodingTips"
schemes:
  - https
paths:
  "/api":
    get:
      description: "Get coding tips"
      produces:
        - application/json
      x-amazon-apigateway-integration: ${apiIntegration}
      responses:
        '200':
          description: "Codingtips were successfully requested"

Terraform is giving me a BadRequestException saying that The REST API doesn't contain any methods.

Because of this I am thinking that it is trying to deploy the REST api without waiting for the methods and integrations of this api to be created.

This made me think in the direction of having to add DEPENDS_ON to the aws_api_gateway_deployment. However I do not know what to depend on since I don't define the method and integration resource using swagger. They should be automatically deducted from the swagger definition.

Am I thinking in the right direction and if so, what do I have to make my aws_api_gateway_deployment depend on? Or is something else wrong with the way I am trying to deploy this api.

My apigateway.tf file looks like this:

resource "aws_api_gateway_rest_api" "codingtips-api-gateway" {
  name        = "ServerlessExample"
  description = "Terraform Serverless Application Example"
  body        = "${data.template_file.codingtips_api_swagger.rendered}"
}

locals{
  "get_codingtips_arn" = "${aws_lambda_function.get-tips-lambda.invoke_arn}"

  "x-amazon-coding-tips-apigateway-integration" = <<EOF
#
uri = "${local.get_codingtips_arn}"
passthroughBehavior: when_no_match
httpMethod: POST
type: aws_proxy
credentials: "${aws_iam_role.api_gateway_role.arn}"
EOF
}

data "template_file" codingtips_api_swagger{
  template = "${file("./swagger.yaml")}"

  vars {
    apiIntegration = "${indent(8, local.x-amazon-coding-tips-apigateway-integration)}"
  }
}

resource "aws_api_gateway_deployment" "codingtips-api-gateway-deployment" {
  rest_api_id = "${aws_api_gateway_rest_api.codingtips-api-gateway.id}"
  stage_name  = "test"
}

How can I fix the BadRequestException: The REST API doesn't contain any methods ?

like image 655
xtra Avatar asked Feb 04 '23 20:02

xtra


1 Answers

I found out what was wrong. It is a syntactical error in the locals{} block. uri = should be uri: . Using a colon instead of an equal sign. The block then looks like this:

locals{
  "get_codingtips_arn" = "${aws_lambda_function.get-tips-lambda.invoke_arn}"

  "x-amazon-codingtips-get-apigateway-integration" = <<EOF
# comment for new line
uri: "${aws_lambda_function.get-tips-lambda.invoke_arn}"
passthroughBehavior: when_no_match
httpMethod: POST
type: aws_proxy
EOF
}

Researching this I found that it reads easier when you specify the x-amazon-apigateway-integration in the swagger.yaml like this:

swagger: '2.0'
info:
  version: '1.0'
  title: "CodingTips"
schemes:
  - https
paths:
  "/api":
    get:
      description: "Get coding tips"
      produces:
        - application/json
      responses:
        '200':
          description: "The codingtips request was successful."
      x-amazon-apigateway-integration:
        uri: ${uri_arn}
        passthroughBehavior: "when_no_match"
        httpMethod: "POST"
        type: "aws_proxy"

The data{} and locals{} blocks in your terraform then look like:

data "template_file" codingtips_api_swagger{
  template = "${file("swagger.yaml")}"

  vars {
    uri_arn = "${local.get_codingtips_arn}"
  }
}

locals {
  "get_codingtips_arn" = "${aws_lambda_function.get-tips-lambda.invoke_arn}"
}
like image 182
xtra Avatar answered Feb 08 '23 17:02

xtra