我目前使用Lambda函数,该函数使用API网关作为触发器,并且API网关内的方法和端点是手动创建的。我正在尝试将其移至使用Terraform自动创建的位置。不过,我对Terraform还是很陌生,由于每个lambda函数的方法和端点的数量可能不同,因此我很难弄清楚如何创建循环结构。
我已经阅读了模板和内插法,但是由于我需要两层,所以我无法真正拼凑出最佳解决方案
这是我手动创建网关资源时可能会遇到的问题的一个示例。假设端点的数量可以变化,并且每个端点内的方法数量也可以变化。
{
"api_name" : "branches",
"api_description" : "Branches API",
"endpoints" : [
{
"name" : "branch1",
"path" : "branch1/Retail/GetData",
"methods" : [
{
"type" : "get",
"folder" : "branches",
"handler" : "index.handler",
"authenticator": false
}
]
},
{
"name" : "branch2",
"path" : "branch2/Retail/GetData",
"methods" : [
{
"type" : "get",
"folder" : "branches",
"handler" : "index.get_handler",
"authenticator": false
},
{
"type" : "post",
"folder" : "branches",
"handler" : "index.post_handler",
"authenticator": false
}
]
}
]
}
我希望最终结果产生这样的东西:
resource "aws_api_gateway_rest_api" "LambdaTrigger" {
name = "${var.API_NAME}"
description = "${var.API_DESCRIPTION}"
}
resource "aws_api_gateway_resource" "Resource1" {
rest_api_id = "${aws_api_gateway_rest_api.LambdaTrigger.id}"
parent_id = "${aws_api_gateway_rest_api.LambdaTrigger.root_resource_id}"
path_part = "GetData"
}
resource "aws_api_gateway_method" "Method1" {
rest_api_id = "${aws_api_gateway_rest_api.LambdaTrigger.id}"
resource_id = "${aws_api_gateway_resource.Resource1.id}"
http_method = "GET"
authorization = "NONE"
}
resource "aws_api_gateway_resource" "Resource2" {
rest_api_id = "${aws_api_gateway_rest_api.LambdaTrigger.id}"
parent_id = "${aws_api_gateway_rest_api.LambdaTrigger.root_resource_id}"
path_part = "GetData"
}
resource "aws_api_gateway_method" "Method2" {
rest_api_id = "${aws_api_gateway_rest_api.LambdaTrigger.id}"
resource_id = "${aws_api_gateway_resource.Resource2.id}"
http_method = "GET"
authorization = "NONE"
}
resource "aws_api_gateway_method" "Method2" {
rest_api_id = "${aws_api_gateway_rest_api.LambdaTrigger.id}"
resource_id = "${aws_api_gateway_resource.Resource2.id}"
http_method = "POST"
authorization = "NONE"
}
答案 0 :(得分:0)
由于您无法按需要进行循环,并且模块当前不支持count
,因此可以通过module创建资源/方法组,然后每次调用模块以获取资源/模块组。
我使用path_part
字段调整了元数据对象。
{
"api_name" : "branches",
"api_description" : "Branches API",
"endpoints" : [
{
"name" : "branch1",
"path" : "branch1/Retail/GetData",
"path_part": "GetData", // added for simplicity
"methods" : [
{
"type" : "get",
"folder" : "branches",
"handler" : "index.handler",
"authenticator": false
}
]
},
{
"name" : "branch2",
"path" : "branch2/Retail/GetData",
"path_part": "GetData", //added for simplicity
"methods" : [
{
"type" : "get",
"folder" : "branches",
"handler" : "index.get_handler",
"authenticator": false
},
{
"type" : "post",
"folder" : "branches",
"handler" : "index.post_handler",
"authenticator": false
}
]
}
]
}
这是用于制作资源及其方法的模块。它会放在一个单独的文件夹中,供您的主文件引用。对于任何terraform项目,我倾向于为所有模块都拥有一个modules
文件夹,因此类似./modules/api_resources
# variables.tf
variable "rest_api_id" {
type = "string"
}
variable "rest_api_root_resource_id" {
type = "string"
}
variable "endpoints" {
type = "list"
}
# main.tf
resource "aws_api_gateway_resource" "resource" {
rest_api_id = "${var.rest_api_id}"
parent_id = "${var.rest_api_root_resource_id}"
path_part = "${var.endpoints[count.index].path_part}"
}
resource "aws_api_gateway_method" "method" {
count = "${length(var.endpoint.methods)}"
rest_api_id = "${var.rest_api_id}"
resource_id = "${aws_api_gateway_resource.resource.id}"
http_method = "${var.endpoint.methods[count.index].type}"
authorization = "${var.endpoint.methods[count.index].authenticator ? "WHATEVER_AUTH_TYPE_YOU_ARE_USING" : "NONE"}"
}
#outputs.tf
output "resource_id" {
value = "${aws_api_gateway_resource.resource.id}"
}
output "resource_path" {
value = "${aws_api_gateway_resource.resource.path}"
}
现在,您可以在main.tf中为endpoints
的每个部分使用一次该模块。
resource "aws_api_gateway_rest_api" "lambda_trigger" {
name = "${var.api_name}"
description = "${var.api_description}"
}
module "resource1" {
source = "./modules/api_resources"
rest_api_id = "${aws_api_gateway_rest_api.lambda_trigger.id}"
rest_api_root_resource_id = "${aws_api_gateway_rest_api.lambda_trigger.root_resource_id}"
endpoints = "${var.endpoints[0]}"
}
module "resource2" {
source = "./modules/api_resources"
rest_api_id = "${aws_api_gateway_rest_api.lambda_trigger.id}"
rest_api_root_resource_id = "${aws_api_gateway_rest_api.lambda_trigger.root_resource_id}"
endpoints = "${var.endpoints[1]}"
}