Here is some information about this architecture.
This solution demonstrates how to use Terraform modules on the public registry to build a system that uses EventBridge to schedule Lambda function invocations. In this solution, Lambda is invoked once per minute, though you can easily configure a different time period.
Here are the steps you can follow to build this solution on your own.
If you're using the Skillmix Labs feature, open the lab settings (the beaker icon) on the right side of the code editor. Then, click the Start Lab button to start hte lab environment.
Wait for the credentials to load. Then run this in the terminal:
$ aws configure --profile smx-lab
AWS Access Key ID [None]: AKIA3E3W34P42CSHXDH5
AWS Secret Access Key [None]: vTmqpOqefgJfse8i6QwzgpjgswPjHZ6h/oiQq4zf
Default region name [None]: us-west-2
Default output format [None]: json
Be sure to name your credentials profile 'smx-lab'.
Note: If you're using your own AWS account you'll need to ensure that you've created and configured a named AWS CLI profile named smx-lab.
We'll be doing all of our work in one Terraform file. Create a new directory on your computer somewhere, and then create a file named main.tf
in it.
Next, we will create a Terraform configuration that will allow us to use the AWS provider. This configuration will require us to specify the version of the AWS provider that we want to use, as well as the version of Terraform that we are using. We will also specify the AWS profile and region that we want to use. This code will ensure that the correct versions of Terraform and the AWS provider are used, and that the AWS provider is configured correctly.
Append this code to the main.tf
file:
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.9"
}
random = {
source = "hashicorp/random"
version = ">= 2.0"
}
}
}
provider "aws" {
profile = "smx-temp"
region = "us-west-2"
}
Next, we will create a data source that will allow us to access the AWS caller identity of the current user. This data source will be called "aws_caller_identity" and will be set to the "current" provider, which is the AWS Cross Account provider. This data source will allow us to access the identity of the current user, which can be used for authentication and authorization purposes.
Append this code to the main.tf
file:
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
We will need a file Python file to use in this project. We will create a simple one that simply logs some information to the console. In your project directory, create a folder named src
. In that folder create a file named app.py
. Put this code into that file:
def lambda_handler(event, context):
print("Hello World")
return True
Next, we will create a module for EventBridge that will allow us to trigger a Lambda Function periodically. This module will create a rule with a schedule expression of "rate(1 minute)" and a target of the Lambda Function with an input of a JSON-encoded string. Additionally, this module will also create tags for the EventBridge module with a pattern and module name.
Append this code to the main.tf
file:
module "eventbridge" {
source = "terraform-aws-modules/eventbridge/aws"
version = "~> 1.0"
# ScheduleExpression is supported only on the default event bus.
create_bus = false
rules = {
crons = {
description = "Trigger a Lambda Function periodically"
schedule_expression = "rate(1 minute)"
}
}
targets = {
crons = [
{
name = "lambda-loves-cron"
arn = module.lambda_function.lambda_function_arn
input = jsonencode({ "job" : "cron-by-rate" })
}
]
}
tags = {
Pattern = "terraform-eventbridge-scheduled-lambda"
Module = "eventbridge"
}
}
Next, we will create a Lambda function using the Terraform module "terraform-aws-modules/lambda/aws". This module will create a Lambda function with the name "${random_pet.this.id}-lambda", a description of "My awesome lambda function", a handler of "index.lambda_handler", a runtime of "python3.8", and a source path of "${path.module}/../terraform-fixtures/python". Additionally, the module will allow the Lambda function to be triggered by an EventBridge rule with a principal of "events.amazonaws.com" and a source ARN of the EventBridge rule created by the module. Finally, the module will add two tags to the Lambda function, "Pattern" and "Module".
Append this code to the main.tf
file:
module "lambda_function" {
source = "terraform-aws-modules/lambda/aws"
version = "~> 4.0"
function_name = "${random_pet.this.id}-lambda"
description = "My awesome lambda function"
handler = "index.lambda_handler"
runtime = "python3.8"
publish = true
source_path = "${path.module}/src"
allowed_triggers = {
ScheduledEventBridgeRule = {
principal = "events.amazonaws.com"
source_arn = module.eventbridge.eventbridge_rule_arns["crons"]
}
}
tags = {
Pattern = "terraform-eventbridge-scheduled-lambda"
Module = "lambda_function"
}
}
Next, we will create a random pet resource using Terraform. This code will generate a random pet name with two words. The random_pet resource will create a random pet name that is composed of two words, each of which is randomly selected from a list of words. This resource can be used to generate unique names for resources in your Terraform configuration.
Append this code to the main.tf
file:
resource "random_pet" "this" {
length = 2
}
Lastly, we want to return a handful of resources to our console. Add these output resources to the end of the main.tf
file.
# Lambda Function
output "lambda_function_arn" {
description = "The ARN of the Lambda Function"
value = module.lambda_function.lambda_function_arn
}
output "lambda_function_invoke_arn" {
description = "The Invoke ARN of the Lambda Function"
value = module.lambda_function.lambda_function_invoke_arn
}
output "lambda_function_name" {
description = "The name of the Lambda Function"
value = module.lambda_function.lambda_function_name
}
output "lambda_function_qualified_arn" {
description = "The ARN identifying your Lambda Function Version"
value = module.lambda_function.lambda_function_qualified_arn
}
output "lambda_function_version" {
description = "Latest published version of Lambda Function"
value = module.lambda_function.lambda_function_version
}
# IAM Role of Lambda Function
output "lambda_role_arn" {
description = "The ARN of the IAM role created for the Lambda Function"
value = module.lambda_function.lambda_role_arn
}
# EventBridge
output "eventbridge_rule_arns" {
description = "The EventBridge Rule ARNs"
value = module.eventbridge.eventbridge_rule_arns
}
Now that we have all of our code written, we can deploy the project. Open a terminal, navigate to the project, and run these commands.
# initialize the project
$ terraform init
# plan the project
$ terraform plan
# apply the project
$ terraform apply
After deployment, open the CloudWatch Logs console for your account. Look for the lambda function log group. There, you should see a Lambda related log event happening on a per minute schedule.
Run the destroy command to end it all
$ terraform destroy