使用boto3创建SSM文档实现微服务及关联EC2实例并行关停
基于父YAML配置批量生成子SSM文档+自动化关停实现方案
核心实现思路
整体分4个环节落地,完全匹配单实例、多实例两层并行关停要求:
- 解析父配置提取全量微服务清单
- 基于通用模板批量生成对应子SSM文档
- 编排两层并行执行逻辑
- 增加状态校验保障关停顺序正确
步骤1:解析父配置提取服务清单
用Python脚本对接boto3操作AWS资源,首先通过PyYAML加载父配置文件,遍历sequence下所有分组的服务项,去重后得到全量需要生成对应关停文档的微服务列表。统一子文档命名规范为stop-service-<环境标识>-<服务名>,避免跨环境、跨服务文档重名。
步骤2:定义子SSM文档通用模板
所有微服务的关停逻辑结构一致,仅需替换服务名即可,提前写好模板存为本地文件,模板核心逻辑包含服务关停、进程退出轮询校验两个部分,避免关停不彻底的问题,模板示例如下:
--- schemaVersion: "2.2" description: "Stop target micro service on running EC2 instance" parameters: ServiceName: type: String default: "{service_name}" description: "Name of the micro service to shut down" mainSteps: - action: "aws:runShellScript" name: "stopAndVerifyService" inputs: runCommand: - "set -e" - "echo Starting shutdown process for $ServiceName" - "systemctl stop $ServiceName || true" # 轮询等待进程完全退出,最长等待300秒 - "for i in {1..30}; do if ! pgrep -f $ServiceName > /dev/null; then echo $ServiceName stopped successfully; exit 0; fi; sleep 10; done" - "echo Timeout waiting for $ServiceName to exit; exit 1"
步骤3:批量生成并创建子SSM文档
遍历第一步提取的全量服务清单,将模板中的服务名占位符替换为实际服务名,调用SSM接口批量创建文档,增加重复校验逻辑避免同名文档重复创建报错,核心实现代码如下:
import yaml import boto3 # 加载父配置文件 with open("parent_shutdown_config.yaml", "r", encoding="utf-8") as f: parent_config = yaml.safe_load(f) env_flag = parent_config["fabric"] # 收集所有需要处理的微服务 all_services = set() for service_group in parent_config["sequence"].values(): all_services.update(service_group) # 初始化SSM客户端 ssm_client = boto3.client("ssm", region_name="us-east-1") # 加载文档模板 with open("ssm_stop_service_template.yaml", "r", encoding="utf-8") as f: doc_template = f.read() # 批量创建子SSM文档 for service in all_services: doc_name = f"stop-service-{env_flag}-{service}" # 检查文档是否已存在 try: ssm_client.get_document(Name=doc_name) print(f"[Skip] Document {doc_name} already exists") continue except ssm_client.exceptions.InvalidDocument: pass # 替换模板占位符生成实际文档内容 doc_content = doc_template.format(service_name=service) # 调用接口创建文档 ssm_client.create_document( Content=doc_content, Name=doc_name, DocumentType="Command", DocumentFormat="YAML", Tags=[ {"Key": "Environment", "Value": env_flag}, {"Key": "ServiceName", "Value": service}, {"Key": "Scenario", "Value": "auto-shutdown"} ] ) print(f"[Created] SSM document {doc_name}")
步骤4:编排两层并行关停逻辑
文档批量创建完成后,执行关停时按以下逻辑处理即可满足要求:
- 多实例维度并行:调用
send_command时直接传入同服务关联的所有EC2实例ID,SSM默认会在所有目标实例上并行执行命令,无需额外开发多实例调度逻辑。 - 单实例维度顺序控制:对单台实例,先并行下发该实例上所有微服务对应的子SSM关停命令,每10秒轮询一次所有命令的执行状态,等所有微服务关停命令全部返回成功后,再下发EC2实例本身的关停指令(可直接调用EC2 StopInstances接口,或通过SSM执行aws cli关停命令)。
注意事项:如果服务关停超时,要记录对应实例ID、服务名打告警,不要直接强制关停实例,避免数据损坏。
内容的提问来源于stack exchange,提问作者ajhowey
相关产品推荐
相关产品推荐

