Table of Contents
Introduction
You can save cost by turning off non-production ec2 instances when they are not needed. Automating start and stop actions using AWS Lambda and CloudWatch can save costs significantly.
Instead of scripting this from scratch, Terraform modules can help implement the solution quickly and cleanly.
In this guide, we’ll walk through using the open-source terraform-aws-lambda-auto-start-stop-ec2-instances module to automatically start and stop EC2 instances based on tags and schedule expressions. We'll use a real-world example where EC2 instances are:
- Started at 10:00 AM IST
- Stopped at 10:00 PM IST
This setup is useful for non-prod or testing environments that only need to be active during typical working hours.
We'll use a wrapper module available at kubenine/ec2-auto-start-stop-terraform to configure this easily using Terraform.
Problem Statement
Leaving EC2 instances running 24/7 in lower environments (like dev or QA) leads to unnecessary AWS costs. DevOps teams often need predictable and automated control over instance uptime. While AWS provides start/stop APIs, wiring it all together manually with Lambda, CloudWatch, IAM roles, and tagging logic is error-prone and repetitive.
Solution Overview
We use a Terraform module that provisions:
- A Lambda function for EC2 start/stop
- A CloudWatch Event Rule for scheduling
- IAM roles and permissions
The module works by filtering EC2 instances with specific tags (e.g., ops:env = non-prod
) and performing the action (start
or stop
) at the given time.
Diagram

Setup Instructions
1. Tag Your EC2 Instances
Ensure your instances have the required tag:
ops:env = non-prod
2. Define Terraform Modules
Use this in your main.tf
:
# Start EC2 at 10:00 AM IST (4:30 AM UTC)
module "start_ec2_instances" {
source = "github.com/julb/terraform-aws-lambda-auto-start-stop-ec2-instances"
name = "StartEc2Instances"
schedule_expression = "cron(30 4 * * ? *)" # 10:00 AM IST
action = "start"
lookup_resource_tag = {
key = "ops:env"
value = "non-prod"
}
}
# Stop EC2 at 10:00 PM IST (4:30 PM UTC)
module "stop_ec2_instances" {
source = "github.com/julb/terraform-aws-lambda-auto-start-stop-ec2-instances"
name = "StopEc2Instances"
schedule_expression = "cron(30 16 * * ? *)" # 10:00 PM IST
action = "stop"
lookup_resource_tag = {
key = "ops:env"
value = "non-prod"
}
}
3. Apply Terraform
tf init
tf apply
Terraform will provision the Lambda functions, IAM roles, and schedules.
Notes on Timezones
AWS cron expressions always use UTC. Convert your local time to UTC before setting schedule_expression
.
Local Time (IST) | UTC Equivalent | Cron Expression |
---|---|---|
10:00 AM IST | 4:30 AM UTC |
|
10:00 PM IST | 4:30 PM UTC |
|
Final Thoughts
This approach eliminates the need for custom scripts or manual scheduling. With minimal configuration, EC2 lifecycle actions are now automated and tag-driven. It's a clean way to enforce environment schedules, save on AWS costs, and reduce operational overhead.
Use this as a base and customize the schedule or tags to suit your team’s needs.