Skip to content

Instantly share code, notes, and snippets.

@sjoerdsmink
Created July 31, 2022 11:14
Show Gist options
  • Save sjoerdsmink/a36d30eef04fb7d919b8500959df362b to your computer and use it in GitHub Desktop.
Save sjoerdsmink/a36d30eef04fb7d919b8500959df362b to your computer and use it in GitHub Desktop.
Stopping EC2 instances when not in use
# See https://sjoerdsmink.medium.com/saving-energy-and-money-stopping-ec2-instances-when-not-in-use-c8e44eb7f6b6 for full story
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
EC2InstanceId:
Type: 'String'
Description: 'EC2 Instance ID, for example i-1234567890abcdef0'
Resources:
# Optional CloudWatch alarm when CPU < 20% for 50 minutes
CPUAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmActions:
- !Sub "arn:aws:automate:${AWS::Region}:ec2:stop"
AlarmDescription: CPU alarm for unused EC2 instance
ComparisonOperator: LessThanThreshold
DatapointsToAlarm: 10
EvaluationPeriods: 12
MetricName: CPUUtilization
Namespace: AWS/EC2
Period: 300
Statistic: Maximum
Threshold: 20
Dimensions:
- Name: InstanceId
Value: !Ref EC2InstanceId
# Alternative Lambda function to turn off the EC2 instance
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
Description: Stop GitLab runner EC2 instance
Code:
ZipFile: !Sub |
import boto3
region = '${AWS::Region}'
instances = ['${EC2InstanceId}']
ec2 = boto3.client('ec2', region_name=region)
def lambda_handler(event, context):
ec2.stop_instances(InstanceIds=instances)
print('stopped your instances: ' + str(instances))
Handler: index.lambda_handler
MemorySize: 128
Timeout: 10
Role: !Sub ${LambdaExecutionRole.Arn}
Runtime: python3.9
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub '${AWS::StackName}-lambda-role'
Description: !Sub 'Instance Profile for Lambda stopping EC2 instance'
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: StopEC2Instance
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: 'ec2:StopInstances'
Resource: !Sub 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:instance/${EC2InstanceId}'
# CloudWatch cron to trigger Lambda function
LambdaSchedule:
Type: AWS::Events::Rule
Properties:
Description: Schedule for stopping EC2 instance end of day
ScheduleExpression: cron(0 18 * * ? *)
State: ENABLED
Targets:
- Arn: !Sub ${LambdaFunction.Arn}
Id: LambdaSchedule
LambdaSchedulePermission:
Type: AWS::Lambda::Permission
Properties:
Action: 'lambda:InvokeFunction'
FunctionName: !Sub ${LambdaFunction.Arn}
Principal: 'events.amazonaws.com'
SourceArn: !Sub ${LambdaSchedule.Arn}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment