我正在实例上运行 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代码运行良好。它创建一个显示在 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 值。