Har*_* KM 4 amazon-web-services terraform aws-api-gateway
我正在构建一个 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"
}
}
Run Code Online (Sandbox Code Playgroud)
在我的模块中,将使用 Terraform 资源部署此输入aws_api_gateway_resource。它需要以下参数:
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.
}
Run Code Online (Sandbox Code Playgroud)
官方文档:链接.
示例:对于输入/pets/{petID},path_part上面的内容将是{petID}&parent_id将是创建 的 Terraform 资源的 ID pets path_part。
所以像这样:
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}"
}
Run Code Online (Sandbox Code Playgroud)
注意:aws_api_gateway_rest_api其他地方已经存在:
resource "aws_api_gateway_rest_api" "rest_api" {
name = "my-api"
}
Run Code Online (Sandbox Code Playgroud)
为了根据用户输入动态地完成所有这些,我有:
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
}
Run Code Online (Sandbox Code Playgroud)
这对于顶级资源非常有效/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.
Run Code Online (Sandbox Code Playgroud)
我怎样才能让它适用于像这样的嵌套资源/pets/{petID}?/pets/{petID}上述计划中创建资源将会失败!挑战在于parent_id为aws_api_gateway_resource嵌套资源设置正确的值。这需要适用于任何级别的嵌套。
注意:存在一个数据源可以返回任何 URL 路径的 ID,如下所示:
data "aws_api_gateway_resource" "pets_resource" {
rest_api_id = aws_api_gateway_rest_api.rest_api.id
path = "/pets"
}
Run Code Online (Sandbox Code Playgroud)
我只是不知道如何将它们组合在一起!
我最终改变了输入格式以使事情变得更容易。最终结果如下:
用户输入:
api_endpoints = {
"/" = { get = "lambda1" }
"/pets" = {
get = "lambda2"
post = "lambda1"
}
"/pets/{petID}" = { get = "lambda3" }
"/toys" = { get = "lambda3" }
}
lambda_functions = {
lambda1 = {
runtime = "nodejs14.x"
handler = "index.handler"
zip = "../lambda1.zip"
}
lambda2 = {
runtime = "nodejs14.x"
handler = "index.handler"
zip = "../lambda2.zip"
}
lambda3 = {
runtime = "python3.7"
handler = "index.handler"
zip = "../lambda3.zip"
}
}
Run Code Online (Sandbox Code Playgroud)
我的 Terraform 模块中处理此用户输入的代码如下:
其余 API:
locals {
openAPI_spec = {
for endpoint, spec in var.api_endpoints : endpoint => {
for method, lambda in spec : method => {
x-amazon-apigateway-integration = {
type = "aws_proxy"
httpMethod = "POST"
uri = "arn:aws:apigateway:${data.aws_region.region.name}:lambda:path/2015-03-31/functions/arn:aws:lambda:${data.aws_region.region.name}:${data.aws_caller_identity.identity.account_id}:function:${lambda}/invocations"
}
}
}
}
}
resource "aws_api_gateway_rest_api" "rest_api" {
name = var.api_name
endpoint_configuration {
types = ["REGIONAL"]
}
body = jsonencode({
openapi = "3.0.1"
paths = local.openAPI_spec
})
}
Run Code Online (Sandbox Code Playgroud)
Lambda 函数:
module "lambda_function" {
source = "terraform-aws-modules/lambda/aws"
for_each = var.lambda_functions
function_name = each.key
runtime = each.value.runtime
handler = each.value.handler
create_package = false
local_existing_package = each.value.zip
create_current_version_allowed_triggers = false
allowed_triggers = {
api-gateway = {
service = "apigateway"
source_arn = "${aws_api_gateway_rest_api.rest_api.execution_arn}/*/*/*"
}
}
}
Run Code Online (Sandbox Code Playgroud)
更多详细信息请参见我的 GitHub 存储库。
| 归档时间: |
|
| 查看次数: |
1930 次 |
| 最近记录: |