skip to Main Content

I’m running Python code on an instance and I’m trying to start an EC2 instance using boto3 start_instances. The code works and gives the following response:

Response: {'StartingInstances': [{'CurrentState': {'Code': 0, 'Name': 'pending'}, 'InstanceId': 'i-<id>', 'PreviousState': {'Code': 80, 'Name': 'stopped'}}], [..]

But in the UI it’s not up, not even pending. I’ve run the code 7 times and its the same thing. To make a test, I tried the opposite: I started the instance using the UI and used the stop_instances function and it worked!

The permissions are these:

"ec2:StartInstances",
"ec2:StopInstances"

What might be happening?

2

Answers


  1. Chosen as BEST ANSWER

    The problem was that the instance that I was trying to start have an encrypted EBS volume. Then, it is necessary to give some KMS permissions, I found them here: https://nqbao.medium.com/aws-correct-permission-to-start-an-ec2-instance-with-encrypted-ebs-507933c01511

    It is weird that the console don't show an error in this case.


  2. The Python code I am using works fine. It creates an EC2 instance that shows up in the AWS Management Console. Here is output in PyCharm.

    enter image description here

    Here is instance in the Console

    enter image description here

    Python code is:

    import logging
    import boto3
    from botocore.exceptions import ClientError
    
    logger = logging.getLogger(__name__)
    
    
    class InstanceWrapper:
        """Encapsulates Amazon Elastic Compute Cloud (Amazon EC2) instance actions."""
    
        def __init__(self, ec2_resource, instance=None):
            self.ec2_resource = ec2_resource
            self.instance = instance
    
        def create(self, image, instance_type, key_pair, security_groups=None):
            try:
                instance_params = {
                    'ImageId': image.id, 'InstanceType': instance_type, 'KeyName': key_pair.name
                }
                if security_groups is not None:
                    instance_params['SecurityGroupIds'] = [sg.id for sg in security_groups]
                self.instance = self.ec2_resource.create_instances(**instance_params, MinCount=1, MaxCount=1)[0]
                self.instance.wait_until_running()
            except ClientError as err:
                logging.error(
                    "Couldn't create instance with image %s, instance type %s, and key %s. "
                    "Here's why: %s: %s", image.id, instance_type, key_pair.name,
                    err.response['Error']['Code'], err.response['Error']['Message'])
                raise
            else:
                return self.instance
    
        def display(self, indent=1):
            if self.instance is None:
                logger.info("No instance to display.")
                return
    
            try:
                self.instance.load()
                ind = 't' * indent
                print(f"{ind}ID: {self.instance.id}")
                print(f"{ind}Image ID: {self.instance.image_id}")
                print(f"{ind}Instance type: {self.instance.instance_type}")
                print(f"{ind}Key name: {self.instance.key_name}")
                print(f"{ind}VPC ID: {self.instance.vpc_id}")
                print(f"{ind}Public IP: {self.instance.public_ip_address}")
                print(f"{ind}State: {self.instance.state['Name']}")
            except ClientError as err:
                logger.error(
                    "Couldn't display your instance. Here's why: %s: %s",
                    err.response['Error']['Code'], err.response['Error']['Message'])
                raise
    
        def terminate(self):
            if self.instance is None:
                logger.info("No instance to terminate.")
                return
    
            instance_id = self.instance.id
            try:
                self.instance.terminate()
                self.instance.wait_until_terminated()
                self.instance = None
            except ClientError as err:
                logging.error(
                    "Couldn't terminate instance %s. Here's why: %s: %s", instance_id,
                    err.response['Error']['Code'], err.response['Error']['Message'])
                raise
    
        def start(self):
            if self.instance is None:
                logger.info("No instance to start.")
                return
    
            try:
                response = self.instance.start()
                self.instance.wait_until_running()
            except ClientError as err:
                logger.error(
                    "Couldn't start instance %s. Here's why: %s: %s", self.instance.id,
                    err.response['Error']['Code'], err.response['Error']['Message'])
                raise
            else:
                return response
    
        def stop(self):
            if self.instance is None:
                logger.info("No instance to stop.")
                return
    
            try:
                response = self.instance.stop()
                self.instance.wait_until_stopped()
            except ClientError as err:
                logger.error(
                    "Couldn't stop instance %s. Here's why: %s: %s", self.instance.id,
                    err.response['Error']['Code'], err.response['Error']['Message'])
                raise
            else:
                return response
    
        def get_images(self, image_ids):
            try:
                images = list(self.ec2_resource.images.filter(ImageIds=image_ids))
            except ClientError as err:
                logger.error(
                    "Couldn't get images. Here's why: %s: %s",
                    err.response['Error']['Code'], err.response['Error']['Message'])
                raise
            else:
                return images
    
        def get_instance_types(self, architecture):
            try:
                inst_types = []
                it_paginator = self.ec2_resource.meta.client.get_paginator('describe_instance_types')
                for page in it_paginator.paginate(
                        Filters=[{
                            'Name': 'processor-info.supported-architecture', 'Values': [architecture]},
                            {'Name': 'instance-type', 'Values': ['*.micro', '*.small']}]):
                    inst_types += page['InstanceTypes']
            except ClientError as err:
                logger.error(
                    "Couldn't get instance types. Here's why: %s: %s",
                    err.response['Error']['Code'], err.response['Error']['Message'])
                raise
            else:
                return inst_types
    
    
    def main11():
        # Replace 'your-image-id', 'your-instance-type', 'your-key-pair-name', and 'your-security-groups'
        # with your actual values
        image_id = 'ami-043326'
        instance_type = 't1.micro'
        key_pair_name = 'scottkeys'
        security_groups = None  # Replace with your actual security groups if needed
    
        # Create an EC2 resource
        ec2_resource = boto3.resource('ec2', region_name='us-west-2')
    
        # Create an instance of InstanceWrapper
        instance_wrapper = InstanceWrapper(ec2_resource)
    
        # Create an EC2 instance
        created_instance = instance_wrapper.create(
            image=instance_wrapper.get_images([image_id])[0],
            instance_type=instance_type,
            key_pair=ec2_resource.KeyPair(key_pair_name),
            security_groups=security_groups
        )
    
        # Display information about the created instance
        instance_wrapper.display()
    
        # Stop and then start the instance (for demonstration purposes)
        instance_wrapper.stop()
        instance_wrapper.start()
    
        # Terminate the instance
        instance_wrapper.terminate()
    
    
    if __name__ == '__main__':
        main11()
    

    Make sure you enter a valid ID value in the above code.

    Try that code and you will see the instance in the console. Set a break point after you start it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search