Reputation: 466
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
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
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
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