I have App1, App2, App3, etc. To reuse code, I want to create them using Terraform module.
The common infrastructure called by modules is: 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.
The module for app1 is as follows: root\app1\main.tf:
module "app1" {
# should_launch = 1
source = "../common_infra"
app_name = "app1"
schedule = "cron(01 01 ? * * *)"
……
}
Using the module, I have successfully launched a cloudwatch event which triggers the lambda at schedule, and I have successfully launched the lambda called “app”. The lambda gets the app_name = app1 as input and then work on app1.
when I create another app2 as follows, root\app2\main.tf:
module "app2" {
# should_launch = 0
source = "../common_infra"
app_name = "app2"
schedule = "cron(01 01 ? * * *)"
……
}
It tries to create another lambda but fails because the lambda has been created by app1 module. In fact I do not want to create a new lambda because It is unnecessary to create multiple lambda for app1, app2…. I can use input = app_name to control what lambda should do.
I try to use should_launch (see above commented lines) to have lambda created only when app1 is created. But it does not work. When deploying app1, the lambda is created. When creating app2. Terrform complains:
aws_cloudwatch_event_target.app_target
cannot find
arn = "${aws_lambda_function.app.arn}"
My question is: how to organize the layout/structure of my code so that the lambda resource is only declared once for multiple modules? e.g. maybe I should create a new folder root/resource_called_by_all_module/lambda.tf? and then deploy this new folder in advance?