Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

S3 bucket resource not being found using data

I have a main.tf that looks like this:

resource "aws_s3_bucket" "s3_notifications_bucket" {
  bucket        = local.s3_bucket_name
  force_destroy = true
}

module "s3_notification" {
  source              = "..."
  s3_bucket_name      = local.s3_bucket_name
  function_name       = module.lambda.lambda_function_name
  lambda_function_arn = module.lambda.lambda_arn
}

Module s3_notification uses a reference for that bucket. The reason for that is because when I am running locally, I will be creating this bucket. If it’s deployed code, the bucket will already exist and I don’t have to create it.

data "aws_s3_bucket" "s3_notifications_bucket" {
  bucket = var.s3_bucket_name
}

resource "aws_s3_bucket_notification" "aws_lambda_trigger" {
  bucket = data.aws_s3_bucket.s3_notifications_bucket.id

  lambda_function {
    lambda_function_arn = var.lambda_function_arn
    events              = ["s3:ObjectCreated:*"]
  }
}
    
resource "aws_lambda_permission" "lambda_permission" {
  statement_id  = "AllowS3Invoke"
  action        = "lambda:InvokeFunction"
  function_name = var.function_name
  principal     = "s3.amazonaws.com"
  source_arn    = "arn:aws:s3:::${data.aws_s3_bucket.s3_notifications_bucket.id}"
}

However, when I run terraform apply, I get the following error:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Error: Failed getting S3 bucket (my-bucket): NotFound: Not Found
... in data "aws_s3_bucket" "s3_notifications_bucket":

How do I make that bucket to be created before data reference gets processed?

>Solution :

There is actually no need to rely on using a data source in this case, there needs to be one slight change:

module "s3_notification" {
  source              = "..."
  s3_bucket_name      = aws_s3_bucket.s3_notifications_bucket.id
  function_name       = module.lambda.lambda_function_name
  lambda_function_arn = module.lambda.lambda_arn
}

This uses an implicit resource reference, which means that the S3 bucket will be created first, and only then the bucket name attribute will be passed to the s3_bucket_name in the module call.

Additionally, one change needs to happen in the module code as well:

resource "aws_s3_bucket_notification" "aws_lambda_trigger" {
  bucket = var.s3_bucket_name
  lambda_function {
    lambda_function_arn = var.lambda_function_arn
    events              = ["s3:ObjectCreated:*"]
  }
}

and the data source can be dropped for local testing.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading