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.")
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": "*"
}
]
}
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.")
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)