Created
July 31, 2022 11:14
-
-
Save sjoerdsmink/a36d30eef04fb7d919b8500959df362b to your computer and use it in GitHub Desktop.
Stopping EC2 instances when not in use
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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