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

AWS Lambda Python Boto3启动EC2实例遇UnboundLocalError问题咨询

解决UnboundLocalError:'each_scheduled_instance' referenced before assignment

问题原因

你的代码在启动EC2实例时触发UnboundLocalError,根源有两点:

  1. 变量未定义场景:如果AWS账号下没有任何EC2实例,for each_scheduled_instance in ec2_console_resource.instances.all()循环根本不会执行,each_scheduled_instance变量从未被赋值,后续调用each_scheduled_instance.wait_until_running()自然会报错。
  2. 逻辑缺陷:就算存在EC2实例,当前写法也只会等待最后一个启动的实例进入运行状态,其他实例的启动状态没有被监控。

报错信息

{
    "errorMessage": "local variable 'each_scheduled_instance' referenced before assignment",
    "errorType": "UnboundLocalError",
    "requestId": "3054209f-5cf7-429e-bcc7-7109a3b28a29",
    "stackTrace": [
        "  File \"/var/task/lambda_function.py\", line 19, in lambda_handler\n    return dealwithec2instances(event)\n",
        "  File \"/var/task/lambda_function.py\", line 25, in dealwithec2instances\n    return ec2_instances_start(event)\n",
        "  File \"/var/task/lambda_function.py\", line 40, in ec2_instances_start\n    each_scheduled_instance.wait_until_running()\n"
    ]
}

原代码

import boto3
import logging
import os
from pprint import pprint

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    varbotname = event['bot']['name']
    logger.info('bot name is ' +str(varbotname))
    return dealwithec2instances(event)

def dealwithec2instances(event):
    print('in dealwithec2instances')
    intentname = event['currentIntent']['name']
    if intentname == 'StartInstances':
        return ec2_instances_start(event)

def ec2_instances_start(event):
    print('in ec2 instances method')
    aws_mgmt_console = boto3.session.Session()
    ec2_console_resource = aws_mgmt_console.resource('ec2')
    ec2_console_client = aws_mgmt_console.client('ec2')

    waiter=ec2_console_client.get_waiter('instance_running')

    for each_scheduled_instance in  ec2_console_resource.instances.all():
        each_scheduled_instance.start()
    
    each_scheduled_instance.wait_until_running()    

    return 'success'

修复方案

方案一:逐个实例等待启动(资源API方式)

先检查是否存在实例,再逐个启动并等待:

import boto3
import logging
import os
from pprint import pprint

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    varbotname = event['bot']['name']
    logger.info('bot name is ' +str(varbotname))
    return dealwithec2instances(event)

def dealwithec2instances(event):
    print('in dealwithec2instances')
    intentname = event['currentIntent']['name']
    if intentname == 'StartInstances':
        return ec2_instances_start(event)

def ec2_instances_start(event):
    print('in ec2 instances method')
    aws_mgmt_console = boto3.session.Session()
    ec2_console_resource = aws_mgmt_console.resource('ec2')

    # 获取所有实例并转换为列表,方便检查是否为空
    instances = list(ec2_console_resource.instances.all())
    
    if not instances:
        logger.info("No EC2 instances found to start")
        return 'no_instances_found'

    # 逐个启动并等待实例进入运行状态
    for each_instance in instances:
        each_instance.start()
        each_instance.wait_until_running()    

    return 'success'

方案二:批量等待实例启动(客户端API方式,效率更高)

使用EC2客户端的waiter批量监控所有实例状态,适合大量实例场景:

import boto3
import logging
import os
from pprint import pprint

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    varbotname = event['bot']['name']
    logger.info('bot name is ' +str(varbotname))
    return dealwithec2instances(event)

def dealwithec2instances(event):
    print('in dealwithec2instances')
    intentname = event['currentIntent']['name']
    if intentname == 'StartInstances':
        return ec2_instances_start(event)

def ec2_instances_start(event):
    print('in ec2 instances method')
    aws_mgmt_console = boto3.session.Session()
    ec2_console_client = aws_mgmt_console.client('ec2')

    # 收集所有实例ID
    instance_ids = []
    response = ec2_console_client.describe_instances()
    for reservation in response['Reservations']:
        for instance in reservation['Instances']:
            instance_ids.append(instance['InstanceId'])
    
    if not instance_ids:
        logger.info("No EC2 instances found to start")
        return 'no_instances_found'

    # 批量启动实例
    ec2_console_client.start_instances(InstanceIds=instance_ids)
    
    # 使用waiter等待所有实例进入运行状态
    waiter = ec2_console_client.get_waiter('instance_running')
    waiter.wait(InstanceIds=instance_ids)

    return 'success'

修改说明

  • 新增实例存在性检查,避免无实例时变量未定义的错误
  • 方案一保持资源API的简洁性,适合少量实例;方案二用客户端API批量操作,效率更高
  • 确保所有启动的实例都被监控到运行状态,修复原逻辑只等待最后一个实例的缺陷

内容的提问来源于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 03:31:22