How do I stop and start AWS EC2 instances with cronjob expression using lambda function

sophea Mak
4 min readJan 2, 2020

This is my first story in Medium. In this article, I would like to share my experiences about how to stop and start EC2 instances using Lambda function at the regular time interval you like.

The purpose of this Lambda is one of the effective ways to reduce the cost of AWS which is used for SIT, TEST and UAT environment in the company or organization. The Lambda function will get triggered on the scheduled time and stop the running EC2 instances intentionally.

Here are the steps:

A— Create IAM role with the required permissions and attach it to the Lambda function.

Create an IAM policy using the JSON policy editor. Paste this JSON policy document into the policy editor:

{
"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*"
],
"Resource": "*"
}
]
}

B— For instances, we have two EC2 instances with tags: project as key and backend-api as value

EC2 instances with tags project : backend-api

C — create a Lambda function with Python3 language

Lambda function
python 3.7
Environment variables
import json
import boto3
import os

#region = "ap-southeast-1"
region = os.getenv('REGION')
ec2 = boto3.client("ec2", region_name=region)

def get_ec2_instance_ids(project, state):
#print(project + ',' + state)
ec2 = boto3.client("ec2", region_name=region)
filters = [
{ 'Name' : "tag:project",
'Values' : [project]
},{ 'Name' : "instance-state-name",
'Values' : [state]
}
]
##instances with tag and running state
response = ec2.describe_instances(Filters=filters)
#print(response)
instancelist = []
for reservation in (response["Reservations"]):
for instance in reservation["Instances"]:
instancelist.append(instance["InstanceId"])
return instancelist

### stop ec2 instances
def stop_ec2_instances(project):
instance_ids = get_ec2_instance_ids(project, 'running')
#print(instance_ids)
ec2.stop_instances(InstanceIds=instance_ids)
print ("stopped your instances: " + str(instance_ids))
return "stopped:OK"

### start ec2 instances
def start_ec2_instances(project):
instance_ids = get_ec2_instance_ids(project, 'stopped')
ec2.start_instances(InstanceIds=instance_ids)
print ("started your instances: " + str(instance_ids))
return "started:OK"

def lambda_handler(event, context):

print(event)
#instances = ['i-07f7c4e73af277834']

project = event.get('project')
action = event.get('action')
if ('stop' == action):
stop_ec2_instances(project)

elif (action == 'start'):
print('start action')
start_ec2_instances(project)

return {
'statusCode': 200,
'body': json.dumps('success')
}
JSON input : start-instances (EC2 with tag : key: project value : backend-api) {
“action”: “start”,
“project”: “backend-api”
}
##Json input : stop-instances{
"action": "stop",
"project": "backend-api"
}

D- Create rules that trigger your Lambda functions in Cloudwatch

  1. Open the CloudWatch console.
  2. In the left navigation pane, under Events, choose Rules.
  3. Choose Create rule.
  4. Under Event Source, choose Schedule.
  5. Do either of the following:
    For the Fixed rate of, enter an interval of time in minutes, hours, or days.
    For Cron expression, enter an expression that tells Lambda when to stop your instances. For information on the syntax of expressions, see Schedule Expressions for Rules.
    Note: Cron expressions are evaluated in UTC. Be sure to adjust the expression for your preferred time zone
  6. Under Targets, choose Add target.
  7. Choose Lambda function.
  8. For Function, choose the function that stops your EC2 instances.
  9. Choose Configure details.
  10. Under Rule definition, do the following:
    For Name, enter a name to identify the rule, such as “StopEC2Instances”.
    (Optional) For Description, describe your rule. For example, “Stops EC2 instances every night at 10 PM.”For State, select the Enabled check box.
  11. Choose Create rule.
  12. Repeat steps 1–11 to create a rule to start your EC2 instances. Do the following differently: In step 5, for Cron expression, enter an expression that tells Lambda when to start your instances.
  13. In step 8, for Function, choose the function that starts your EC2 instances.
    In step 10, under Rule definition, enter a Name like “StartEC2Instances”, and optionally enter a Description like “Starts EC2 instances every morning at 6 AM.”

ex: Cron-job with Cloudwatch Events - start instances: 08 AM MON-FRI (Phnom Penh) — UTC to GMT + 7

Stop cron-job expression UTC +7 : 19:15pm Monday-Friday (Cron job 15 12 ? * MON-FRI *)

Conclusion

I hope that this article can help you and gain knowledge.

If you found that this article is helpful, please support to press on the clap button and help other readers to reach this story as well.

Leave your feedback and comments, I appreciate and to make it better.

📝 Save this story in Journal.

👩‍💻 Wake up every Sunday morning to the week’s most noteworthy stories in Tech waiting in your inbox. Read the Noteworthy in Tech newsletter.

--

--

sophea Mak

15+ years of professional experience engineer software development with JAVA and open-source majority and DevOps lately. https://www.linkedin.com/in/sopheamak