Save Time and Money with Python, Lambda and EventBridge: Stopping EC2 Instances

Joshua Hunter
4 min readDec 27, 2022

--

Are you tired of manually stopping your EC2 instances? Do you waste valuable time and energy constantly checking on them? Well, fear not because there is a solution for you!

Introducing stopping EC2 instances with Lambda and Amazon EventBridge. This easy-to-use system automatically shuts down your instances when they are not in use, saving you time and money on unnecessary resources. Plus, with Lambda, you can set custom triggers to shut down your instances on a schedule that works best for you.

Below we can see just how simple it is to use a python script in a Lambda function to stop our EC2 resources.

Prerequisites:

  • An AWS account
  • Basic Python Knowledge

Python Script

To start, we will need a Python script that stops all our instances. For this scenario we will stop instances in our account with the Environment: Dev tag.

You can easily modify the tags in your script and Instances for your specific needs.

You can use or modify the following scirpt I created:

# Import the boto3 library for interacting with AWS services
import boto3

# Set the region to 'us-east-1'
region = 'us-east-1'

# Create an EC2 client object for interacting with the EC2 service in the specified region
ec2_client = boto3.client('ec2', region_name=region)


def lambda_handler(event, context):
# Retrieve a list of all the Amazon EC2 instances with the 'Environment' tag set to 'Dev'
dev_instances = ec2_client.describe_tags(Filters=[{'Name': 'tag:Environment', 'Values': ['Dev']}])

# Retrieve a list of all the currently running Amazon EC2 instances
all_running_instances = ec2_client.describe_instance_status()

# Get the list of running instances from the 'InstanceStatuses' field of the all_running_instances dictionary
running_instances = all_running_instances['InstanceStatuses']
running_instance_id = []

# Iterate over the running instances and append the ID of each instance to the running_instance_id list
for i in running_instances:
running_instance_id.append(i['InstanceId'])

# Get the list of EC2 instances with the 'Environment' tag set to 'Dev' from the 'Tags' field of the dev_instances dictionary
dev_instance_tags = dev_instances['Tags']
dev_instance_Id = []

# Iterate over the EC2 instances with the 'Environment' tag set to 'Dev' and append the ID of each instance to the dev_instance_Id list
for i in dev_instance_tags:
dev_instance_Id.append(i['ResourceId'])

# Iterate over the EC2 instance IDs with the 'Environment' tag set to 'Dev'
for i in dev_instance_Id:
if i in running_instance_id:
running_dev_Id = i
id = running_dev_Id
# Use the stop_instances method of the ec2_client object to stop the instance with the ID stored in the id variable
ec2_client.stop_instances(InstanceIds=[id])

Creating a Lambda Function

To run this script on a set schedule, we can use a Lambda function with a trigger set to run daily at a specific time (in this case, 7pm). First, we will need to create a new Lambda function and set the runtime to Python 3.7 or higher. Then, we can copy and paste the code from above into the function’s code window.

First we will need to give Lambda the proper permissions to interact with EC2.

Create an IAM policy and execution role for the Lambda function.

IAM Policy:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"ec2:Start*",
"ec2:Stop*",
"ec2:Describe*"
],
"Resource": "*"
}
]
}

Next we will need to navigate to the Lambda dashboard and author a new function from scratch and create function.

Copy and paste the Python code from early into the “code” section of the Lambda designer and click “deploy” to save.

To test to see if our function works properly we can select the drop down menu on the test button > configure test event > name the event > save. Now we can use the test button to invoke our lambda.

I have created 2 Test EC2 instances. Ensure the instances you wish to stop have the proper tags as described in your Lambda function. After selecting test we should successfully see our instances have stopped.

Setting a up a schedule for our function

Finally, we will need to set up a trigger for the function. In the designer panel, click on the “Add trigger” button and select “EventBridge (CloudWatch Events)” as the trigger type. From the “Rule” dropdown, select “Create a new rule”, and give the rule a name. Under “Rule type”, select “Schedule expression” and enter a schedule expression to specify when the function should run (e.g. cron(0 19 ? * MON-FRI *) for 7pm on weekdays). Then add the expression.

You can modify the schedule expression to execute at any time so you do not need to wait to test the trigger.

With these steps, our Lambda function should be set up to stop all running EC2 instances with the Environment: Dev tag every day at 7pm. Note that this script can easily be modified.

--

--