I have a list of ARNs I need to add lambda permission AND consider as a dependency for the bucket notification but unsure how to tie both.
This is my variable:
variable "lambda_filters" {
type = list(object({ lambda_function_arn : string, prefix : string, suffix : string }))
}
This is the permission and the notification:
resource "aws_lambda_permission" "allow_bucket" {
statement_id = "AllowS3Invoke"
action = "lambda:InvokeFunction"
principal = "s3.amazonaws.com"
source_arn = "arn:aws:s3:::${var.bucket}"
I HAVE A LIST AND NOT ONLY ONE ---> function_name = <MY ARN>
}
resource "aws_s3_bucket_notification" "bucket_notification" {
bucket = var.bucket
dynamic "lambda_function" {
for_each = var.lambda_filters
iterator = it
content {
lambda_function_arn = it.value.lambda_function_arn
events = ["s3:ObjectCreated:*"]
filter_prefix = it.value.prefix
filter_suffix = it.value.suffix
}
REFERENCE SOMEHOW HERE --> depends_on = [aws_lambda_permission.allow_bucket]
}
}
As you can see in aws_s3_bucket_notification
, I want to add depends_on
based on all buckets I have to add permission.
Lambda is being created in another module and ARN is the output of that:
output "lambda_arn" {
value = aws_lambda_function.my_lambda.qualified_arn
}
Module is being used like this:
module "s3_bucket_notifications" {
source = "../bucket_notifications"
lambda_filters = [
{
lambda_function_arn : module.my_lambda.lambda_arn,
prefix : "blah/blah", suffix : ".zip"
}
]
}
How do I create lambda permissions for all ARNs inside that list and reference from bucket notification?
What I would suggest is a bit of refactoring of a part of the code to make it easier to work with the rest of the code you have. I would start with redefining the lambda_filters
variable in such a way it is a map instead of a list, as using it with for_each
will be easier:
variable "lambda_filters" {
type = map(map(string))
description = "(optional) describe your variable"
default = {
"lambda1" = {
"lambda_function_arn" = "arn:aws:events:eu-west-1:111122223333:rule"
"prefix" = "blah/blah"
"suffix" = ".zip"
}
}
}
Then, when calling the module for bucket notification, you could try something like:
module "s3_bucket_notifications" {
source = "../bucket_notifications"
lambda_filters = {
"${module.my_lambda.lambda_function_name}" = {
"lambda_function_arn" = module.my_lambda.lambda_arn
"prefix" = "blah/blah"
"suffix" = ".zip"
}
}
}
Of course, for this to work, you would have to define an output value in the Lambda module, i.e., module.my_lambda.lambda_function_name
.
The last part can be reconfigured to use for_each
in the aws_lambda_permission
resource:
resource "aws_lambda_permission" "allow_bucket" {
for_each = var.lambda_filters
statement_id = "AllowS3Invoke"
action = "lambda:InvokeFunction"
principal = "s3.amazonaws.com"
source_arn = "arn:aws:s3:::${var.bucket}"
function_name = each.key
}
While the aws_s3_bucket_notification
resource can be rewritten like this:
resource "aws_s3_bucket_notification" "bucket_notification" {
bucket = var.bucket
dynamic "lambda_function" {
for_each = var.lambda_filters
content {
lambda_function_arn = lambda_function.value.lambda_function_arn
events = ["s3:ObjectCreated:*"]
filter_prefix = lambda_function.value.prefix
filter_suffix = lambda_function.value.suffix
}
}
depends_on = [
aws_lambda_permission.allow_bucket
]
}