如何通过Ansible将本地证书复制到VMware ESXi OOB服务器?
问题描述
我有一个用于为VMware ESXi主机生成证书的Ansible角色,证书在本地生成后需要复制到每台服务器的OOB主机。目前用的Ansible代码能运行但不规范:
- name: Copy new certificate and key to Server shell: | sshpass -p "{{esxi_password}}" scp -o 'StrictHostKeyChecking no' root@"{{ESXI_OOBHOST}}" 'mv /etc/vmware/ssl/my.key /etc/vmware/ssl/"$(date +"%d-%m-%Y")"_my.key' sshpass -p "{{esxi_password}}" scp -o 'StrictHostKeyChecking no' root@"{{ESXI_OOBHOST}}" 'mv /etc/vmware/ssl/my.crt /etc/vmware/ssl/"$(date +"%d-%m-%Y")"_my.crt' sshpass -p "{{esxi_password}}" scp -o 'StrictHostKeyChecking no' -r ./certs/my.crt root@"{{ESXI_OOBHOST}}":/etc/vmware/ssl/my.crt sshpass -p "{{esxi_password}}" scp -o 'StrictHostKeyChecking no' -r ./certs/my.key root@"{{ESXI_OOBHOST}}":/etc/vmware/ssl/my.key sshpass -p "{{esxi_password}}" scp -o 'StrictHostKeyChecking no' root@"{{ESXI_OOBHOST}}" 'services.sh restart' delegate_to: localhost register: files_list no_log: true
我尝试用delegate_to: "{{ESXI_OOBHOST}}"调用copy模块但无效,原因是本地SSH密钥未添加到OOB主机,且任务在GitLab Runner上执行,无法添加密钥:
- ansible.builtin.copy: src: ./certs/my.key dest: /etc/vmware/ssl/my.key owner: root group: root mode: 0775 backup: yes delegate_to: "{{ESXI_OOBHOST}}"
请问有没有合适的Ansible模块可以实现从本地向VMware主机复制文件?
解决方案
方法1:利用Ansible连接变量配合copy模块
既然无法使用密钥认证,你可以在任务中直接指定SSH密码和跳过主机密钥检查的参数,让copy模块通过密码认证连接到OOB主机,无需delegate_to到localhost:
- name: Backup and copy certificate files to ESXi OOB host ansible.builtin.copy: src: "./certs/{{ item.src }}" dest: "/etc/vmware/ssl/{{ item.dest }}" owner: root group: root mode: '0600' # 证书和密钥用更严格的权限更安全 backup: yes # Ansible会自动以时间戳命名备份文件,替代手动mv操作 loop: - { src: "my.crt", dest: "my.crt" } - { src: "my.key", dest: "my.key" } vars: ansible_ssh_user: root ansible_ssh_pass: "{{ esxi_password }}" ansible_ssh_common_args: "-o StrictHostKeyChecking=no" no_log: true
方法2:用command模块替代shell做规范的单步操作
如果需要通过localhost中转,可拆分原shell命令为独立的command任务,更符合Ansible最佳实践:
# 备份原有证书 - name: Backup existing my.key on ESXi OOB host ansible.builtin.command: cmd: sshpass -p "{{ esxi_password }}" ssh -o StrictHostKeyChecking=no root@{{ ESXI_OOBHOST }} "mv /etc/vmware/ssl/my.key /etc/vmware/ssl/$(date +'%d-%m-%Y')_my.key" delegate_to: localhost no_log: true - name: Backup existing my.crt on ESXi OOB host ansible.builtin.command: cmd: sshpass -p "{{ esxi_password }}" ssh -o StrictHostKeyChecking=no root@{{ ESXI_OOBHOST }} "mv /etc/vmware/ssl/my.crt /etc/vmware/ssl/$(date +'%d-%m-%Y')_my.crt" delegate_to: localhost no_log: true # 复制新证书 - name: Copy new my.crt to ESXi OOB host ansible.builtin.command: cmd: sshpass -p "{{ esxi_password }}" scp -o StrictHostKeyChecking=no ./certs/my.crt root@{{ ESXI_OOBHOST }}:/etc/vmware/ssl/my.crt delegate_to: localhost no_log: true - name: Copy new my.key to ESXi OOB host ansible.builtin.command: cmd: sshpass -p "{{ esxi_password }}" scp -o StrictHostKeyChecking=no ./certs/my.key root@{{ ESXI_OOBHOST }}:/etc/vmware/ssl/my.key delegate_to: localhost no_log: true # 重启服务 - name: Restart ESXi services ansible.builtin.command: cmd: sshpass -p "{{ esxi_password }}" ssh -o StrictHostKeyChecking=no root@{{ ESXI_OOBHOST }} "services.sh restart" delegate_to: localhost no_log: true
方法3:使用community.general.sshpass连接插件
如果你的环境安装了community.general集合,可以直接使用sshpass连接插件,无需在任务里写sshpass命令,更简洁:
首先确保安装集合:
ansible-galaxy collection install community.general
然后在任务中指定连接方式:
- name: Backup and copy certificate files to ESXi OOB host ansible.builtin.copy: src: "./certs/{{ item.src }}" dest: "/etc/vmware/ssl/{{ item.dest }}" owner: root group: root mode: '0600' backup: yes loop: - { src: "my.crt", dest: "my.crt" } - { src: "my.key", dest: "my.key" } vars: ansible_connection: community.general.sshpass ansible_ssh_user: root ansible_ssh_pass: "{{ esxi_password }}" ansible_ssh_common_args: "-o StrictHostKeyChecking=no" no_log: true
注意事项
- 证书和密钥文件建议设置
0600权限,比0775更安全,避免非授权访问 backup: yes参数会让Ansible自动备份原有文件,文件名格式为原文件名.时间戳,可替代手动写的mv命令no_log: true必须保留,避免密码泄露到日志中
内容的提问来源于stack exchange,提问作者devopstechy
相关产品推荐
相关产品推荐

