Ansible playbook修改自身连接密码触发校验报错问题咨询
问题根因
Ansible 会在每个play启动初始化阶段读取并缓存目标主机的所有连接参数,包含连接用的账号密码。执行过程中如果直接修改远端ansible连接账号的密码,当前play缓存的连接参数不会自动同步更新,后续任务、模块执行后的连接校验环节依然会用旧密码发起认证,必然触发连接报错。
解决方法
核心原则是修改ansible连接账号密码的任务必须放在对应主机组所有业务任务的最后,任务执行后主动刷新Ansible缓存的连接凭证,让后续校验、操作自动使用新密码,不需要拆分playbook或者手动修改inventory配置。
具体操作要点:
- 修改ansible账号密码的任务,要显式指定用旧密码发起当前任务的连接,保证改密操作本身能正常执行
- 改密任务执行成功后,通过
set_fact更新主机缓存中对应连接插件的密码变量为新值:Windows主机(WinRM连接)更新ansible_winrm_password,Linux主机(SSH连接)更新ansible_password、ansible_ssh_password - 凭证刷新后加一个轻量的连通性校验任务,直接验证新密码可用
- 原playbook中Linux段修改admin密码的任务存在语法错误:task层级不支持
hosts参数,改用when条件判断主机所属分组即可实现相同效果
修正后的完整playbook如下:
--- # 更新所有Windows系统本地账号 - hosts: windows gather_facts: yes ignore_errors: no vars: # 旧ansible连接密码从现有vars配置、inventory中读取即可,不需要硬编码 # old_ansible_win_pass: "Windows端原ansible账号密码" tasks: - name: 修改Windows Administrator账号密码 ansible.windows.win_user: name: administrator update_password: always password: "{{ new_win_admin_pass }}" - name: 修改Windows端ansible连接账号密码 vars: # 本任务执行阶段仍用旧密码建立连接 ansible_winrm_password: "{{ old_ansible_win_pass }}" ansible.windows.win_user: name: ansible update_password: always password: "{{ new_ansible_pass }}" register: win_ansible_pw_change - name: 刷新Windows主机连接凭证缓存 set_fact: ansible_password: "{{ new_ansible_pass }}" ansible_winrm_password: "{{ new_ansible_pass }}" when: win_ansible_pw_change is succeeded - name: 用新密码验证Windows主机连通性 ansible.windows.win_ping: # 更新所有Linux系统账号 - hosts: rhel become: yes gather_facts: yes ignore_errors: no vars: # 旧ansible连接密码从现有vars配置、inventory中读取即可,不需要硬编码 # old_ansible_linux_pass: "Linux端原ansible账号密码" tasks: - name: 修改RHEL工作站admin账号密码 ansible.builtin.user: name: admin update_password: always password: "{{ new_admin_pass | password_hash('sha512') }}" when: inventory_hostname in groups['rhel_workstations'] - name: 修改Linux root账号密码 ansible.builtin.user: name: root update_password: always password: "{{ new_root_pass | password_hash('sha512') }}" - name: 修改Linux端ansible连接账号密码 vars: # 本任务执行阶段仍用旧密码建立连接 ansible_password: "{{ old_ansible_linux_pass }}" ansible_ssh_password: "{{ old_ansible_linux_pass }}" ansible.builtin.user: name: ansible update_password: always password: "{{ new_ansible_pw_var | password_hash('sha512') }}" register: linux_ansible_pw_change - name: 刷新Linux主机连接凭证缓存 set_fact: ansible_password: "{{ new_ansible_pw_var }}" ansible_ssh_password: "{{ new_ansible_pw_var }}" when: linux_ansible_pw_change is succeeded - name: 用新密码验证Linux主机连通性 ansible.builtin.ping:
注意事项
- 所有新密码变量建议用
ansible-vault加密存储,不要明文写在playbook里 - 如果环境是用SSH密钥做ansible连接认证,不存在这个问题,不需要做凭证刷新操作
- 不要在ansible连接账号改密、凭证刷新步骤之后加其他需要远端执行的配置修改任务,避免新密码认证异常导致配置回滚困难
内容的提问来源于stack exchange,提问作者Kevin Bittner
相关产品推荐
相关产品推荐

