Valentin Jacquemin

Terraform recipe: Cron to execute a Lambda Function

This one too will come handy: trigger a lambda function on the basis of a schedule expression.

The only requirement is to have a completed AWS CLI setup.

With this minimal folder:

.
├── lambda
│   ├── index.js
│   ├── lambda.zip
│   └── package.json
├── schedule.tf

With ~50 lines of infrastructure description in schedule.tf:

module "eventbridge" {
  source  = "terraform-aws-modules/eventbridge/aws"
  create_bus = false # bus not needed in this case, will otherwise trigger an error: 
                     # invalid value for name (cannot be 'default')
                     
  # ensures the cron is authorized to call the lambda                     
  attach_lambda_policy = true
  lambda_target_arns   = [aws_lambda_function.lambda-func.arn]

  schedules = {
    lambda-cron = {
      description         = "Trigger for a Lambda"
      # at, cron and rate functions available to define the schedule
      schedule_expression = "rate(5 minutes)"
      arn                 = aws_lambda_function.lambda-func.arn
      input               = jsonencode({ "job" : "cron-by-rate" })
    }
  }
}

data "archive_file" "lambda" {
  type        = "zip"
  source_file = "${path.module}/lambda/index.js"
  output_path = "${path.module}/lambda/lambda.zip"
}

resource "aws_lambda_function" "lambda-func" {
  filename      = data.archive_file.consolidate_lambda.output_path
  function_name = "func"
  role          = aws_iam_role.iam_for_lambda.arn
  handler       = "index.handler"
  runtime       = "nodejs24.x"
  code_sha256   = data.archive_file.lambda.output_base64sha256
}

resource "aws_iam_role" "iam_for_lambda" {
  name               = "iam_for_lambda"
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
}

data "aws_iam_policy_document" "assume_role" {
  statement {
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["lambda.amazonaws.com"]
    }

    actions = [
      "sts:AssumeRole"
    ]
  }
}

For the lambda itself, the one-liner listed on Terraform recipe: S3 Bucket with notification to Lambda Function will do it.

Once applied, the lambda is called as per the definition set for schedule_expression which can either be a rate, at, or cron. More details and examples are available under Schedule types on EventBridge Scheduler in the EventBridge Scheduler User Guide.

The rate construct used in this example will make the lambda function to be called every 5 minutes.