首页 > 解决方案 > 使用基于 swagger 文件的 terraform 部署 api 网关

问题描述

我想用 terraform 部署我的 api 网关,使用 swagger 文件来描述我的 api。swagger.yaml 看起来像这样:

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 给了我一个BadRequestException说法The REST API doesn't contain any methods

因此,我认为它正在尝试部署 REST api,而无需等待创建此 api 的方法和集成。

这让我想到了必须添加DEPENDS_ONaws_api_gateway_deployment. 但是我不知道要依赖什么,因为我没有使用 swagger 定义方法和集成资源。它们应该自动从 swagger 定义中扣除。

我是否朝着正确的方向思考,如果是这样,我必须aws_api_gateway_deployment依靠什么?或者我尝试部署这个api的方式有什么问题。

我的apigateway.tf文件如下所示:

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"
}

我该如何解决BadRequestException: The REST API doesn't contain any methods

标签: swaggeraws-api-gatewayterraform

解决方案


我发现出了什么问题。这是locals{}块中的语法错误。 uri =应该是uri:。使用冒号代替等号。然后该块如下所示:

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
}

研究这个我发现当你x-amazon-apigateway-integration像这样在 swagger.yaml 中指定时它更容易阅读:

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"

terraform 中的data{}andlocals{}块看起来像:

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}"
}

推荐阅读