Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import * as sns from '@aws-cdk/aws-sns';
import * as cdk from '@aws-cdk/core';
import { Duration } from '@aws-cdk/core';
import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
import { Ec2Action } from './ec2action';
import { Metric } from '@aws-cdk/aws-cloudwatch';
import { SnsAction } from '@aws-cdk/aws-cloudwatch-actions';
import * as AWS from 'aws-sdk';
class LombaXInstance {
id: String
name: String
constructor(id: String, name: String) {
this.id = id;
this.name = name;
}
}
export class LombaXStatusCheckEc2Stack extends cdk.Stack {
async parseInstances() {
return new Promise((resolve, reject) => {
// to retrieve all the EC2 Instances, I integrated the AWS SDK inside the CDK Stack.
// This is not considered a best practice however...you should rely on CDK Custom Resources
AWS.config.loadFromPath('./aws_credentials.json');
let params = {
DryRun: false
};
let ec2 = new AWS.EC2({apiVersion: '2016-11-15'});
let parsedInstances: Array<any> = [];
// find all instances in the account and region
ec2.describeInstances(params, function(err, data) {
if (err)
reject(err);
let dataParsed = data;
let inst = dataParsed?.Reservations;
inst?.forEach(el => {
let instancesToPush = el.Instances;
instancesToPush?.forEach(i => {
let instanceID = i.InstanceId as string;
let instanceName = (i.Tags?.find((o) => (o.Key == 'Name')))?.Value as string;
// filter over instance with the "autorecovery" tag set to true
let instanceRecoveryTag = (i.Tags?.find((o) => (o.Key == 'autorecovery')))?.Value as string;
if ( typeof instanceID === 'string' &&
typeof instanceName === 'string' &&
typeof instanceRecoveryTag === 'string' &&
instanceRecoveryTag == 'true') {
let obj = new LombaXInstance(
instanceID,
instanceName
);
parsedInstances.push(obj);
}
});
});
resolve(parsedInstances);
});
});
}
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const topicARN = 'arn:aws:sns:eu-west-1:123123123:XXXXX'; // insert here your default topic ARN
const topic = sns.Topic.fromTopicArn(this, id, topicARN);
const snsAction = new SnsAction(topic);
const ec2Action = new Ec2Action(`arn:aws:automate:${props?.env?.region}:ec2:recover`);
this.parseInstances().then(
(parsedInstances: any) => {
parsedInstances.forEach((instance: LombaXInstance) => {
let instanceID = instance.id;
let instanceName = instance.name;
console.log('Found following instance ID: '+ instanceID + ' Name: ' + instanceName);
let statusCheckMetric = new Metric({
metricName: "StatusCheckFailed_System",
namespace: "AWS/EC2",
dimensions: {
InstanceId: instanceID
},
statistic: "Minimum",
period: Duration.minutes(1)
});
let statusCheckAlarm = statusCheckMetric.createAlarm(
this,
'StatusCheckAlarm-'+instanceName,
{
evaluationPeriods: 15,
threshold: 0,
comparisonOperator:
cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
statistic: "Minimum",
}
);
statusCheckAlarm.addAlarmAction(
snsAction,
ec2Action
);
});
}
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment