使用Terraform模块创建资源,其中一些资源由模块共享



我有App1、App2、App3等。为了重用代码,我想使用Terraform模块创建它们。

模块调用的通用基础设施是:root\Common_ifra\main.tf:

resource "aws_lambda_function" "app" {
# count = “${var.should_launch}”
function_name = "app"
…
}
resource "aws_cloudwatch_event_rule" "app" {
name                = " ${var.app_name } "
schedule_expression = "${var.app_schedule}"
}
resource "aws_cloudwatch_event_target" "app_target" {
rule      = "${aws_cloudwatch_event_rule.app.name}"
arn       = "${aws_lambda_function.app.arn}"
input = <<EOF
{
"app_name": "${var.app_name}"
}
EOF
}
resource "aws_lambda_permission" "allow_cloudwatch_to_call_lambda"   {
action        = "lambda:InvokeFunction"
function_name =     "${aws_lambda_function.app.function_name}"
principal     = "events.amazonaws.com"
source_arn    = "${aws_cloudwatch_event_rule.app.arn}"
}
# Other resources each app need to create.

app1的模块如下:root\app1\main.tf:

module "app1" {
# should_launch = 1
source  = "../common_infra"
app_name = "app1"
schedule = "cron(01 01 ? * * *)"
……
}

使用该模块,我成功地启动了一个cloudwatch事件,该事件按计划触发lambda,并且我成功地推出了名为"app"的lambda。lambda获取app_name=app1作为输入,然后处理app1。

当我如下创建另一个app2时,root\app2\main.tf:

module "app2" {
# should_launch = 0
source = "../common_infra"
app_name = "app2"
schedule = "cron(01 01 ? * * *)"
……
}

它试图创建另一个lambda,但失败了,因为该lambda是由app1模块创建的。事实上,我不想创建一个新的lambda,因为没有必要为app1、app2…创建多个lambda…。我可以使用input=app_name来控制lambda应该做什么。

我尝试使用should_launch(请参阅上面的注释行)来只在创建app1时创建lambda。但它不起作用。部署app1时,会创建lambda。创建app2。Terrform投诉:

aws_cloudwatch_event_target.app_target 

找不到

arn = "${aws_lambda_function.app.arn}"

我的问题是:如何组织代码的布局/结构,使lambda资源只为多个模块声明一次?例如,也许我应该创建一个新的文件夹root/resource_called_by_all_module/lambda.tf?然后提前部署这个新文件夹?

是的,正如您所指出的,在当前设置中,所有模块都将尝试单独创建该文件中的所有资源。因为lambda的名称是硬编码的,所以terraform会正确地抱怨。

如果你有一个其他东西依赖的资源,你可以重新排列你的地形,在一个单独的地形应用程序上构建该资源。

因此,您可以从这些文件中取出Lambda资源,并将其放在一个单独的文件夹中。然后,您只需先运行Terraform应用程序来获取这些共享资源('app'lambda),然后再运行依赖它们的资源('app1','app2')。

创建共享资源后,您可以使用Terraform数据源(通常用于获取名称或ARN)从中检索所需的详细信息。

相关内容

  • 没有找到相关文章

最新更新