Error S3-Notification module when Create is conditional
crackmac opened this issue Β· comments
Description
When using a conditional for the 'create' parameter in the S3-Notification module you will get errors Error: invalid value for function_name
and Error: "source_arn" (arn:aws:s3:::) is an invalid ARN: missing resource value
.
Example of error
β Error: invalid value for function_name (must be valid function name or function ARN)
β
β with module.develop_bucket_notify.aws_lambda_permission.allow["content_data_sync_lambda"],
β on .terraform/modules/develop_bucket_notify/modules/notification/main.tf line 67, in resource "aws_lambda_permission" "allow":
β function_name = each.value.function_name
I have/will submit a PR with the proposed fix.
- [
β ]β I have searched the open/closed issues and my issue is not listed.
Versions
-
Module version [Required]:
3.6.1 -
Terraform version:
Terraform v1.2.7
-
Provider version(s):
- provider registry.terraform.io/hashicorp/aws v4.54.0
- provider registry.terraform.io/hashicorp/external v2.2.3
- provider registry.terraform.io/hashicorp/local v2.3.0
- provider registry.terraform.io/hashicorp/null v3.2.1
- provider registry.terraform.io/hashicorp/random v3.4.3
Reproduction Code [Required]
module "develop_bucket_notify" {
source = "terraform-aws-modules/s3-bucket/aws//modules/notification"
version = "3.6.1"
create = var.environment == "develop" ? true : false
bucket = module.bucket.s3_bucket_id
lambda_notifications = {
content_data_sync_lambda = {
function_arn = module.lambda.lambda_function_arn
function_name = module.lambda.lambda_function_name
events = ["s3:ObjectCreated:Put"]
filter_prefix = "test"
}
}
}
Expected behavior
We expect all module resources to not execute if the create
flag is set to false
Actual behavior
The aws_s3_bucket_notification
module resource works as expected.
The aws_lambda_permission
module resource still examines the var.lambda_notifications
object which, in our use case, does not resolve with valid values (function name and arn are only created during certain conditions)
Terminal Output Screenshot(s)
β Error: invalid value for function_name (must be valid function name or function ARN)
β
β with module.develop_bucket_notify.aws_lambda_permission.allow["content_data_sync_lambda"],
β on .terraform/modules/develop_bucket_notify/modules/notification/main.tf line 67, in resource "aws_lambda_permission" "allow":
β function_name = each.value.function_name
Additional context
We use the same Terraform plan for multiple environments and we only create the lambda and hence the S3-Notifications in one environment and not the others.
To do this, you can specify lambda_notifications
conditionally. Like you already do with the create
argument.
Please re-open this issue... we should discuss.
True that you can conditionally set lambda_notifications
, but that would mean setting two conditionals in the same code block and it hurts the readability of the code. This is that mine would look like.
module "develop_bucket_notify" {
source = "terraform-aws-modules/s3-bucket/aws//modules/notification"
version = "3.6.1"
create = var.environment == "develop" ? true : false
bucket = module.develop_bucket.s3_bucket_id != "" ? module.develop_bucket.s3_bucket_id : local.bucket_name
lambda_notifications = var.environment == "develop" ? {
content_data_sync_lambda = {
function_arn = module.lambda.lambda_function_arn
function_name = module.lambda.lambda_function_name
events = ["s3:ObjectCreated:Put"]
filter_prefix = "test"
} : {}
}
}
IMO The create
parameter implies setting it to false should be all you need to do to disable the modele.
I understand that create
is usually a super-argument which controls creation of all-or-nothing, but in this case, a user may want to create resources a bit more independently.
You can also do this:
module "develop_bucket_notify" {
source = "terraform-aws-modules/s3-bucket/aws//modules/notification"
version = "3.6.1"
count = var.environment == "develop" ? 1 : 0
bucket = module.develop_bucket.s3_bucket_id
lambda_notifications = {
content_data_sync_lambda = {
function_arn = module.lambda.lambda_function_arn
function_name = module.lambda.lambda_function_name
events = ["s3:ObjectCreated:Put"]
filter_prefix = "test"
}
}
}
module "prod_bucket_notify" {
source = "terraform-aws-modules/s3-bucket/aws//modules/notification"
version = "3.6.1"
count = var.environment == "develop" ? 0 : 1
bucket = local.bucket_name
}
output "bucket_id" {
value = try(module.prod_bucket_notify[0].bucket_id, module.develop_bucket_notify[0].bucket_id, "")
}
That was my initial approach which failed because even though count = var.environment == "develop" ? 1 : 0
would be false
, the module's for_each loop still tries to render module.lambda.lambda_function_arn
and module.lambda.lambda_function_name
which only exist in the develop environment. That's exactly why I submitted the fix I did.
I'm going to lock this issue because it has been closed for 30 days