How to Setup and Run Crons With Lambda in Aws and Eventsbridge

Step-by-step guide on How to Setup and Run Crons With Labda in Aws and Eventsbridge

Automation is at the heart of reliable cloud systems. Whether you want to fetch weather data, clean logs, update caches, or ping a health endpoint, scheduled tasks (aka cron jobs) are essential.

Traditionally, cron jobs lived on servers. But in the cloud-native world, we aim to make our tasks serverless, secure, and scalable. Enter:

  • AWS Lambda — for running lightweight, event-driven functions.
  • Amazon EventBridge (formerly CloudWatch Events) — for triggering those functions on a schedule (like crontab).

In this guide, we’ll explore how to:

  • Package a Python script for AWS Lambda
  • Run it every 6 hours using EventBridge
  • Automate deployment with a Makefile
  • Clean up all resources when you’re done

Let’s dive in.

The Code Logic

Let’s say we have a Python script that:

  • Fetches weather data from WeatherAPI
  • Sends that data to a debug API endpoint for processing or logging

Here’s our logic saved in src/script.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import json
import os

import requests

def get_weather_data(city="Nairobi"):
    api_key = os.environ.get("WEATHERAPI_KEY", "e35b01c9046641c2af095849252503")
    url = f"http://api.weatherapi.com/v1/current.json?key={api_key}&q={city}"

    try:
        response = requests.get(url)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"Error fetching weather data: {e}")
        return None

def send_to_jsonplaceholder(data):
    url = "https://stage-opsman-api.citizix.com/debug-request"
    payload = {
        "title": f"Weather Report for {data['location']['name']}",
        "body": f"Temperature: {data['current']['temp_c']}°C, Conditions: {data['current']['condition']['text']}, Humidity: {data['current']['humidity']}%",
        "userId": 1
    }

    try:
        response = requests.post(url, json=payload)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"Error sending data: {e}")
        return None

def main():
    city = os.environ.get("WEATHER_CITY", "Nairobi")
    weather_data = get_weather_data(city)

    if weather_data:
        print(f"Successfully retrieved weather data for {city}")
        result = send_to_jsonplaceholder(weather_data)

        if result:
            print(f"Successfully sent data to JSONPlaceholder API")
            print(f"Response: {json.dumps(result, indent=2)}")
        else:
            print("Failed to send data to JSONPlaceholder API")
    else:
        print(f"Failed to retrieve weather data for {city}")


if __name__ == "__main__":
    main()

Lambda Entry Point

We wrap this in a Lambda-compatible handler in src/main.py:

1
2
3
4
5
6
from script import main


def handler(event, context):
    main()
    return {'statusCode': 200}

This is the file AWS Lambda will call when the function is triggered.

Packaging the Code

To make Lambda understand your code:

  • Add dependencies in requirements.txt:
1
requests
  • Install them locally into src/:
1
pip install -r requirements.txt -t ./src
  • Package the folder:
1
cd src && zip -r ../make-health-check.zip .

This ZIP will be uploaded to AWS as your Lambda function code.

Creating IAM Role for Lambda

AWS Lambda needs permissions to run. So, we create a role and attach basic execution permissions:

  • Trust policy
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
cat > trust-policy.json << EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

Create Iam role

1
aws iam create-role --role-name MakeHealthCheckRole --assume-role-policy-document file://trust-policy.json

Attach basic execution policy

1
aws iam attach-role-policy --role-name MakeHealthCheckRole --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

Get role arn

1
aws iam get-role --role-name MakeHealthCheckRole --query 'Role.Arn' --output text

Deploying the Lambda Function

Use the zipped code to create the Lambda function:

1
2
3
4
5
6
7
8
9
zip -r make-monitor.zip .

aws lambda create-function \
  --function-name MakeHealthCheck \
  --zip-file fileb://make-monitor.zip \
  --handler main.handler \
  --runtime python3.12 \
  --role arn:aws:iam::<your-account-id>:role/MakeHealthCheckRole \
  --timeout 30

Make sure to replace <your-account-id> with your real AWS account number.

Setting Up a Cron with EventBridge

AWS EventBridge allows us to run the Lambda every 6 hours using a cron expression:

