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

时间:2019-04-04 13:28:38

标签: terraform terraform-provider-aws

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

模块调用的常见基础结构是: root \ Common_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.

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_ named_by_all_module / lambda.tf?然后预先部署这个新文件夹?

1 个答案:

答案 0 :(得分:1)

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

如果您拥有其他依赖于此的资源,则可以重新布置Terraform以在单独的Terraform应用程序上构建该资源。

因此,您可以从那些文件中取出该Lambda资源,并将其放置在单独的文件夹中。然后,您只需先运行Terraform申请那些共享资源(“ app” lambda),然后再依赖它们的资源(“ app1”,“ app2”)。

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