1
votes

I am using below python boto3 code to start Ec2

import boto3
region='us-east-1'
instance_id = 'i-06ce851edfXXXXXX'
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
resp = ec2.describe_instance_status(InstanceIds=[str(instance_id)],
        IncludeAllInstances=True)
print("Response = ",resp)

instance_status = resp['InstanceStatuses'][0]['InstanceState']['Code']
print("Instance status =", instance_status)

if instance_status == 80:
    ec2.start_instances(InstanceIds=[instance_id])
    print("Started instance with Instance_id",instance_id)

elif instance_status == 16:
     ec2.stop_instances(InstanceIds=[instance_id])
     print("Stopped EC2 with Instance-ID",instance_id)
else:
     print("No desired state found")

When instance is in running status i am able to stop the instance by running this lambda.

But when instance is in stopped state and i run Lambda i get below message and it show no error.But when i check in console instance is still in stopped state.I am not able to find out why instance is not getting in running stage. Instance status = 80 Started instance with Instance_id i-06ce851edfXXXXXX

Below is IAM role used

 {
    "Action": [
        "ec2:StopInstances",
        "ec2:StartInstances",
        "ec2:RebootInstances"
    ],
     "Resource": [
             "arn:aws:ec2:us0east-1:2x83xxxxxxxxxx:instance/i-06ce851edfXXXXXX"
      ],
     "Effect": "Allow"
3
Have you checked your output in CloudWatch logs?Chris Williams
Yes same as i given above.AWS_Beginner

3 Answers

4
votes

Your code is working. I verified it on my test instance with my lambda.

I reformatted it a bit to be easier to read, but it worked without any changes (except instance id). I can stop running instance. Then I can start stopped instance.

One thing to note is that stopping and starting take time. If you execute your function to fast, it won't be able to start an instance in a stopping state. Maybe that's why you thought it did not work.

Also make sure you increase your lambda's default timeout from 3 seconds to 10 or more.

import boto3

region='us-east-1'
instance_id = 'i-08a1e399b3d299c2d'

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

def lambda_handler(event, context):

    resp = ec2.describe_instance_status(
            InstanceIds=[str(instance_id)],
            IncludeAllInstances=True)

    print("Response = ",resp)

    instance_status = resp['InstanceStatuses'][0]['InstanceState']['Code']

    print("Instance status =", instance_status)

    if instance_status == 80:
        ec2.start_instances(InstanceIds=[instance_id])
        print("Started instance with Instance_id",instance_id)

    elif instance_status == 16:
         ec2.stop_instances(InstanceIds=[instance_id])
         print("Stopped EC2 with Instance-ID",instance_id)
    else:
         print("No desired state found")
1
votes

I found out the issue.Root volume of EC2 was encrypted so i have added KMS permission in role and it worked.

1
votes

Indeed, encryption of the root volume is the issue here. You can add inline policy to the role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "kms:*"
            ],
            "Resource": "*"
        }]
}

Note that it will grant full access form KMS for all of the resources. If you want, you can restrict the range of this policy to some specific resource.

More info about this problem here: https://aws.amazon.com/premiumsupport/knowledge-center/encrypted-volumes-stops-immediately/