1
2
3
aws events put-rule \
  --name MakeHealthCheckSchedule \
  --schedule-expression "cron(0 0/6 * * ? *)"

This runs the function at 00:00, 06:00, 12:00, and 18:00 UTC daily.

Give EventBridge Permission to Trigger Lambda

Add permission for CloudWatch to invoke Lambda

1
2
3
4
5
6
aws lambda add-permission \
  --function-name MakeHealthCheck \
  --statement-id MakeHealthCheckSchedule \
  --action lambda:InvokeFunction \
  --principal events.amazonaws.com \
  --source-arn $(aws events describe-rule --name MakeHealthCheckSchedule --query 'Arn' --output text)

Create Target

Create target JSON file. This defines where EventBridge sends the event (to Lambda):

1
2
3
4
5
6
7
8
cat > targets.json << EOF
[
  {
    "Id": "1",
    "Arn": "$(aws lambda get-function --function-name MakeHealthCheck --query 'Configuration.FunctionArn' --output text)"
  }
]
EOF

Add target to the rule

1
2
3
aws events put-targets \
  --rule MakeHealthCheckSchedule \
  --targets file://targets.json

Updating the Lambda

As you change your Python code, redeploy by zipping and updating:

1
2
3
4
5
zip -r make-health-check.zip .

aws lambda update-function-code \
  --function-name MakeHealthCheck \
  --zip-file fileb://make-health-check.zip

Or use the Makefile…

Automate with Makefile

Automate all the manual steps with a Makefile:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# Makefile for building and deploying the weather-lambda project

.PHONY: install package deploy clean

install:
 pip install -r requirements.txt -t ./src

package:
 cd src && zip -r ../make-health-check.zip .

deploy: package
 aws lambda update-function-code \
  --function-name MakeHealthCheck \
  --zip-file fileb://make-health-check.zip

clean:
 rm -f make-health-check.zip
 rm -rf src/__pycache__

Now you can deploy with just:

1
make deploy

Cleaning Up

When you’re done, clean up resources to avoid charges.

Delete CloudWatch Event Rule and Targets

1
2
3
4
5
6
7
8
# First remove targets from the rule
aws events remove-targets \
  --rule MakeHealthCheckSchedule \
  --ids "1"

# Then delete the rule itself
aws events delete-rule \
  --name MakeHealthCheckSchedule

Delete lambda function

1
2
3
# Delete the function
aws lambda delete-function \
  --function-name MakeHealthCheck

Delete IAM Role and Policies

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# First detach any managed policies from the role
aws iam detach-role-policy \
  --role-name MakeHealthCheckRole \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

# Delete any inline policies (if you added any)
aws iam list-role-policies --role-name MakeHealthCheckRole --query 'PolicyNames' --output text | \
while read -r policy; do
  aws iam delete-role-policy --role-name MakeHealthCheckRole --policy-name "$policy"
done

# Finally, delete the role
aws iam delete-role \
  --role-name MakeHealthCheckRole

Verify Cleanup

To make sure everything is cleaned up:

1
2
3
4
5
6
7
8
# Check if function still exists
aws lambda get-function --function-name MakeHealthCheck 2>&1 || echo "Function deleted successfully"

# Check if rule still exists
aws events describe-rule --name MakeHealthCheckSchedule 2>&1 || echo "Rule deleted successfully"

# Check if role still exists
aws iam get-role --role-name MakeHealthCheckRole 2>&1 || echo "Role deleted successfully"

If you’re unsure about any resources, you can use the AWS Console to search for “MakeHealthCheck” across all services to find any remaining resources.

One-liner to find related resources (optional)

1
aws resourcegroupstaggingapi get-resources --tag-filters Key=Name,Values=MakeHealthCheck

Conclusion: Serverless Scheduling Made Simple

By combining AWS Lambda, EventBridge, and Python, you’ve created a lightweight and scalable cron job — without ever worrying about servers, uptime, or instance cost.

This pattern is perfect for:

  • Health checks and monitoring
  • Scheduled API data ingestion
  • Log cleanup
  • Notifications and alerts

With a clean deployment pipeline using a Makefile, and proper IAM practices, your serverless cron architecture is robust, automated, and cloud-native.

comments powered by Disqus
Citizix Ltd
Built with Hugo
Theme Stack designed by Jimmy