How to create S3 bucket and Lambda in Terraform when they are codependent on each other?

Viewed 58

I am creating a Lambda function that has it's handler code stored in an S3 bucket. I need to create these resources and I am using Terraform.

It appears the S3 bucket is dependent on the Lambda's ARN output so that I can set the correct Principal config for the bucket.

The Lambda is also dependent on the S3 bucket existing so I can configure the bucket which stores the handler code.

I have 2 modules creating the required resources

# S3 Bucket module
resource "aws_s3_bucket" "s3-lambda" {
  bucket = var.bucket_name
  acl = "private"
  policy = data.aws_iam_policy_document.s3_lambda_permissions.json

  tags = {
    Name        = var.tag_name
    Environment = var.env_name
  }
}

# Lambda module
resource "aws_lambda_function" "redirect_lambda" {
  s3_bucket     = var.bucket_name
  s3_key        = var.key
  handler       = var.handler
  runtime       = var.runtime
  role          = aws_iam_role.redirect_lambda.arn
  function_name = "redirect_lambda-${var.env_name}"
  publish       = true
}

I am then calling these modules in my main.tf

module "qr_redirect_lambda" {
  source = "./modules/qr-redirect"

  env_name    = var.env_name
  bucket_name = var.qr_redirect_lambda_bucket_name
  key         = var.lambda_key
  runtime     = var.lambda_runtime_16
  handler     = var.lambda_handler
  tag_name = "tag name
}

How can I create these 2 resources that are codependent on each other?

Error output:

 Error: error creating Lambda Function (1): InvalidParameterValueException: Error occurred while GetObject. S3 Error Code: NoSuchBucket. S3 Error Message: The specified bucket does not exist
│ {
│   RespMetadata: {
│     StatusCode: 400,
│     RequestID: "xxx-xxx"
│   },
│   Message_: "Error occurred while GetObject. S3 Error Code: NoSuchBucket. S3 Error Message: The specified bucket does not exist",
│   Type: "User"
│ }
│ 
│   with module.qr_redirect_lambda.aws_lambda_function.qr_redirect_lambda,
│   on modules/qr-lambda/main.tf line 1, in resource "aws_lambda_function" "qr_redirect_lambda":
│    1: resource "aws_lambda_function" "qr_redirect_lambda" {

1 Answers

I think you can do this it in three stages, instead of two:

  1. Create bucket without bucket policy
  2. Create lambda. You can use depends_on to create the lambda only after the bucket.
  3. Use aws_s3_bucket_policy to create the bucket policy.
Related