Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
393 views
in Technique[技术] by (71.8m points)

python - Lambda Boto3 program to stop instances based on tag

I have already written code on automatic stopping of instances based on specific tag. Though my program is working good. But the problem is for me is that my tag value is case sensitive. For example if I rename my tag value as "testinstance" my program does not work. Can anyone help me with this?

Thanks in advance

Here is my code,

import json
import boto3

def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name='ap-south-1')
    a = ec2.describe_instances(Filters=[{'Name':'tag:Testing', 'Values':['TestInstance']}])
    b = a['Reservations']

    for c in b:
        inst = c['Instances']

        for d in inst:
           instid = d['InstanceId']
           instrun = d['State']['Name']

           if instrun == 'running':
              ec2.stop_instances(InstanceIds=[instid])
              print("The instance is stopped:" + instid)
           else:
              print("The instance in stop state:" + instid)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't think there's a "good" way to do this. Ideally I'd recommend just making all your tags lowercase so you don't have this problem.

What you could do is pull ALL the instances from AWS and then check the tags manually in Python:

import json
import boto3

ec2 = boto3.client('ec2', region_name='ap-south-1')

def lambda_handler(event, context):
    ec2_instances = ec2.describe_instances()
    ec2_reservations = ec2_instances['Reservations']

    for reservation in ec2_reservations:
        instances = reservation['Instances']

        for instance in instances:
            if should_stop_instance(instance):
                stop_instance(instance)


def should_stop_instance(instance):
    should_stop = False

    instance_state = instance['State']['Name']

    for tag in instance['Tags']:
        if tag['key'].lower() == 'tag:testing' and tag['Value'].lower() == 'testinstance' and instance_state == 'running':
            should_stop = True

    return should_stop


def stop_instance(instance):
    instance_id = instance['InstanceId']

    ec2.stop_instances(InstanceIds=[instance_id])
    print("The instance is stopped:" + instance_id)

Also, you would benefit from posting more legible code in the future. Naming variables a, b and c makes it really difficult for people to understand it. See how my variables are named in a way that makes it simpler to read and logic is split out in to functions which helps legibility.

I've also moved the ec2 = boto3.client('ec2', region_name='ap-south-1') out of the handler function. You likely just want to initialise this once when the lambda cold starts and not every time from 'warm' starts.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...