我有以下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.
。但是,如果我使用AWS控制台创建相同的API网关,则
Method Response
部分显示的内容有所不同:为什么会这样?
以下步骤是我如何使用AWS控制台创建API网关的方法:
Create Method
。POST
方法。我尝试过先手动创建上述资源,然后执行
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 Framework或AWS SAM),因为在Terraform中创建事件非常冗长且容易出错。
通常,我将Terraform和无服务器框架结合在一起:我使用Terraform创建基础结构资源(即使它们是无服务器的),例如DynamoDB表,SQS队列,SNS主题等,以及无服务器框架来创建Lambda函数及其相应的事件。
关于amazon-web-services - 使用Terraform创建API网关时,为什么方法响应不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56071536/