如何让调用AWS SSM命令的Ansible任务在底层Powershell脚本失败时触发失败
问题根源
你当前的配置错误核心是:aws ssm send-command是异步提交命令的接口,命令行返回码rc仅代表「向AWS SSM服务提交命令请求」是否成功,和远端Windows主机上PowerShell脚本的执行结果完全无关。哪怕远端脚本执行失败,只要请求提交成功,aws cli的返回码始终是0,所以你原来的failed_when判断逻辑完全不生效。
正确实现方案
你需要新增两个后续任务:1. 轮询SSM命令的执行状态直到完成;2. 校验所有目标实例的脚本执行返回码,判定任务是否失败。
步骤1:调整原有提交命令的任务,提取命令ID
- name: 提交SSM命令 shell: | aws ssm send-command \ --document-name "AWS-RunPowerShellScript" \ --document-version "1" \ --targets "Key=instanceids,Values={{ instances | join(',') }}" \ --parameters '{{ parameters | to_json | safe }}' \ --timeout-seconds 300 \ --max-concurrency "50" \ --max-errors "0" \ --output json vars: <passing variables> register: ssm_submit_result # 这里仅判断提交请求是否失败 failed_when: ssm_submit_result.rc != 0 - name: 提取SSM命令ID set_fact: ssm_command_id: "{{ ssm_submit_result.stdout | from_json | json_query('Command.CommandId') }}"
步骤2:轮询等待SSM命令执行完成
- name: 等待SSM命令执行完成 shell: | aws ssm list-command-invocations \ --command-id {{ ssm_command_id }} \ --details \ --output json register: ssm_exec_result retries: 60 delay: 5 until: > (ssm_exec_result.stdout | from_json | json_query('CommandInvocations[].Status') | unique) | difference(['Success', 'Failed', 'TimedOut', 'Cancelled']) | length == 0 failed_when: ssm_exec_result.rc != 0
步骤3:校验执行结果,判定任务失败条件
- name: 校验SSM命令执行结果 vars: exec_details: "{{ ssm_exec_result.stdout | from_json | json_query('CommandInvocations[]') }}" debug: msg: "实例{{ item.InstanceId }}执行失败,错误输出:{{ item.StandardErrorContent }}" loop: "{{ exec_details }}" # 满足以下任意条件即判定任务失败:1. 命令状态非Success;2. PowerShell返回码非0 failed_when: item.Status != 'Success' or item.CommandPlugins[0].ResponseCode != 0
配套PowerShell脚本注意事项
需要在你的PowerShell脚本开头加以下配置,确保脚本出错时会正确返回非0退出码:
$ErrorActionPreference = 'Stop' # 脚本任意位置出错时直接退出并返回非0码 trap { Write-Error $_ exit 1 }
内容的提问来源于stack exchange,提问作者Sachin Deshmukh
相关产品推荐
相关产品推荐

