Not all EC2 instances need to be up all the time. As a cost-saving measure, it may be worth shutting down these instances on a set schedule.
Below are the steps to achieve this by leveraging Lambda Functions and CloudWatch Rules.
Begin by creating an IAM user Role. Name it something like StartStopEC2 and attach an inline policy allowing the role to describe, start, and stop EC2 instances with the following JSON policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:StartInstances",
"ec2:StopInstances"
],
"Resource": "*"
}
]
}
Note: Below the role and inline policy were named StartStopEC2. This is relevant in the next section
Create a Lambda Function to shutdown the target EC2 instance using a simple Python 2.7 script and the IAM role create above.
Begin by selecting Author from scratch and name is something similar to Stop[ServerName]. Select Choose an existing role and choose the role StartStopEc2 created in the previous section.
Select Python 2.7 for the Runtime and copy the following script, substituting the server InstanceId in line 5.
import boto3
client=boto3.client('ec2')
def lambda_handler(event, context):
response=client.describe_instances()
id=["<instance id starting with ‘i-’>"]
client.stop_instances(InstanceIds=id)
return("Complete.")
First, verify the EC2 instance is in a running state. Then, on the Lambda function page seen above, click Test in the top right corner, name it something like test, leave default values, and click Create. Then, click Save and test.
From CloudWatch, create a new rule by clicking on Create Rule under Rules.
Select Schedule and Cron Expression.
(See AWS Doc on Schedule Expressions Using Rate or Cron for details on the Cron Expression field.)
In this example, the server will shutdown at 02:05 GMT (8pm Central).
(See GMT Time Converter for easy conversion with local time.)
In the Targets section, click Add target. Then, click the drop down option next to Function and select the Lambda Function created in the previous section.
Click Configure details, name the rule and provide a description.
If you'd like to specify only weekdays, use the following cron expression -
05 2 ? * MON-FRI *
As explained on this post, the third value and the fifth are exclusive. Since it is not possible to calculate the days of the month and the day of the week at the same time, a ? should be added as a variable for one when the other is used.