You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

主机名非静态时,跨组复用Ansible主机变量的问题

解决Ansible多Play切换主机后变量丢失的备份上传问题

你遇到的是Ansible的核心特性:变量与主机绑定,跨Play切换主机后,原主机的变量无法直接访问。针对批量处理Palo防火墙备份并上传到Azure Blob的需求,以下是几种可行的解决思路:

方案1:用add_host收集备份信息到临时组

在第一个Play中,将每台防火墙的备份文件路径、目标Blob路径等信息添加到一个临时主机组,第二个Play遍历这个组的信息完成批量上传。

修改第一个Play的任务:

- name: Pull configuration backups from Palo firewalls
  hosts: groupName
  gather_facts: no
  tasks:
    # 原有备份任务...
    - name: Saving configuration file...
      connection: local
      check_mode: no
      ansible.builtin.copy:
        content: "{{ configuration_string['content'] }}"
        dest: '/etc/ansible/backups/{{ inventory_hostname }}/{{ inventory_hostname }}_{{ current_date }}.txt'
    # 添加临时组收集备份信息
    - name: Register backup details to temporary group
      ansible.builtin.add_host:
        name: "{{ inventory_hostname }}"
        groups: backup_hosts
        backup_src_path: '/etc/ansible/backups/{{ inventory_hostname }}/{{ inventory_hostname }}_{{ current_date }}.txt'
        blob_dest_path: '/{{ inventory_hostname }}/{{ inventory_hostname }}_{{ current_date }}.txt'

第二个Play遍历临时组的信息执行上传:

- name: Copy configuration from Ansible to Azure Blob...
  gather_facts: no
  pre_tasks:
    - include_vars: /etc/ansible/sftp_secrets.yml
  hosts: AzureBlobStorage
  tasks:
    - name: Copying files to Azure blob storage via SFTP...
      ansible.netcommon.net_put:
        src: "{{ hostvars[item].backup_src_path }}"
        protocol: sftp
        destination: "{{ hostvars[item].blob_dest_path }}"
      loop: "{{ groups['backup_hosts'] }}"

方案2:将备份信息存储到localhost的全局变量

在第一个Play中,把所有防火墙的备份信息收集到localhost的变量中,第二个Play直接读取这个变量循环上传。

修改第一个Play的任务:

- name: Pull configuration backups from Palo firewalls
  hosts: groupName
  gather_facts: no
  tasks:
    # 原有备份任务...
    - name: Saving configuration file...
      connection: local
      check_mode: no
      ansible.builtin.copy:
        content: "{{ configuration_string['content'] }}"
        dest: '/etc/ansible/backups/{{ inventory_hostname }}/{{ inventory_hostname }}_{{ current_date }}.txt'
    # 收集备份信息到localhost变量
    - name: Collect backup info to localhost
      ansible.builtin.set_fact:
        backup_list: "{{ backup_list | default([]) + [
          {'host': inventory_hostname, 'file': inventory_hostname ~ '_' ~ current_date}
        ] }}"
      delegate_to: localhost
      delegate_facts: true

第二个Play循环读取localhost的backup_list:

- name: Copy configuration from Ansible to Azure Blob...
  gather_facts: no
  pre_tasks:
    - include_vars: /etc/ansible/sftp_secrets.yml
  hosts: AzureBlobStorage
  tasks:
    - name: Copying files to Azure blob storage via SFTP...
      ansible.netcommon.net_put:
        src: "/etc/ansible/backups/{{ item.host }}/{{ item.file }}.txt"
        protocol: sftp
        destination: "/{{ item.host }}/{{ item.file }}.txt"
      loop: "{{ hostvars['localhost'].backup_list }}"

方案3:直接遍历备份目录(无需变量传递)

如果备份路径的命名规则固定(比如主机名作为子目录,文件名包含主机名和日期),可以直接在第二个Play中扫描备份目录,解析路径信息完成上传,无需传递变量。

修改第二个Play:

- name: Copy configuration from Ansible to Azure Blob...
  gather_facts: no
  pre_tasks:
    - include_vars: /etc/ansible/sftp_secrets.yml
  hosts: AzureBlobStorage
  tasks:
    # 扫描备份目录获取所有文件
    - name: Get all backup files
      ansible.builtin.find:
        path: "/etc/ansible/backups"
        recurse: yes
        patterns: "*.txt"
      delegate_to: localhost
      register: backup_files
    # 循环上传每个文件
    - name: Copying files to Azure blob storage via SFTP...
      ansible.netcommon.net_put:
        src: "{{ item.path }}"
        protocol: sftp
        # 从路径中解析主机名(倒数第二个目录)和文件名
        destination: "/{{ item.path.split('/')[-2] }}/{{ item.path.split('/')[-1] }}"
      loop: "{{ backup_files.files }}"

方案选型建议

  • 方案1/2适合需要传递额外上下文变量(比如备份备注、自定义路径规则)的场景,能保留更多备份相关信息。
  • 方案3适合备份路径规则固定、无需额外变量的情况,实现更简洁,不需要修改原有备份Play的逻辑。

内容的提问来源于stack exchange,提问作者Moridn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 16:35:52