forked from jansauer/ec2-start-stop-lambda
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
97 lines (83 loc) · 4.26 KB
/
index.js
File metadata and controls
97 lines (83 loc) · 4.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
'use strict';
// const AWSXRay = require('aws-xray-sdk');
// const AWS = AWSXRay.captureAWS(require('aws-sdk'));
const AWS = require('aws-sdk');
const ec2 = new AWS.EC2();
const parser = require('cron-parser');
const moment = require('moment');
const momentTimezone = require('moment-timezone');
const startExpressionTag = process.env.START_EXPRESSION_TAG;
const stopExpressionTag = process.env.STOP_EXPRESSION_TAG;
const graceTime = process.env.GRACE_TIME_MINUTES;
const timezone = process.env.TIMEZONE ? process.env.TIMEZONE : 'Europe/Berlin';
exports.handler = (event, context, callback) => {
ec2.describeInstances({
Filters: [{
Name: 'tag-key',
Values: [
startExpressionTag,
stopExpressionTag
]
}]
}, function (error, data) {
if (error) callback(error);
console.log('setting timezone ', timezone);
moment.tz.setDefault(timezone);
data.Reservations.forEach(function (reservation) {
reservation.Instances.forEach(function (instance) {
// Check if instance should be started
let startexpression = instance.Tags.find(function (element) {
return element.Key == startExpressionTag;
});
if (startexpression && instance.State.Name == 'stopped') {
try {
console.log('Found start expression \'%s\' on stopped instance \'%s\'', startexpression.Value, instance.InstanceId);
if (isCurrentTimeAffectedByCron(startexpression)) {
console.log('Instance \'%s\' should be started as of \'%s\'', instance.InstanceId);
ec2.startInstances({
InstanceIds: [instance.InstanceId]
}, function (error, data) {
if (error) callback(error);
console.log('Instance \'%s\' is now \'%s\'',
data.StartingInstances[0].InstanceId, data.StartingInstances[0].CurrentState.Name);
});
}
} catch (error) {
console.log('Unable to parse start expression \'%s\' on stopped instance \'%s\'',
startexpression.Value, instance.InstanceId);
}
}
// Check if instance should be stopped
let stopexpression = instance.Tags.find(function (element) {
return element.Key == stopExpressionTag;
});
if (stopexpression && instance.State.Name == 'running') {
try {
console.log('Found stop expression \'%s\' on running instance \'%s\'', stopexpression.Value, instance.InstanceId);
if (isCurrentTimeAffectedByCron(stopexpression)) {
console.log('Instance \'%s\' should be stopped as of \'%s\'', instance.InstanceId);
ec2.stopInstances({
InstanceIds: [instance.InstanceId]
}, function (error, data) {
if (error) callback(error);
console.log('Instance \'%s\' is now \'%s\'',
data.StoppingInstances[0].InstanceId, data.StoppingInstances[0].CurrentState.Name);
});
}
} catch (error) {
console.log('Unable to parse stop expression \'%s\' on running instance \'%s\'',
stopexpression.Value, instance.InstanceId);
}
}
});
});
});
};
function isCurrentTimeAffectedByCron(expression) {
const interval = parser.parseExpression(expression.Value);
const previousCronFire = interval.prev();
let prev = moment(previousCronFire.toDate());
let prevWithGrace = moment(previousCronFire.toDate()).add(graceTime, 'm');
console.log('Is ', moment(), ' between ', prev, ' and ', prevWithGrace, ' = ', moment().isBetween(prev, prevWithGrace));
return moment().isBetween(prev, prevWithGrace);
}