Search code examples
pythonamazon-web-servicesamazon-ec2lambdaboto3

How to Stop and Start EC2 Instance using boto3 and lambda Function


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"
}

Solution

  • 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)
        }