创建CloudWatch警报,该警报通过SNS / Lambda将实例设置为待机

时间:2019-09-09 19:21:52

标签: aws-lambda amazon-cloudwatch

我要执行的操作是在实例达到警报状态时将其设置为待机模式。我已经设置了一个警报来检测我的实例何时达到90%的CPU时间。警报当前通过SNS调用Lambda函数发送Slack和文本消息。我要添加的是使实例进入待机模式。这些实例位于自动伸缩组中。

我发现您可以使用以下命令通过CLI执行此操作:

aws autoscaling enter-standby --instance-ids i-66b4f7d5be234234234 --auto-scaling-group-name my-asg --should-decrement-desired-capacity

您也可以使用boto3进行此操作:

    response = client.enter_standby(
        InstanceIds=[
            'string',
        ],
        AutoScalingGroupName='string',
        ShouldDecrementDesiredCapacity=True|False
    )

我假设我需要编写另一个由SNS触发的Lambda函数,它将使用boto3代码来做到这一点?

在我开始之前是否有更好/更简便的方法?

我已经将InstanceId传递给Lambda事件,所以我必须在事件中添加ASG名称。

当我已经具有实例ID时,是否可以在Lambda函数中获取ASG名称?然后,我不必随事件传递它。

谢谢!

2 个答案:

答案 0 :(得分:1)

您的问题有两个子部分,因此我将尝试按顺序回答它们:

  

我假设我需要编写另一个由SNS触发的Lambda函数,它将使用boto3代码来做到这一点?

不需要,您可以重载现有功能。我可以为单独的函数(关注点分离)或一个函数(因为“对CPU的响应达到90%”基本上是“一件事”)看到一个有效的参数。

  

在我开始之前是否有更好/更简便的方法?

除了Cloudwatch-> SNS-> Lambda,我不知道有什么其他方法可以实现。

  

当我已经具有实例ID时,是否可以在Lambda函数中获取ASG名称?

是的,see this question for an example。由您自己决定是在Lambda中执行此操作还是将其他参数传递给清洁器选项。

答案 1 :(得分:0)

对于任何感兴趣的人,这是我为Lambda函数(在Python中)想到的:

# Puts the instance in the standby mode which takes it off the load balancer
#   and a replacement unit is spun up to take its place
#

import json
import boto3

ec2_client = boto3.client('ec2')
asg_client = boto3.client('autoscaling')

def lambda_handler(event, context):
    # Get the id from the event JSON
    msg = event['Records'][0]['Sns']['Message']
    msg_json = json.loads(msg)
    id = msg_json['Trigger']['Dimensions'][0]['value']
    print("Instance id is " + str(id))

    # Capture all the info about the instance so we can extract the ASG name later
    response = ec2_client.describe_instances(
        Filters=[
            {
                'Name': 'instance-id',
                'Values': [str(id)]
            },
        ],
    )

    # Get the ASG name from the response JSON
    #autoscaling_name = response['Reservations'][0]['Instances'][0]['Tags'][1]['Value']
    tags = response['Reservations'][0]['Instances'][0]['Tags']
    autoscaling_name = next(t["Value"] for t in tags if t["Key"] == "aws:autoscaling:groupName")
    print("Autoscaling name is - " + str(autoscaling_name))

    # Put the instance in standby
    response = asg_client.enter_standby(
        InstanceIds=[
            str(id),
        ],
        AutoScalingGroupName=str(autoscaling_name),
        ShouldDecrementDesiredCapacity=False
    )