You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python Boto3的AWS Lambda启动EC2实例时触发IncorrectInstanceState错误

问题描述

我用Python Boto3写了一个AWS Lambda函数,用来启动所有EC2实例,之前运行正常。后来我终止了2台实例,现在运行代码时,它还是会尝试启动已经终止的实例,这太奇怪了。Lambda难道不该忽略已终止的实例,只启动处于“Stopped”状态的实例吗?我是不是必须自己写逻辑检查实例状态,只启动处于“Stopped”状态的实例?

错误信息

ClientError: 调用StartInstances操作时发生错误(IncorrectInstanceState):实例'i-002d545f637ad1ebd'处于无法启动的状态。
回溯(最近的调用位于最前):

原Lambda代码

import json
import boto3
import pprint
from pprint import pprint


def lambda_handler(event, context):
    aws_mgmt_console = boto3.session.Session()
    ec2_console_resource = aws_mgmt_console.resource('ec2')
    ec2_console_client = aws_mgmt_console.client('ec2')
  

    # 同时启动所有实例
    # 第一步:获取所有实例列表       
  
    all_instance_ids=[]
    for each_instance in ec2_console_resource.instances.all():
         all_instance_ids.append(each_instance.id)
  
    # 第二步:创建等待器       
    waiter=ec2_console_client.get_waiter('instance_running')
 
    ec2_console_resource.instances.start()
    
    waiter.wait(InstanceIds=all_instance_ids) 

    print("所有EC2实例已启动并运行")

解决方案

是的,你必须自行编写逻辑过滤出处于Stopped状态的实例,再执行启动操作。原因如下:

  • Boto3的instances.start()方法不会自动过滤实例状态,它会尝试对所有传入的实例执行启动操作,包括已终止(Terminated)、运行中(Running)等非Stopped状态的实例。
  • 已终止的实例属于不可操作状态,调用StartInstances会直接抛出IncorrectInstanceState错误。

修改后的代码可以这样写:

import json
import boto3

def lambda_handler(event, context):
    aws_mgmt_console = boto3.session.Session()
    ec2_console_resource = aws_mgmt_console.resource('ec2')
    ec2_console_client = aws_mgmt_console.client('ec2')

    # 过滤出处于Stopped状态的实例
    stopped_instances = ec2_console_resource.instances.filter(
        Filters=[{'Name': 'instance-state-name', 'Values': ['stopped']}]
    )
    
    stopped_instance_ids = [instance.id for instance in stopped_instances]
    
    if not stopped_instance_ids:
        print("没有处于Stopped状态的实例需要启动")
        return
    
    # 启动过滤后的实例
    ec2_console_resource.instances.filter(InstanceIds=stopped_instance_ids).start()
    
    # 等待实例启动完成
    waiter = ec2_console_client.get_waiter('instance_running')
    waiter.wait(InstanceIds=stopped_instance_ids)

    print(f"已成功启动以下实例: {stopped_instance_ids}")

修改点说明:

  • 使用filter方法配合instance-state-name过滤器,只获取Stopped状态的实例
  • 先检查是否有需要启动的实例,避免无意义的操作
  • 仅对过滤后的实例执行启动和等待操作,避免对已终止或运行中实例的无效调用

内容的提问来源于stack exchange,提问作者Jason

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 22:24:28