DEV Community

VENKATA SRI HARI
VENKATA SRI HARI

Posted on

Cut AWS EC2 Costs with Python: Automate Cost Optimization Using AWS Lambda

Introduction
Managing AWS EC2 costs efficiently is crucial for DevOps and cloud engineers. In this guide, we’ll explore how to automate EC2 instance optimization using AWS Lambda and Python (Boto3). You’ll learn how to:
✅ Automatically stop and start instances based on business hours
✅ Monitor CPU utilization and shut down underutilized instances
✅ Use tags and CloudWatch metrics to identify non-essential resources
✅ Schedule the Lambda function using EventBridge (CloudWatch Events)
✅ Improve cost efficiency while ensuring service availability.

Image description

With hands-on examples and best practices, this article will help you reduce EC2 costs without manual intervention.

Lambda Use Case
Create an IAM Role for Lambda
Write the Python Code for Lambda
Schedule the Lambda Function
Modify to Stop EC2 Instances Based on CPU Usage
Final Steps
Conclusion.

**

  1. Lambda Use Case: -** Stop idle EC2 instances outside of business hours (e.g., stop from 8 PM to 8 AM). Start instances automatically during working hours. Monitor CPU usage and shut down underutilized instances. Tag-based filtering to exclude critical instances.

*2.Create an IAM Role for Lambda: -
*

Your Lambda function needs EC2 permissions to start/stop instances.
Create an IAM Role with the following permissions:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": "*"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Version: The policy language version.
Statement: The array of permissions statements.
Effect: This policy allows the listed actions.
Action: The specific EC2 actions allowed by this policy (DescribeInstances, StartInstances, StopInstances).
Resource: The resource scope for the actions (in this case, all resources).

3. Write the Python Code for Lambda
Auto-Stop EC2 Instances Based on Time:-

import boto3
import datetime

# Initialize EC2 client
ec2 = boto3.client('ec2')

# Define business hours (e.g., 8 AM - 8 PM)
START_HOUR = 8
STOP_HOUR = 20

def lambda_handler(event, context):
    now = datetime.datetime.now()
    current_hour = now.hour

    # Fetch all running instances with the tag `AutoStop=Yes`
    instances = ec2.describe_instances(Filters=[
        {'Name': 'instance-state-name', 'Values': ['running']},
        {'Name': 'tag:AutoStop', 'Values': ['Yes']}
    ])

    instance_ids = [i['InstanceId'] for r in instances['Reservations'] for i in r['Instances']]

    if current_hour >= STOP_HOUR or current_hour < START_HOUR:
        if instance_ids:
            ec2.stop_instances(InstanceIds=instance_ids)
            print(f"Stopped instances: {instance_ids}")
    else:
        print("Business hours - no action needed")

    return {
        'statusCode': 200,
        'body': 'Lambda execution completed'
    }
Enter fullscreen mode Exit fullscreen mode

How It Works?
The function runs on a schedule (CloudWatch Event Trigger).
It checks if the current time is outside business hours (8 AM — 8 PM).
If instances have the tag AutoStop=Yes, they are stopped.

4. Schedule the Lambda Function
Use Amazon EventBridge (CloudWatch Rule) to trigger this Lambda:

Cron Expression: 0 20 * * ? * → Runs at 8 PM UTC every day.
Separate Function: Create a separate Lambda function to start instances at 8 AM, ensuring they are available during working hours.

5. Modify to Stop EC2 Instances Based on CPU Usage
If you want to stop EC2 instances with low CPU utilization, modify the function to check CloudWatch CPU metrics:

import boto3

ec2 = boto3.client('ec2')
cloudwatch = boto3.client('cloudwatch')

def get_cpu_utilization(instance_id):
    response = cloudwatch.get_metric_statistics(
        Namespace='AWS/EC2',
        MetricName='CPUUtilization',
        Dimensions=[{'Name': 'InstanceId', 'Value': instance_id}],
        StartTime=datetime.datetime.utcnow() - datetime.timedelta(minutes=30),
        EndTime=datetime.datetime.utcnow(),
        Period=300,
        Statistics=['Average']
    )
    return response['Datapoints'][0]['Average'] if response['Datapoints'] else 0

def lambda_handler(event, context):
    instances = ec2.describe_instances(Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])
    for res in instances['Reservations']:
        for inst in res['Instances']:
            instance_id = inst['InstanceId']
            cpu_usage = get_cpu_utilization(instance_id)

            if cpu_usage < 10:  # Stop instances with <10% CPU utilization
                ec2.stop_instances(InstanceIds=[instance_id])
                print(f"Stopped instance {instance_id} due to low CPU usage")

    return {'statusCode': 200, 'body': 'Lambda executed successfully'}
Enter fullscreen mode Exit fullscreen mode

6. Final Steps
Deploy the Lambda function in AWS Lambda.
Assign the IAM Role created earlier.
Set an EventBridge schedule (e.g., every hour) to trigger it.
Tag instances with AutoStop=Yes to include them in automation.
This Lambda function helps reduce EC2 costs by shutting down idle or low-utilization instances while keeping critical workloads running.

Conclusion:
Automating AWS EC2 cost optimization with Python and AWS Lambda is a smart way to reduce cloud expenses while maintaining operational efficiency. By implementing automated start/stop schedules, monitoring CPU utilization, and leveraging tags, you can ensure that only necessary instances are running — saving costs without compromising performance.

By integrating CloudWatch, EventBridge, and Boto3, you create a scalable and hands-free solution that continuously optimizes your cloud infrastructure. This approach not only enhances cost efficiency but also aligns with DevOps best practices for cloud automation.

Start implementing cost-saving Lambda functions today, and take control of your AWS billing! 🚀💡

………………………………………………………………………………………………………………………………………………………………………………………………

You’re welcome! Have a great time ahead! Enjoy your day!

Please Connect with me any doubts.

Mail: sriharimalapati6@gmail.com

LinkedIn: www.linkedin.com/in/

GitHub: https://github.com/Consultantsrihari

Medium: Sriharimalapati — Medium

Thanks for watching ##### %%%% Sri Hari %%%%
Python
AWS Lambda
AWS
DevOps
Automation

Top comments (0)