4

I want to start and stop EC2 instances using Lambda Function

I am able to start and stop EC2 instances using the Instance ID but How can I do the same for Instance name, I am trying to do this because my end-user doesn't know what is instance-id they are only aware of Instance name

below is my code which is working fine for instance ID

import json
import boto3

region = 'us-east-1'
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    instances = event["instances"].split(',')
    action = event["action"]
    
    if action == 'Start':
        print("STARTing your instances: " + str(instances))
        ec2.start_instances(InstanceIds=instances)
        response = "Successfully started instances: " + str(instances)
    elif action == 'Stop':
        print("STOPping your instances: " + str(instances))
        ec2.stop_instances(InstanceIds=instances)
        response = "Successfully stopped instances: " + str(instances)
    
    return {
        'statusCode': 200,
        'body': json.dumps(response)
    }

Events I am passing for stopping

{
  "instances": "i-0edb625f45fd4ae5e,i-0818263a2152a23bd,i-0cd2e17ba6f62f651",
  "action": "Stop"
}

Events I am passing for starting

{
  "instances": "i-0edb625f45fd4ae5e,i-0818263a2152a23bd,i-0cd2e17ba6f62f651",
  "action": "Start"
}
4
  • 1
    Instance name is not unique. You may have many instances with same name. Then you want to stop all of them? Commented Feb 25, 2021 at 7:57
  • yes make sense right Commented Feb 25, 2021 at 8:02
  • So instead of instance-ids, you are going to pass instance names? Commented Feb 25, 2021 at 8:14
  • yes we have instance name only ,because end user don't know about instances IDs Commented Feb 25, 2021 at 9:17

2 Answers 2

7

Instance name is based on tag called Name. So to get instance ids based on name you have to filter instances by tags. Below is one possible way of doing that:

import json
import boto3

region = 'us-east-1'

ec2 = boto3.client('ec2', region_name=region)

def get_instance_ids(instance_names):

    all_instances = ec2.describe_instances()
    
    instance_ids = []
    
    # find instance-id based on instance name
    # many for loops but should work
    for instance_name in instance_names:
        for reservation in all_instances['Reservations']:
            for instance in reservation['Instances']:
                if 'Tags' in instance:
                    for tag in instance['Tags']:
                        if tag['Key'] == 'Name' \
                            and tag['Value'] == instance_name:
                            instance_ids.append(instance['InstanceId'])
                            
    return instance_ids

def lambda_handler(event, context):
    
    instance_names = event["instances"].split(',')
    action = event["action"]

    instance_ids = get_instance_ids(instance_names)

    print(instance_ids)

    if action == 'Start':
        print("STARTing your instances: " + str(instance_ids))
        ec2.start_instances(InstanceIds=instance_ids)
        response = "Successfully started instances: " + str(instance_ids)
    elif action == 'Stop':
        print("STOPping your instances: " + str(instance_ids))
        ec2.stop_instances(InstanceIds=instance_ids)
        response = "Successfully stopped instances: " + str(instance_ids)
    
    return {
        'statusCode': 200,
        'body': json.dumps(response)
    }
Sign up to request clarification or add additional context in comments.

5 Comments

Be aware that Names have not to be unique and this will start/stop all of them (with the same name) at once
@lipek Yes, as names are not unqiue. Otherwise have to ask your client to get you instance id, not name. Or maybe your client is sure he/she does not have duplicate names?
@lipek Oh. I thought you were the OP. So my comment is probably out of context:-)
@RahultheSWE What do you mean? Did the answer worked?
I'm getting keyError
1

There is a highly scalable and cost-effective solution developed by AWS. Check it at https://aws.amazon.com/es/solutions/implementations/instance-scheduler-on-aws/.

It is easily deployed using CloudFormation templates and managed by a cli. Last but not least, it operates over multiple accounts, and that way you can have a lot of ec2 instances (and RDS instances too) spread over multiple accounts and this solution will save you a lot of effort.

2 Comments

but it will come up with some cost, as designing the whole system we always prefer to save money,that is more important,but thanks for your response
I use it and it's very cheap for me (in my team we manage about 20 instances) as you can use lambda 24 times (hourly) a day and a dynamo table with a few entries... nothing else. So I recommend you if your number of instances increases because you will get a strong control over the solution, but actually, if you just have a few instances, it makes more sense use just a lambda

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.