Skip to content

S3-triggered Function

S3 to Lambda

A Lambda function that is triggered by incoming data to an S3 bucket.

This guide walks you through setting up an event-driven workflow that triggers a Lambda function whenever new content is uploaded to an S3 bucket. The resources should be created inside the infrastructure repository.

components :

  • S3 bucket
  • Lambda function
  • S3 bucket notification
source directory structure
├──application-name/
  ├── byks_application_name.tf
        lambda_functions {}
  └── locals.tf
  └── s3.tf
  └── s3_notifications.tf

Step 1 : The Lambda Function

At BYM, when configuring event triggered Lambda functions, the development team is expected to deploy the function code as an ECR container image.

Before proceeding, follow the step-by-step guides to Create ECR repository and Build & push Docker image to ECR.

Taking the kattehotell example further, the following code provisions kattehotell-incoming-resrvations-test Lambda function using the container image pushed to ECR.

byks_kattehotell.tf
module "byks_kattehotell" {
  source = "git@github.com:BYM-IKT/terraform-byks-module.git?ref=v12"
  # ...

  lambda_functions = {
    kattehotell_reservations = {
      override_name          = "kattehotell-incoming-resrvations-test"
      ecr_uri                = data.terraform_remote_state.shared_kattehotell_ecr.outputs.kattehotell_reservations_ecr_repo
      image_tag              = var.environment
      environment_variables  = local.kattehotell_incoming_reservations_environment_variables
    }
  }
}
The required environment variables for the Lambda function can be provided in the locals.tf file inside kattehotell_incoming_reservations_environment_variables section.

locals.tf
1
2
3
4
5
locals {
  kattehotell_incoming_reservations_environment_variables = {
    ...
  }
}

Step 2 : The S3 Bucket

The code below creates bym-kattehotell-test S3 bucket.

s3.tf
1
2
3
4
5
6
module "s3_kattehotell" {
    source = "git@github.com:BYM-IKT/terraform-aws-s3-bucket.git?ref=v4"
    name        = lower("bym-kattehotell-${var.environment}")
    environment = test
    ...
}

Step 3 : The S3 Bucket Notification

The following configuration sets up the S3 bucket notification and grants the required invoke permission, allowing the S3 bucket to trigger the Lambda function.

s3_notifications.tf
resource "aws_iam_role_policy_attachment" "lambda_kattehotell_s3_access_policy" {
  role       = module.byks_kattehotell.lambda_functions["kattehotell_reservations"].iam_role_name
  policy_arn = module.s3_kattehotell.write_policy_arn 
}

resource "aws_lambda_permission" "allow_kattehotell_s3bucket_invoke_incoming_reservations" {
  statement_id  = "AllowExecutionFromS3Bucket"
  action        = "lambda:InvokeFunction"
  function_name = module.byks_kattehotell.lambda_functions["kattehotell_reservations"].lambda_name
  principal     = "s3.amazonaws.com"
  source_arn    = "arn:aws:s3:::${module.s3_kattehotell.bucket_name}"
}

resource "aws_s3_bucket_notification" "kattehotell_reservasion_s3_notification" {
  bucket = module.s3_kattehotell.bucket_name
  ...
  lambda_function {
    lambda_function_arn = module.byks_kattehotell.lambda_functions["kattehotell_reservations"].lambda_arn
    events              = ["s3:ObjectCreated:Put"]
    filter_prefix       = "new-reservations/"  # use if you want to limit the trigger based on a specific prefix
  }
   depends_on = [aws_lambda_permission.s3_bucket_invoke_permission]
}

Result :

A file being uploaded to the bym-kattehotell-test/new-reservations/ S3 bucket triggeres a new deployment of the lambda function kattehotell-incoming-reservations-test.