AWS_Beginner
AWS_Beginner

Reputation: 466

boto3 python to start EC2

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"

Upvotes: 1

Views: 3272

Answers (3)

AGR
AGR

Reputation: 351

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/

Upvotes: 1

AWS_Beginner
AWS_Beginner

Reputation: 466

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

Upvotes: 3

Marcin
Marcin

Reputation: 238051

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

Upvotes: 4

Related Questions