Boto3 并未真正启动实例

问题描述 投票:0回答:1

我正在实例上运行 Python 代码,并尝试使用 boto3 启动 EC2 实例

start_instances
。该代码有效并给出以下响应:

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

但在 UI 中它还没有启动,甚至没有挂起。我已经运行了代码 7 次,结果是一样的。为了进行测试,我尝试了相反的方法:我使用 UI 启动实例并使用

stop_instances
函数,它成功了!

权限如下:

"ec2:StartInstances",
"ec2:StopInstances"

可能会发生什么?

python amazon-web-services amazon-ec2 boto3
1个回答
0
投票

我使用的Python代码运行良好。它创建一个显示在 AWS 管理控制台中的 EC2 实例。这是 PyCharm 中的输出。

这是控制台中的实例

Python代码是:

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

确保在上述代码中输入有效的 ID 值。

© www.soinside.com 2019 - 2024. All rights reserved.