如何通过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
相关产品推荐
相关产品推荐

