【发布时间】:2021-07-29 21:16:49
【问题描述】:
我正在构建一个 Terraform 模块,该模块在 AWS API Gateway 中部署一个 REST API。该模块的用户将提供如下输入:
api_resources = {
resource1 = {
api_endpoint = "/pets/{petID}"
http_method = "GET"
},
resource2 = {
api_endpoint = "/pets"
http_method = "GET"
},
resource3 = {
api_endpoint = "/toys"
http_method = "GET"
},
resource4 = {
api_endpoint = "/pets"
http_method = "POST"
}
}
在我的模块中,此输入将使用aws_api_gateway_resource Terraform 资源进行部署。它采用以下参数:
resource "aws_api_gateway_resource" "resource" {
rest_api_id = # ID of the parent REST API resource.
parent_id = # ID of the immediate parent of this "part" of the API endpoint.
path_part = # The rightmost "part" of the endpoint URL.
}
官方文档:Link.
示例:对于输入 /pets/{petID},上面的 path_part 将是 {petID},parent_id 将是创建 pets path_part 的 Terraform 资源的 ID。
所以是这样的:
resource "aws_api_gateway_resource" "pets_resource" {
rest_api_id = aws_api_gateway_rest_api.rest_api.id
parent_id = aws_api_gateway_rest_api.rest_api.root_resource_id
path_part = "pets"
}
resource "aws_api_gateway_resource" "petID_resource" {
rest_api_id = aws_api_gateway_rest_api.rest_api.id
parent_id = aws_api_gateway_resource.pets_resource.id
path_part = "{petID}"
}
注意:aws_api_gateway_rest_api 已经存在于别处:
resource "aws_api_gateway_rest_api" "rest_api" {
name = "my-api"
}
为了根据用户输入动态完成所有这些,我有:
- 从输入中提取所有 API 端点。
- 遍历它们并为每个资源创建一个
aws_api_gateway_resource。
像这样:
locals {
api_endpoints = toset([
for key, value in var.api_resources :
trimprefix(value.api_endpoint, "/")
])
}
resource "aws_api_gateway_resource" "resource" {
rest_api_id = aws_api_gateway_rest_api.rest_api.id
parent_id = aws_api_gateway_rest_api.rest_api.root_resource_id
for_each = local.api_endpoints # pets/{petID}, pets, toys
path_part = each.key
}
这适用于顶级资源/pets 和/toys,如此 Terraform 计划所示:
Terraform will perform the following actions:
# aws_api_gateway_resource.resource["pets"] will be created
+ resource "aws_api_gateway_resource" "resource" {
+ id = (known after apply)
+ parent_id = "e79wlf30x5"
+ path = (known after apply)
+ path_part = "pets"
+ rest_api_id = "yrpm6dx4z8"
}
# aws_api_gateway_resource.resource["pets/{petID}"] will be created
+ resource "aws_api_gateway_resource" "resource" {
+ id = (known after apply)
+ parent_id = "e79wlf30x5"
+ path = (known after apply)
+ path_part = "pets/{petID}"
+ rest_api_id = "yrpm6dx4z8"
}
# aws_api_gateway_resource.resource["toys"] will be created
+ resource "aws_api_gateway_resource" "resource" {
+ id = (known after apply)
+ parent_id = "e79wlf30x5"
+ path = (known after apply)
+ path_part = "toys"
+ rest_api_id = "yrpm6dx4z8"
}
Plan: 3 to add, 0 to change, 0 to destroy.
如何使它适用于像/pets/{petID} 这样的嵌套资源? 在上述计划中创建/pets/{petID} 资源将失败!挑战在于为嵌套资源的aws_api_gateway_resource 设置正确的parent_id。这需要适用于任何级别的嵌套。
注意:有一个数据源可以像这样返回任意 URL 路径的 ID:
data "aws_api_gateway_resource" "pets_resource" {
rest_api_id = aws_api_gateway_rest_api.rest_api.id
path = "/pets"
}
我只是不知道如何把它们放在一起!
【问题讨论】:
标签: amazon-web-services terraform aws-api-gateway