DEV Community

Cover image for Cut Costs by Automating EC2 Start/Stop with AWS Lambda
Esther Nnolum
Esther Nnolum

Posted on

Cut Costs by Automating EC2 Start/Stop with AWS Lambda

Every hour an unused EC2 instance runs is money slipping through the cracks, but with a little smart automation, you can turn that waste into predictable savings. Managing cloud costs is important, especially when dev or test servers run outside of business hours. A great way to save is to automatically stop EC2 instances after work hours, and start them again in the morning.

In this article, you’ll learn how to do this using:

  • AWS Lambda
  • EC2 tags to control which instances are affected
  • EventBridge Scheduler
  • IAM roles

Prerequisites

Before you begin, make sure you have:

  • An AWS account
  • Basic understanding of EC2 and AWS Console
  • EC2 instances you want to automate

Step 1: Tag Your EC2 Instances

This step is important if you don’t want to stop every instance, but just the ones you choose.
Go to your EC2 instances (Select the instance, open the Tags tab, and click Manage Tags) and add a tag:

  • Key: AutoShutdown
  • Value: Yes

This is to tell our automation to only act on these tagged instances.

Step 2: Create Lambda Function to Stop EC2 Instances

Go to AWS Console → Lambda → Create Function

  • Name: StopEC2Instances
  • Runtime: Python 3.x
  • Permissions: Create a new role with basic Lambda permissions

Click on Create function and Replace the default code with:

import boto3

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')

    # Get all running EC2 instances with AutoShutdown = Yes
    response = ec2.describe_instances(
        Filters=[
            {'Name': 'tag:AutoShutdown', 'Values': ['Yes']},
            {'Name': 'instance-state-name', 'Values': ['running']}
        ]
    )

    instances_to_stop = []
    for reservation in response['Reservations']:
        for instance in reservation['Instances']:
            instances_to_stop.append(instance['InstanceId'])

    if instances_to_stop:
        print(f"Stopping instances: {instances_to_stop}")
        ec2.stop_instances(InstanceIds=instances_to_stop)
    else:
        print("No instances to stop.")
Enter fullscreen mode Exit fullscreen mode

Step 3: Update IAM Permissions

Go to IAM → Roles → find your Lambda role (StopEC2Instances-role-xxxx) → attach this policy:

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

Step 4: Schedule the Stop Function with EventBridge Scheduler

Go to Amazon EventBridge → Create Schedule

  • Schedule name: StopEC2AtNight
  • Occurrence: Recurring schedule
  • Time zone: "select-your-timezone"
  • Schedule type: Cron-based schedule
  • Cron expression: cron(0 19 ? * MON-FRI *)

This means 7:00 PM of the specified timezone, Monday to Friday
N.B: Replace "select-your-timezone" with your preferred timezone

Step 5: Create Lambda Function to Start EC2 Instances

Now let’s create a second function to start the instances in the morning.
Create another Lambda function

  • Name: StartEC2Instances
  • Runtime: Python 3.x
  • Use the same IAM role

Click on Create function and Replace the default code with:

import boto3

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')

    response = ec2.describe_instances(
        Filters=[
            {'Name': 'tag:AutoShutdown', 'Values': ['Yes']},
            {'Name': 'instance-state-name', 'Values': ['stopped']}
        ]
    )

    instances_to_start = []
    for reservation in response['Reservations']:
        for instance in reservation['Instances']:
            instances_to_start.append(instance['InstanceId'])

    if instances_to_start:
        print(f"Starting instances: {instances_to_start}")
        ec2.start_instances(InstanceIds=instances_to_start)
    else:
        print("No instances to start.")
Enter fullscreen mode Exit fullscreen mode

Step 6: Schedule the Start Function

Go to Amazon EventBridge → Create Schedule

  • Schedule name: StartEC2InTheMorning
  • Occurrence: Recurring schedule
  • Time zone: "select-your-timezone"
  • Schedule type: Cron-based schedule
  • Cron expression: cron(0 7 ? * MON-FRI *) This means 7:00 AM of the specified timezone, Monday to Friday

Conclusion

This simple automation is proof that small changes can deliver big results. By letting AWS Lambda and EventBridge Scheduler handle your EC2 stop/start, you’re not just cutting costs, you’re building a culture of efficiency and smart resource usage.
The result: predictable savings, reduced human error, and an AWS environment that runs only when it needs to.

Top comments (0)