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

使用Terraform模块创建资源,模块共享一些资源,terraform,terraform-provider-aws,Terraform,Terraform Provider Aws,我有App1、App2、App3等。为了重用代码,我想使用Terraform模块创建它们 由模块调用的公共基础结构是: root\Common\u infra\main.tf: resource "aws_lambda_function" "app" { # count = “${var.should_launch}” function_name = "app" … } resource "aws_cloudwatch_event_rule" "app" { n

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

由模块调用的公共基础结构是: root\Common\u infra\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.
使用该模块,我成功地启动了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\u name来控制lambda应该做什么

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

aws_cloudwatch_event_target.app_target 
找不到

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

我的问题是:如何组织代码的布局/结构,以便多个模块只声明一次lambda资源?e、 g.也许我应该创建一个新的文件夹root/resource\u,名为\u by\u all\u module/lambda.tf?然后提前部署这个新文件夹?

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

如果你有一个其他东西都依赖的资源,你可以重新安排你的地形,在一个单独的地形上构建这个资源

因此,您可以从这些文件中取出Lambda资源,并将其放在单独的文件夹中。然后,您只需在依赖于这些共享资源的资源('app1','app2')之前,先运行Terraform apply for the shared resources('app'lambda))


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

您是否在询问如何组织代码,以便lambda资源在多个模块中仅声明一次,或者为什么一个模块可以声明,而另一个模块不能声明,或者如何组织代码,使lambda设置独立于特定于应用程序的资源,或者完全其他什么?你很好地描述了当前的状况,但不清楚你在问什么,因为不清楚你想在这里走什么路,因为你所问的问题相当广泛。@MattSchuchard:谢谢,我更新了我的帖子。我的意思是我的代码的正确布局/结构是什么。谢谢你。这可能是唯一的解决方案。我相信通过在Terraform中使用条件等可以实现这一点,但我认为更重要的是保持文件的可读性:)
arn = "${aws_lambda_function.app.arn}"