如何在 ansible playbook 中将变量从上一个主机传递到下一个目标主机

如何在 ansible playbook 中将变量从上一个主机传递到下一个目标主机

我想将名为 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

相关内容