How to invoke an AWS Lambda Function at scheduled intervals with AWS EventBridge Rule using Terraform

How to invoke an AWS Lambda Function at scheduled intervals with AWS EventBridge Rule using Terraform

Amazon EventBridge is a serverless event bus service that you can use to connect your applications with data from a variety of sources. Events are central to EventBridge and the events are observable. Event bridge also supports integration with many SAAS-based applications and third-party applications. It also supports sending events to other AWS services like Lambda functions, step functions.

In this blog, we will set up a rule to run the lambda function on schedule every 2 minutes using Terraform.

Project Structure

  • Create a new directory and move to the directory

    mkdir lambda-schedule-event-bridge && cd lambda-schedule-event-bridge
    
  • Create a resource folder to store the code for lambda

    mkdir resources
    

Create a Lambda

Create a folder profile-generator-lambda in the resources folder and add the index.js file with the below content. Also, initialize the node project and install the dependencies.

mkdir profile-generator-lambda && cd profile-generator-lambda
touch index.js
npm init -y
npm install faker
const faker = require("faker/locale/en_IND");

exports.handler = async (event, context) => {
  let firstName = faker.name.firstName();
  let lastName = faker.name.lastName();
  let phoneNumber = faker.phone.phoneNumber();
  let vehicleType = faker.vehicle.vehicle();

  let response = {
    firstName: firstName,
    lastName: lastName,
    phoneNumber: phoneNumber,
    vehicleType: vehicleType,
  };

  return {
    statusCode: 200,
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      profile: response,
    }),
  };
};

Terraform Providers

Now, we will write the terraform scripts in HCL language where we will utilize the AWS provider. Create a main.tf file in the root directory of the project and add the below content.

touch main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "3.50.0"
    }
  }
}

provider "aws" {
  # Configuration options
  region                  = var.region
  profile                 = var.aws_profile
  shared_credentials_file = var.shared_credentials_file
  default_tags {
    tags = var.tags
  }
}
  • Each Terraform module must declare which providers it requires so that Terraform can install and use them. Provider requirements are declared in a _requiredproviders block.

  • AWS providers require configurations like cloud regions, profiles, credential_files to be available before they can be used.

  • All the values will be provided from the variables parameters.

Let's create variables.tf in the root directory of the project and add the below content.

touch variables.tf
variable "region" {
  description = "Deployment Region"
  default     = "ap-south-1"
}

variable "aws_profile" {
  description = "Given name in the credential file"
  type        = string
  default     = "rahul-admin"
}

variable "shared_credentials_file" {
  description = "Profile file with credentials to the AWS account"
  type        = string
  default     = "~/.aws/credentials"
}

variable "tags" {
  description = "A map of tags to add to all resources."
  type        = map(string)
  default = {
    application = "Learning-Tutor"
    env         = "Test"
  }
}

Each input variable accepted by a module must be declared using a variable block. The label after the variable keyword is a name for the variable, which must be unique among all variables in the same module.

  • A default value makes the variable optional.
  • A Type indicates what value types are accepted for the variable.
  • A description specifies the input variable's documentation.

Terraform Modules

Now, we will use the module terraform-aws-modules/lambda/aws to create lambda and lambda layer infrastructure.

Create the files lambda.tf in the root directory of the project and add the below content.

touch lambda.tf
module "profile_generator_lambda" {
  source  = "terraform-aws-modules/lambda/aws"
  version = "2.7.0"
  # insert the 28 required variables here
  function_name = "profile-generator-lambda"
  description   = "Generates a new profiles"
  handler       = "index.handler"
  runtime       = "nodejs14.x"
  source_path   = "${path.module}/resources/profile-generator-lambda"

  tags = {
    Name = "profile-generator-lambda"
  }
}

EventBridge Rule

Create the files event_bridge.tf in the root directory of the project and add the below content.

touch event_bridge.tf
resource "aws_cloudwatch_event_rule" "profile_generator_lambda_event_rule" {
  name = "profile-generator-lambda-event-rule"
  description = "retry scheduled every 2 min"
  schedule_expression = "rate(2 minutes)"
}

resource "aws_cloudwatch_event_target" "profile_generator_lambda_target" {
  arn = module.profile_generator_lambda.lambda_function_arn
  rule = aws_cloudwatch_event_rule.profile_generator_lambda_event_rule.name
}

resource "aws_lambda_permission" "allow_cloudwatch_to_call_rw_fallout_retry_step_deletion_lambda" {
  statement_id = "AllowExecutionFromCloudWatch"
  action = "lambda:InvokeFunction"
  function_name = module.profile_generator_lambda.lambda_function_name
  principal = "events.amazonaws.com"
  source_arn = aws_cloudwatch_event_rule.profile_generator_lambda_event_rule.arn
}

As can be seen above, the schedule_expression attribute has a rate of 2 minutes. It means, it triggers the lambda function which is in the target using the resource aws_cloudwatch_event_target.profile_generator_lambda_target. We also give lambda permission, so that, the event will be able to invoke the function.

Run Terraform scripts

Let us run the 3 basic commands of terraform to create the resources in AWS.

  • Initialize the Terraform which will download all the providers and modules used in the configuration.
terraform init
  • Check if a plan matches the expectation and also store the plan in output file plan-out
terraform plan -out  "plan-out"
  • Once the plan is verified, apply the changes to get the desired infrastructure components.
terraform apply "plan-out"

Verify the infrastructure on AWS

  • Lambda with Event Bridge

event-bridge-1.png

If you check the cloud watch logs, you can see that the lambda function is getting invoked every 2 minutes.

event-bridge-2.png

Delete the resources

We can delete the resources created by terraform by issuing the below command so that we do not get billed for the resources.

terraform destroy

Conclusion

In this blog post, we saw how to create a lambda function and event bridge rule using terraform. We also saw, how to schedule the lambda function every 2 minutes by creating an event bus rule.

Github Repository : https://github.com/rahulmlokurte/aws-usage/tree/main/terraform/lambda-schedule-event-bridge

Did you find this article valuable?

Support Rahul Lokurte by becoming a sponsor. Any amount is appreciated!