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

boto3创建EFS挂载目标删除自定义Waiter提示不存在问题排查

错误根因
  1. 自定义waiter配置中的名称和调用时传入的名称不匹配:你在waiter_config里定义的waiter键为MountTargetDeleted,但传入create_waiter_with_client的waiter_name值为TargetDeleted,二者不一致导致boto3找不到对应waiter。
  2. 现有逻辑中,你创建完waiter实例后没有调用wait()方法执行等待操作,waiter没有实际生效。
  3. 原acceptor规则未覆盖挂载目标全部删除后MountTargets列表为空的场景,会导致waiter永远等不到success状态。
  4. 删除挂载目标后直接调用EFS删除接口,没有等待异步删除完成,逻辑和你的设计预期不符。
修复后代码
import boto3
from botocore.waiter import WaiterModel
from botocore.waiter import create_waiter_with_client

client = boto3.client('efs')
# 修正waiter名称和配置中一致
waiter_name = "MountTargetDeleted"
waiter_config = {
    "version": 2,
    "waiters": {
            "MountTargetDeleted": {
                  "delay": 30,
                  "operation": "DescribeMountTargets",
                  "maxAttempts": 90,
                  "acceptors": [
                    # 新增:挂载目标列表为空说明全部删除完成
                    {
                      "expected": True,
                      "matcher": "path",
                      "state": "success",
                      "argument": "length(MountTargets) == `0`"
                    },
                    {
                      "expected": "deleted",
                      "matcher": "pathAll",
                      "state": "success",
                      "argument": "MountTargets[].LifeCycleState"
                    },
                    {
                      "expected": "updating",
                      "matcher": "pathAny",
                      "state": "failure",
                      "argument": "MountTargets[].LifeCycleState"
                    },
                    {
                      "expected": "creating",
                      "matcher": "pathAny",
                      "state": "failure",
                      "argument": "MountTargets[].LifeCycleState"
                    }
                  ]
            }
        }

}
# 提前初始化waiter,无需在循环内重复创建
waiter_model = WaiterModel(waiter_config)
mount_target_deleted_waiter = create_waiter_with_client(waiter_name, waiter_model, client)

def lambda_handler(event, context):
    response = client.describe_file_systems()
    fs_list = response['FileSystems']
    
    for fs_details in fs_list:
        fid = fs_details['FileSystemId']
        tag_response = client.describe_tags(FileSystemId=fid)
        all_tags = tag_response['Tags']
        
        if {'Key': 'Retain', 'Value': 'True'} not in all_tags:
            # 先查是否有挂载目标,避免先删EFS报错
            mount_targets_resp = client.describe_mount_targets(FileSystemId=fid)
            mount_targets = mount_targets_resp['MountTargets']
            # 先删所有挂载目标
            for mt in mount_targets:
                client.delete_mount_target(MountTargetId=mt['MountTargetId'])
            # 等待所有挂载目标删除完成
            if mount_targets:
                mount_target_deleted_waiter.wait(FileSystemId=fid)
            # 再删EFS
            try:
                client.delete_file_system(FileSystemId=fid)
                print(f"文件系统 {fid} 已删除")
            except Exception as e:
                print(f"删除文件系统 {fid} 失败: {str(e)}")
        else:
            print(f"文件系统 {fid} 设置了Retain=True标签,跳过删除")
额外优化说明
  • 将waiter初始化移到handler外,避免每次函数执行/循环内重复创建实例,减少不必要开销
  • 调整了异常处理逻辑,先检查挂载目标再执行删除,避免无意义的异常捕获
  • 把原来的pathAll失败匹配改成pathAny,只要有一个挂载目标处于异常状态就终止等待,符合实际场景预期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:24:04