如果任何实例未在EC2中的安全组下运行,是否可以获得警报?

时间:2018-01-19 19:31:21

标签: amazon-web-services amazon-ec2

基本上,如果我的一个安全组中有3个实例正在运行,那么如果一个实例没有响应,那么突然有3个实例,那么我需要发送cloudWatch Alert。可能吗 ?如果没有,那么我们将不胜感激。

2 个答案:

答案 0 :(得分:1)

此方法使用以下服务

创建SNS topic

创建一个SNS主题,并为Lambda函数的未来通知订阅接收者。我们叫MyTopic

使用以下政策创建IAM Role

我们称之为DummyRole(此角色的名称取决于您)。 此角色将附加到新的Lambda函数,以授予发布,记录和描述EC2实例的权限。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "logs:CreateLogGroup",
            "Resource": "arn:aws:logs:us-east-1:450338205852:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:us-east-1:450338205852:log-group:/aws/lambda/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "sns:Publish"
            ],
            "Resource": [
                "arn:aws:sns:us-east-1:450338205852:MyTopic"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

accountId替换为当前帐户。

创建一个新的Lambda函数

  • 此新Lambda函数的名称取决于您,对于此示例,名称为InstancesInSG,并且让我们附加IAM角色DummyRole。实现此Lambda函数以获取具有安全组的实例以及发送电子邮件取决于您。在这个例子中,我只是从Cloudwatch记录事件。

Lambda函数NodeJs示例

var AWS = require('aws-sdk');

"use strict";

//These constants must be declared in Environment variables.
const THRESHOLD = 5; // Lesser than this will notify to SNS topic.
const SECURITY_GROUPS = ['sg-11111']; //Only EC2 instances with this security group.
const TOPIC_ARN = "arn:aws:sns:us-east-1:AccountId:MyTopic";

exports.handler = (event, context, callback) => {
    var settings = { apiVersion: '2017-01-01', region: process.env.AWS_REGION };
    var ec2 = new AWS.EC2(settings);
    var params = {
        DryRun: false,
        MaxResults: THRESHOLD, // This value must be equals to the THRESHOLD.  The min value is 5.
        Filters: []
    };

    // You can use 'instance.group-name' to filter by security group's name.
    params.Filters = [
        {
            Name: 'instance.group-id',
            Values: SECURITY_GROUPS
        }, 
        {
            Name: 'instance-state-code',
            Values: ['16']
        }
    ];

    ec2.describeInstances(params, function(err, data) {
        if (err) {
            callback(err);
        } else {
            let count = 0;
            let reservations = data['Reservations'] || [];
            for (let i = 0; i < reservations.length; i++) {
                count += reservations[i]['Instances'].length;
            }

            if (count < THRESHOLD) {
                console.log("Sending SNS notification!");

                var sns = new AWS.SNS({region: process.env.AWS_REGION});
                let snsparams = { TargetArn: TOPIC_ARN, Message: `Only ${count} Instance(s) with security group '${SECURITY_GROUPS}' are running, please take action.`, Subject: 'EC2 Notification' };
                sns.publish(snsparams, callback);
                callback();
            }
        }
    });
};

Lambda函数Java示例

int THRESHOLD = 5; // Lesser than this will notify to SNS topic.
String[] SECURITY_GROUPS = new String[]{"sg-11111"}; //Only EC2 instances with this security group.
String TOPIC_ARN = "arn:aws:sns:us-east-1:AccountId:MyTopic";

AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

DescribeInstancesRequest request = new DescribeInstancesRequest();
request.setMaxResults(THRESHOLD);
ArrayList<Filter> filters = new ArrayList<Filter>();
Filter filter = new Filter();
filter.setName("instance.group-id");
filter.setValues(Arrays.asList(SECURITY_GROUPS));

filter = new Filter();
filter.setName("instance-state-code");
filter.setValues(Collections.singletonList("16"));

request.setFilters(filters);
DescribeInstancesResult response = ec2.describeInstances(request);

int count = response.getReservations().stream().mapToInt(reservation -> reservation.getInstances().size()).sum();
if (count < THRESHOLD) {
    AmazonSNS sns = AmazonSNSClientBuilder.defaultClient();
    String msg = String.format("Only %d Instance(s) with security group '%s' are running, please take action.", count, Arrays.toString(SECURITY_GROUPS));
    PublishRequest publishRequest = new PublishRequest(TOPIC_ARN, msg, "EC2 Notification");
    sns.publish(publishRequest);
}

您可以下载Java Maven项目here

收件箱中的通知消息: 只有2个安全组“sg-09311111”的实例正在运行,请采取措施。

enter image description here

创建Cloudwatch预定事件

在这里,您需要选择一个预定事件规则,将周期性窗口设置为1分钟并选择目标。目标将是Lambda函数InstancesInSG

enter image description here

enter image description here

enter image description here

这是在Cloudwatch中打印到日志中的事件:

enter image description here

希望有所帮助!

答案 1 :(得分:0)

I would like to be able to set cloudwatch alerts that monitor how many instances of a certain security group are running, and if the # of instances for that security group that are running goes below a certain number, an alert should be sent out.

如果可能,这是理想的情况,我建议创建自动缩放组,然后创建CloudWatch警报,甚至可以自动执行自动执行所需操作的操作,而不必让人员对事件做出响应。

如果这不起作用,是的,您可以随时在特定的EC2实例上创建CloudWatch警报,以观察StatusCheckFailed或类似的东西。

这与安全组无关。