我想将名为 ssh_user 的变量从 ansible playbook 上的第一个 play 传递到下一个不同的主机 play。我尝试使用“set_fact”,但似乎仍然无法从上一个 play 中检索变量。
以下是我的 ansible playbook 代码:
- hosts: localhost
vars_prompt:
- name: target_host
prompt: Target Host IP
private: false
- name: auth_method
prompt: Authentication method (password/key)
private: false
vars:
ssh_user: "{{ ssh_user_out.user_input }}"
ssh_pass: "{{ ssh_pass_out.user_input }}"
ssh_keypath: "{{ ssh_keypath_out.user_input }}"
tasks:
- block:
- pause:
prompt: SSH Username
register: ssh_user_out
- pause:
prompt: SSH Password
echo: false
register: ssh_pass_out
- set_fact:
ssh_user: "{{ ssh_user }}"
ssh_pass: "{{ ssh_pass }}"
when: auth_method == 'password'
- block:
- pause:
prompt: SSH Username
register: ssh_user_out
- pause:
prompt: Private Key Path
register: ssh_keypath_out
- set_fact:
ssh_user: "{{ ssh_user }}"
ssh_keypath: "{{ ssh_keypath }}"
when: auth_method == 'key'
- add_host:
name: "{{ target_host }}"
groups: dynamically_created_hosts
- name: Download files from FTP on target host
hosts: dynamically_created_hosts
tasks:
- name: set the facts per host
set_fact:
ssh_user: "{{hostvars['localhost']['ssh_user']}}"
ssh_pass: "{{hostvars['localhost']['ssh_pass']}}"
ssh_keypath: "{{hostvars['localhost']['ssh_keypath']}}"
gather_facts: false
remote_user: "{{ ssh_user }}"
become: true
become_user: root
become_method: sudo
tasks:
- name: Create upgrade directory if not exist
file:
path: /root/upgrade
state: directory
- name: Download file from FTP
get_url:
url: "ftp://something.com/{{ file_path }}"
dest: "/root/upgrade/{{ file_path }}"
force: yes
timeout: 30
remote_src: yes
validate_certs: false
url_username: "{{ ftp_username }}"
url_password: "{{ ftp_password }}"
register: download_result
ignore_errors: true
- name: Check if file downloaded successfully
debug:
msg: "File '{{ file_path }}' downloaded successfully."
when: download_result is success
- name: Display error message if file download failed
debug:
msg: "Failed to download file '{{ file_path }}'. Please check the file path or FTP credentials."
when: download_result is failed and file_path != 'q'
- name: Exit playbook if 'q' is pressed
meta: end_play
when: file_path == 'q'
以下是错误:
WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: While constructing a mapping from /Related/ansible/upgrade/upgrade.yml, line 50, column 3, found a duplicate
dict key (tasks). Using last defined value only.
Target Host IP: 192.168.10.1
Authentication method (password/key): password
PLAY [localhost] *******************************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************************
ok: [localhost]
TASK [pause] ***********************************************************************************************************************************************
[pause]
SSH Username:
ok: [localhost]
TASK [pause] ***********************************************************************************************************************************************
[pause]
SSH Password (output is hidden):
ok: [localhost]
TASK [set_fact] ********************************************************************************************************************************************
ok: [localhost]
TASK [pause] ***********************************************************************************************************************************************
skipping: [localhost]
TASK [pause] ***********************************************************************************************************************************************
skipping: [localhost]
TASK [set_fact] ********************************************************************************************************************************************
skipping: [localhost]
TASK [add_host] ********************************************************************************************************************************************
changed: [localhost]
PLAY [Download files from FTP on target host] **************************************************************************************************************
TASK [Create upgrade directory if not exist] ***************************************************************************************************************
fatal: [192.168.10.1]: FAILED! => {"msg": "The field 'remote_user' has an invalid value, which includes an undefined variable. The error was: 'ssh_user' is undefined. 'ssh_user' is undefined. 'ssh_user' is undefined. 'ssh_user' is undefined"}
PLAY RECAP *************************************************************************************************************************************************
192.168.10.1 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
localhost : ok=5 changed=1 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
如您所见,即使在我尝试使用 set_fact 和 hostvars 从之前的播放中调用 vars 之后,它仍然显示“ {“msg”:“字段'remote_user'具有无效值,其中包括未定义的变量。错误为:'ssh_user'未定义。'ssh_user'未定义。'ssh_user'未定义。'ssh_user'未定义”}”
对于类似的情况,我尝试了几种方法,但目前都没有效果。
感谢你的帮助!
答案1
添加主机时声明变量。参见第一个例子。 例如,
- add_host:
name: "{{ target_host }}"
groups: dynamically_created_hosts
ssh_user: "{{ ssh_user|d('UNDEF') }}"
ssh_pass: "{{ ssh_pass|d('UNDEF') }}"
ssh_keypath: "{{ ssh_keypath|d('UNDEF') }}"
放默认值,因为某些变量未定义。
- 完整测试剧本的示例
shell> cat pb.yml
- hosts: localhost
vars_prompt:
- name: target_host
prompt: Target Host IP
private: false
- name: auth_method
prompt: Authentication method (password/key)
private: false
vars:
ssh_user: "{{ ssh_user_out.user_input }}"
ssh_pass: "{{ ssh_pass_out.user_input }}"
tasks:
- block:
- pause:
prompt: SSH Username
register: ssh_user_out
- pause:
prompt: SSH Password
echo: false
register: ssh_pass_out
when: auth_method == 'password'
- add_host:
name: "{{ target_host }}"
groups: dynamically_created_hosts
ssh_user: "{{ ssh_user|d('UNDEF') }}"
ssh_pass: "{{ ssh_pass|d('UNDEF') }}"
ssh_keypath: "{{ ssh_keypath|d('UNDEF') }}"
- hosts: dynamically_created_hosts
tasks:
- debug:
msg: |
ssh_user: {{ ssh_user }}
ssh_pass: {{ ssh_pass }}
ssh_keypath: {{ ssh_keypath }}
给出
shell> ansible-playbook pb.yml
Target Host IP: 10.1.0.10
Authentication method (password/key): password
PLAY [localhost] ******************************************************************************
TASK [pause] **********************************************************************************
[pause]
SSH Username:
admin^Mok: [localhost]
TASK [pause] **********************************************************************************
[pause]
SSH Password (output is hidden):
ok: [localhost]
TASK [add_host] *******************************************************************************
changed: [localhost]
PLAY [dynamically_created_hosts] **************************************************************
TASK [debug] **********************************************************************************
ok: [10.1.0.10] =>
msg: |-
ssh_user: admin
ssh_pass: 1234
ssh_keypath: UNDEF
PLAY RECAP ************************************************************************************
10.1.0.10: ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost: ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
- 使用设置事实将变量放入主机变量。例如,下面的剧本也可以完成这项工作
shell> cat pb.yml
- hosts: localhost
vars_prompt:
- name: target_host
prompt: Target Host IP
private: false
- name: auth_method
prompt: Authentication method (password/key)
private: false
tasks:
- block:
- pause:
prompt: SSH Username
register: ssh_user_out
- pause:
prompt: SSH Password
echo: false
register: ssh_pass_out
- set_fact:
ssh_user: "{{ ssh_user_out.user_input }}"
ssh_pass: "{{ ssh_pass_out.user_input }}"
when: auth_method == 'password'
- add_host:
name: "{{ target_host }}"
groups: dynamically_created_hosts
- hosts: dynamically_created_hosts
vars:
ssh_user: "{{ hostvars.localhost.ssh_user|d('UNDEF') }}"
ssh_pass: "{{ hostvars.localhost.ssh_pass|d('UNDEF') }}"
ssh_keypath: "{{ hostvars.localhost.ssh_keypath|d('UNDEF') }}"
tasks:
- debug:
msg: |
ssh_user: {{ ssh_user }}
ssh_pass: {{ ssh_pass }}
ssh_keypath: {{ ssh_keypath }}
给出
shell> ansible-playbook pb.yml
Target Host IP: 10.1.0.10
Authentication method (password/key): password
PLAY [localhost] ******************************************************************************
TASK [pause] **********************************************************************************
[pause]
SSH Username:
admin^Mok: [localhost]
TASK [pause] **********************************************************************************
[pause]
SSH Password (output is hidden):
ok: [localhost]
TASK [set_fact] *******************************************************************************
ok: [localhost]
TASK [add_host] *******************************************************************************
changed: [localhost]
PLAY [dynamically_created_hosts] **************************************************************
TASK [debug] **********************************************************************************
ok: [10.1.0.10] =>
msg: |-
ssh_user: admin
ssh_pass: 1234
ssh_keypath: UNDEF
PLAY RECAP ************************************************************************************
10.1.0.10: ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost: ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0