How to shutdown & restart the AWS infrastructure for an application at the scheduled time

Vipin Katiyar
4 min readJun 6, 2021

Generally, as a good practice, we need to shut down all the services which are deployed in the AWS for an application on the development or acceptance environment on weekends (Sat, Sun) and also outside the office hours (After 6:30 PM) to reduce the cost. These services should automatically start on weekdays (Mon-Fri) at 9:30 AM and should shut down at (6:30 PM).

Shutdown: After 6:30 PM every day

Restart: every day (Mon-Friday at 9:30 AM) except Sat & Sun

Requirement:

1: Amazon EventBridge

2. All the IDs of the resources, which you need to shut down and restart.

3. Lambda

4. IAM for lambda’s execution role.

Step 1: Create two lambda functions one for Start the services and another one for Stop the services. I am taking three services (ec2 instance, rds instance, and ECS cluster) in this example. you can add more services as per your need.

Add the below code into the event handler of start-lambda function :

import boto3
import os
# Enter the region your instances are in. Include only the region without specifying Availability Zone; e.g., 'us-east-1'
region = os.environ['AWS_REGION']
def lambda_handler(event, context):
print 'EVENT: ' + str(event)
if 'ec2Instances' in event:
ec2 = boto3.client('ec2', region_name=region)
ec2.start_instances(InstanceIds=event['ec2Instances'])
if 'rdsInstance' in event:
rds = boto3.client('rds', region_name=region)
rds.start_db_instance(DBInstanceIdentifier=event['rdsInstance'])
if 'ecsCluster' in event:
ecs = boto3.client('ecs')
ecsResponse = ecs.list_services(cluster=event['ecsCluster'], launchType='FARGATE')
for serviceArn in ecsResponse['serviceArns']:
serviceName = serviceArn.split('/')[1];
ecs.update_service(cluster=event['ecsCluster'], service=serviceName, desiredCount=1)

Add the below code into the event handler of Stop-lambda function:

import boto3
import os
# Enter the region your instances are in. Include only the region without specifying Availability Zone; e.g., 'us-east-1'
region = os.environ['AWS_REGION']
def lambda_handler(event, context):
print 'EVENT: ' + str(event)
if 'ec2Instances' in event:
ec2 = boto3.client('ec2', region_name=region)
ec2.stop_instances(InstanceIds=event['ec2Instances'])
if 'rdsInstance' in event:
rds = boto3.client('rds', region_name=region)
rds.stop_db_instance(DBInstanceIdentifier=event['rdsInstance'])
if 'ecsCluster' in event:
ecs = boto3.client('ecs')
ecsResponse = ecs.list_services(cluster=event['ecsCluster'], launchType='FARGATE')
for serviceArn in ecsResponse['serviceArns']:
serviceName = serviceArn.split('/')[1];
ecs.update_service(cluster=event['ecsCluster'], service=serviceName, desiredCount=0)

Note: Please update/create the IAM Policies as per your need while attaching them to the lambda function’s execution rule.

{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"VisualEditor0",
"Effect":"Allow",
"Action":[
"ecs:ListServices",
"ec2:StartInstances",
"ec2:StopInstances"
],
"Resource":"*"
},
{
"Sid":"VisualEditor1",
"Effect":"Allow",
"Action":[
"ecs:UpdateService",
"ssm:GetParameters",
"rds:StopDBInstance",
"rds:StartDBInstance"
],
"Resource":"*"
},
{
"Sid":"VisualEditor2",
"Effect":"Allow",
"Action":"ssm:DescribeParameters",
"Resource":"arn:aws:ssm:*:*:*"
}
]
}

Step 2: Go to Amazon eventBridge and move to the rules section and create a rule for the start

Step 2.1: Add name and description:

Step 2.2: Define pattern: Select Schedule and Cron expression.

Note: Cron only supports the GMT. Please adjust the time in the cron after selecting the Local time zone. I have selected the IST. once set up the Cron, we can see the next 10 triggers date at the bottom.

Learn more about cron expression from here

Define event pattern for strat

Step 2.3: Select event Bus: Please select the AWS default event bus

Event bus

Step 2.4: Select target: Add the already created lambda function ‘ start-lambda‘ in the target and update the configure input

Configure Lambda and input

Step 3: Go to Amazon eventBridge and move to the rules section and create a rule for the stop

Step 3.1:

stop rule

Step 3.2:

Note: Cron only supports the GMT. Please adjust the time in the cron after selecting the Local time zone. I have selected the IST. once set up the Cron, we can see the next 10 triggers date at the bottom.

Learn more about cron expression from here

Step 3.3: Same as step 2.3

Step 3.4: Select target: Add the already created lambda function ‘ stop-lambda‘ in the target and update the configure input

It's Done. Now every day, the mentioned AWS resources will start automatically at 9:30 AM and shut down at 6:30 PM except Sat & Sun.

How to start the resources manually when required?

> Go to lambda function (create-lambda/stop-lambda) and click on the test tab and configure the test event.

> Put the event document in JSON file and click on the test. once clicked, it will start/stop the resources.

restart manually

--

--