top of page

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.

  1. Creating a role for lambda and attach a policy with permission to Start the EC2 instances.

  2. Creating a lambda event handler to execute a script (Python script in our example) for starting EC2 instances.

  3. 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.

  1. Enter the stopped instance(s) Id in the cloud formation in the instances field under parameters section.

  2. Enter the appropriate region of your EC2 instance(s)

  3. Enter the hours, minutes and the days in the CRON expression either in the script or in the CRON field while uploading

  4. 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.

 


661 views0 comments
bottom of page