amazon-web-services - 使用Terraform创建API网关时,为什么方法响应不同?

标签 amazon-web-services aws-api-gateway terraform

我有以下terraform脚本,该脚本创建了一个API网关,该网关将请求传递给lambda函数。

provider "aws" {

  access_key = "${var.access_key}"

  secret_key = "${var.secret_key}"
  # 
  region     = "${var.region}"

  version = "~> 2.6"
}

resource "aws_api_gateway_rest_api" "MyDemoAPI" {
  name        = "MyDemoAPI"
  description = "This is my API for demonstration purposes"
}

resource "aws_api_gateway_resource" "MyDemoResource" {
  rest_api_id = "${aws_api_gateway_rest_api.MyDemoAPI.id}"
  parent_id   = "${aws_api_gateway_rest_api.MyDemoAPI.root_resource_id}"
  path_part   = "mydemoresource"
}

resource "aws_api_gateway_method" "MyDemoMethod" {
  rest_api_id   = "${aws_api_gateway_rest_api.MyDemoAPI.id}"
  resource_id   = "${aws_api_gateway_resource.MyDemoResource.id}"
  http_method   = "POST"
  authorization = "NONE"
}

resource "aws_api_gateway_integration" "MyDemoIntegration" {
  rest_api_id = "${aws_api_gateway_rest_api.MyDemoAPI.id}"
  resource_id = "${aws_api_gateway_resource.MyDemoResource.id}"
  http_method = "${aws_api_gateway_method.MyDemoMethod.http_method}"
  integration_http_method = "POST"
  type        = "AWS_PROXY"
  uri         = "arn:aws:apigateway:ap-southeast-1:lambda:path/2015-03-31/functions/${aws_lambda_function.test_lambda_function.arn}/invocations"
  content_handling = "CONVERT_TO_TEXT"
}

resource "aws_api_gateway_method_response" "200" {
  rest_api_id = "${aws_api_gateway_rest_api.MyDemoAPI.id}"
  resource_id = "${aws_api_gateway_resource.MyDemoResource.id}"
  http_method = "${aws_api_gateway_method.MyDemoMethod.http_method}"
  status_code = "200"
  response_models {
     "application/json" = "Empty"
  }
}

resource "aws_lambda_function" "test_lambda_function" {
  filename         = "lambda.zip"
  description      = "test build api gateway and lambda function using terraform"
  function_name    = "test_lambda_function"
  role             = "arn:aws:iam::123456789123:role/my_labmda_role"
  handler          = "gateway.lambda_handler"
  runtime          = "python3.6"
  memory_size      = 128
  timeout          = 60
}

API网关资源的Method Response部分显示Select an integration response.

enter image description here

但是,如果我使用AWS控制台创建相同的API网关,则Method Response部分显示的内容有所不同:

enter image description here

为什么会这样?

以下步骤是我如何使用AWS控制台创建API网关的方法:
  • 在资源下选择Create Method
    enter image description here
  • 选择POST方法。
    enter image description here
  • 选择所需的选项。
    enter image description here

  • 我尝试过先手动创建上述资源,然后执行terraform apply。然后terraform告诉我什么都不需要更改。
    terraform apply
    aws_api_gateway_rest_api.MyDemoAPI: Refreshing state... (ID: 1qa34vs1k7)
    aws_lambda_function.test_lambda_function: Refreshing state... (ID: test_lambda_function)
    aws_api_gateway_resource.MyDemoResource: Refreshing state... (ID: 4xej81)
    aws_api_gateway_method.MyDemoMethod: Refreshing state... (ID: agm-1qa34vs1k7-4xej81-POST)
    aws_api_gateway_method_response.200: Refreshing state... (ID: agmr-1qa34vs1k7-4xej81-POST-200)
    aws_api_gateway_integration.MyDemoIntegration: Refreshing state... (ID: agi-1qa34vs1k7-4xej81-POST)
    
    Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
    

    这似乎意味着手动构建的结构与terraform构建的结构相同。

    最佳答案

    由于API Gateway是一个复杂的AWS组件,您可以控制它上的几乎所有内容(基本上,它的每个部分都是独立管理的,这使您可以对创建的内容进行很多控制,但也使得处理起来更加困难)。

    看到它说“选择一个集成响应”,但是由于您的Terraform代码没有创建一个,因此为空。

    几周前,我遇到了同样的问题,并且在Terraform的GitHub上找到了解决方案。我认为Terraform应该更好地记录这一点,因为您不是第一个提出这个问题的人,也不是您提出这个问题的最后一个人。好吧,至少现在我们已经在StackOverflow中对此进行了记录:)

    长话短说,您需要向API网关添加aws_api_gateway_integration_response terraform资源。

    resource "aws_api_gateway_integration_response" "MyDemoIntegrationResponse" {
       rest_api_id = "${aws_api_gateway_rest_api.MyDemoAPI.id}"
       resource_id = "${aws_api_gateway_resource.MyDemoResource.id}"
       http_method = "${aws_api_gateway_method.MyDemoMethod.http_method}"
       status_code = "${aws_api_gateway_method_response.200.status_code}"
    
       response_templates = {
           "application/json" = ""
       } 
    }
    

    但是,如果可以的话,我建议您使用适当的框架将事件挂接到Lambda函数(例如Serverless FrameworkAWS SAM),因为在Terraform中创建事件非常冗长且容易出错。

    通常,我将Terraform和无服务器框架结合在一起:我使用Terraform创建基础结构资源(即使它们是无服务器的),例如DynamoDB表,SQS队列,SNS主题等,以及无服务器框架来创建Lambda函数及其相应的事件。

    关于amazon-web-services - 使用Terraform创建API网关时,为什么方法响应不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56071536/

    相关文章:

    c# - AWS API 网关 403 :Forbidden

    amazon-web-services - CloudFront 和 API 网关缺少身份验证 token 错误

    amazon-web-services - AWS 的 Terraform : How to have multiple events per S3 bucket filtered on object path?

    javascript - 从 Amazon 检索 ASIN 并将其存储在 Netsuite 中

    amazon-web-services - Docker,GitLab并将镜像部署到AWS EC2

    python-3.x - 使用 boto3 验证 AWS 凭证

    python - API网关主体映射动了?

    azure - 使用 terraform 管理许多 azure 订阅

    amazon-web-services - 如何在 terraform 中导入 aws_lambda_permission

    node.js - 使用 Amazon Cognito 将用户添加到用户池