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

如何通过AWS Boto3 SSM客户端向超50台EC2实例批量执行命令?

解决SSM SendCommand超过50台实例的限制问题

问题原因

AWS SSM的send_command接口对Targets中InstanceIds的Values列表长度有严格限制,单批次最多支持50个实例ID,超过这个数量就会触发ValidationException错误。


方案一:分批处理实例ID

将收集到的实例ID按每50个一组拆分,循环调用send_command接口完成批量命令执行。同时修复原代码中实例ID收集的遍历错误(原代码未正确处理describe_instances返回的Reservations层级结构):

import boto3

# 初始化客户端
ec2_client = boto3.client('ec2')
ssm_client = boto3.client('ssm')

# 正确获取运行中的EC2实例ID,支持分页处理大量实例
def get_running_instance_ids():
    instance_ids = []
    paginator = ec2_client.get_paginator('describe_instances')
    # 筛选运行状态的实例
    for page in paginator.paginate(Filters=[{'Name': 'instance-state-name', 'Values': ['running']}]):
        for reservation in page['Reservations']:
            for instance in reservation['Instances']:
                instance_ids.append(instance['InstanceId'])
    return instance_ids

instance_ids = get_running_instance_ids()

# 按每批50个实例拆分执行
batch_size = 50
for i in range(0, len(instance_ids), batch_size):
    batch_instance_ids = instance_ids[i:i+batch_size]
    try:
        run_cmd_resp = ssm_client.send_command(
            Targets=[
                {"Key": "InstanceIds", "Values": batch_instance_ids},
            ],
            DocumentName="AWS-RunShellScript",
            DocumentVersion="1",
            Parameters={
                "commands": ["#!/bin/bash", "ls -ltrh", "# some commands"]
            }
        )
        print(f"批次 {i//batch_size +1} 命令发送成功,命令ID: {run_cmd_resp['Command']['CommandId']}")
    except Exception as e:
        print(f"批次 {i//batch_size +1} 执行失败: {str(e)}")

方案二:使用标签目标(更推荐)

如果你的EC2集群已统一配置标签(例如Cluster:Production),可以直接通过标签筛选目标实例,无需手动收集和拆分实例ID。SSM会自动处理超过50个实例的批量执行逻辑:

import boto3

ssm_client = boto3.client('ssm')

run_cmd_resp = ssm_client.send_command(
    Targets=[
        {"Key": "tag:Cluster", "Values": ["Production"]},
    ],
    DocumentName="AWS-RunShellScript",
    DocumentVersion="1",
    Parameters={
        "commands": ["#!/bin/bash", "ls -ltrh", "# some commands"]
    }
)

print(f"集群命令发送成功,命令ID: {run_cmd_resp['Command']['CommandId']}")

这种方式更适合动态变化的集群,无需维护实例ID列表,且管理更高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 18:45:26