Start EC2 instances whenever you need, through AWS CloudFormation!
In this article, I have articulated how we can START the stopped EC2 instances as and when we need. Automating the start of EC2 instances daily at specific time periods like start of the day (when stopped previous night) would be a real cost optimizing step.
Pre-cursor
Before we look into the cloudformation script directly, please make sure that you have atleast one EC2 instance in STOPPED state. Also, Please read my previous article on stopping the instances through CFN as one may require the script for that as well.
What the script does?
Starting EC2 instances using cloudformation involves the following steps. The cloudformation script would do all the below mentioned steps.
Creating a role for lambda and attach a policy with permission to Start the EC2 instances.
Creating a lambda event handler to execute a script (Python script in our example) for starting EC2 instances.
Create a script to start EC2 instances by running the lambda event handler at the specific time and specific days.
Here, the specific time and days are provided in the form of a CRON expression. So one need to clearly understand the CRON expression before running the CFN script.
This script has been taken from AWS documentation but I have modified and separated the scripts for STOP and START actions.
Understanding CRON Expression


For more information on CRON expression, please follow the amazon documentation link.
Cloud formation script to START (or schedule to start) instances whenever we need.
AWSTemplateFormatVersion: '2010-09-09'
Description: Lambda function with cfn-response.
Parameters:
instances:
Default: i-0506f7d826a359c4f
Description: Instance ID's seperated by commers
Type: String
Region:
Default: ap-southeast-1
Description: region only 1 region supported
Type: String
StartScheduled:
Default: cron(0 7 ? * MON-SUN *)
Description: enter an Schedule expression example cron(0 7 ? * MON-FRI * ) see https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html
Type: String
Resources:
StartEC2Instances:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.8
Role: !GetAtt Role.Arn
Handler: index.lambda_handler
Timeout: 60
Environment:
Variables:
instances: !Ref instances
Region: !Ref Region
Code:
ZipFile: |
import json
import re
import os
import boto3
def lambda_handler(event, context):
# TODO implement
instances_str = os.environ['instances']
region = os.environ['Region']
ec2 = boto3.client('ec2', region_name=region)
instances= re.findall(r"i-[0-9a-z]{17}|i-[0-9a-z]{8}", instances_str)
print('started your instances: ' + str(instances)+ "in Region "+ region)
ec2.start_instances(InstanceIds=instances)
return {
'statusCode': 200,
'body': json.dumps('started your instances: ' + str(instances))
}
Description: Function that started instances
permissionForEventsToInvokeStartEC2Instances:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !GetAtt StartEC2Instances.Arn
Action: lambda:InvokeFunction
Principal: events.amazonaws.com
"SourceArn" : !GetAtt StartScheduledRule.Arn
Role:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
Policies:
- PolicyName: Ec2permissions
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- "ec2:StartInstances"
Resource: '*'
StartScheduledRule:
Type: AWS::Events::Rule
Properties:
Description: "ScheduledRule"
ScheduleExpression: !Ref StartScheduled
State: "ENABLED"
Targets:
-
Arn: !GetAtt StartEC2Instances.Arn
Id: "TargetFunctionV1"
Formatted Script



How to execute the script?
As mentioned in the pre-cursor section, to execute the START script, you must ensure that you have one or more EC2 instances in STOPPED state.

Enter the stopped instance(s) Id in the cloud formation in the instances field under parameters section.
Enter the appropriate region of your EC2 instance(s)
Enter the hours, minutes and the days in the CRON expression either in the script or in the CRON field while uploading
Upload the script in CloudFormation on clicking Create Stack

5. click on Next, provide a name to the stack and enter the time to stop the EC2 instance in the StartScheduled field.

6. Click on the acknowledgement for creating a role and create the stack. The stack runs successfully.

7. Once the script has been successfully run, check the status of the instance under EC2

8. Also, check for the lambda function being created in the Lambda section.

TIP:
If you do not want to Start or schedule that start time everyday and want to start instances at an adhoc basis, you could just go ahead run the stack by providing the hours and minutes on the CRON expression and then delete the stack when instance is started.
I hope the above article will be useful for many AWS users who want to start the stopped EC2 instances automatically on need basis.
If you find this article helpful, kindly share this with your known groups and also provide your valuable comments here. Thank you.