My blog site is a personal project, so I don’t need the EC2 instances running all of the time. To simplify things, I set up automation with AWS Lambda and EventBridge. Now, my instances turn off at night and start up in the morning.
Here’s how I set it up.
Step 1: Tagging EC2 Instances
I needed a way to specify which instances should be part of this automation. Instead of hardcoding instance IDs in the Lambda function, I used tags. This makes the solution dynamic — I can add this tag to more instances in the future, instead of modifying and redeploying the Lambda function each time.
How I Added Tags:
- Open the AWS EC2 Console.
- Select the instances I wanted to manage.
- Click on the Tags tab and select Manage Tags.
- Add a tag:
- Key:
auto-start-stop
- Value:
Yes
- Key:
With this in place, only the instances with auto-start-stop=Yes
will be stopped and started by the Lambda functions.
Step 2: Creating Lambda Functions
I created two Lambda functions—one to start EC2 instances in the morning and another to stop them at night.
Start EC2 Instances Lambda Function
This function starts all EC2 instances that are stopped and have the tag auto-start-stop=Yes
.
import boto3
ec2 = boto3.resource('ec2', region_name='eu-west-1')
def lambda_handler(event, context):
instances = ec2.instances.filter(
Filters=[
{'Name': 'instance-state-name', 'Values': ['stopped']},
{'Name': 'tag:auto-start-stop', 'Values': ['Yes']}
]
)
for instance in instances:
instance.start()
print('Started instance:', instance.id)
return 'Started instances'
Stop EC2 Instances Lambda Function
This function stops all EC2 instances that are running and have the tag auto-start-stop=Yes
.
import boto3
ec2 = boto3.resource('ec2', region_name='eu-west-1')
def lambda_handler(event, context):
instances = ec2.instances.filter(
Filters=[
{'Name': 'instance-state-name', 'Values': ['running']},
{'Name': 'tag:auto-start-stop', 'Values': ['Yes']}
]
)
for instance in instances:
instance.stop()
print('Stopped instance:', instance.id)
return 'Stopped instances'
These functions use boto3, the AWS SDK for Python, to manage the EC2 instances. They filter instances by state (running or stopped) and the auto-start-stop tag, ensuring only the tagged instances are started or stopped as needed.
Step 3: Setting Up EventBridge to Trigger Lambda
I needed a way to run these Lambda functions at specific times. EventBridge lets me schedule events like a cron job.
Creating a Rule to Start EC2 Instances
- Open the AWS EventBridge Console.
- Click Create Rule.
- Set the name as StartEC2Instances.
- Choose Schedule as the rule type.
- Enter this cron expression to run it at 8 AM UTC every day:
0 8 * * ? *
- Under Target, choose Lambda Function and select the function StartEC2Instances
- Click Create Rule.
Creating a Rule to Stop EC2 Instances
I followed the same steps but changed the schedule to 11 PM UTC using this cron expression:
0 23 * * ? *
and selected the function StopEC2Instances
Step 4: Setting Up IAM Permissions
For EventBridge to invoke the Lambda functions and for Lambda to control EC2 instances, I needed to setup two IAM roles.
IAM Role for Lambda Functions
I created an IAM role called LambdaStartStopEC2Role to allow my Lambda functions to control EC2 instances. Since the functions need permissions to start and stop instances, I attached the AmazonEC2FullAccess managed policy to the role. This policy grants full control over EC2, ensuring the Lambda functions can list, start, and stop instances as needed.
Once the role was set up, I assigned it to both the StartEC2Instances and StopEC2Instances Lambda functions. This way, both functions run with the necessary permissions without needing additional configuration.
IAM Role for Event Bridge Rules
I created a custom IAM role that allows EventBridge to invoke my Lambda functions. I attached the following policy to the role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"arn:aws:lambda:eu-west-1:<account-id>:function:StartEC2Instances:*",
"arn:aws:lambda:eu-west-1:<account-id>:function:StartEC2Instances",
"arn:aws:lambda:eu-west-1:<account-id>:function:StopEC2Instances:*",
"arn:aws:lambda:eu-west-1:<account-id>:function:StopEC2Instances"
]
}
]
}
I then attached this role to both EventBridge rules — one for starting instances and one for stopping them. This ensures that EventBridge has the necessary permissions to trigger both Lambda functions.
Why Automate EC2 Start/Stop?
Setting this up has been really useful. The benefits include:
- Cost Savings: By stopping instances when not in use, I avoid paying for unused compute time.
- No Manual Work: I don’t have to remember to turn instances on and off.
- Scalability: I can easily add more instances to the automation just by tagging them.
If you’re running EC2 instances only during certain hours, automating their start/stop with Lambda and EventBridge is an easy way to cut costs. Let me know if you found this helpful or if you have any questions!