在主机之间生成和共享变量的 Ansible 剧本

Ansible playbook that generates and shares variable between hosts

我的 Ansible 剧本同时部署到数据库和网络服务器,我需要在它们之间使用一些共享变量。 from this 几乎满足了我的需求:

---
- hosts: all
  tasks:
  - set_fact: my_global_var='hello'

- hosts: db
  tasks:
  - debug: msg={{my_global_var}}

- hosts: web
  tasks:
  - debug: msg={{my_global_var}}

但是,在我的例子中,变量是一个密码,由剧本在每个 运行 上随机生成,然后必须共享:

---
- hosts: all
  tasks:
  - name: Generate new password
    shell: "tr -dc _[:alnum:] < /dev/urandom | head -c${1:-20}"
    register: new_password    
  - name: Set password as fact
    set_fact:
      my_global_var: "{{ new_password.stdout }}"

- hosts: db
  tasks:
  - debug: msg={{my_global_var}}

- hosts: web
  tasks:
  - debug: msg={{my_global_var}}

上面的例子不起作用,因为现在重新生成了密码,并且 all 主机中的每个主机的密码完全不同(除非您巧合地为您的数据库使用相同的 machine/hostname 和网络服务器)。

理想情况下,我不希望有人必须记住使用 --extra-vars 在命令行中传递一个好的随机密码,它应该由剧本生成和处理。

在 Ansible 中是否有任何建议的机制用于在剧本中创建变量并让该剧本中的所有主机都可以访问它?

您可能想尝试在本地主机上生成通行证,然后将其复制到所有其他主机:

---
- hosts: localhost
  tasks:
  - name: Generate new password
    shell: "tr -dc _[:alnum:] < /dev/urandom | head -c${1:-20}"
    register: new_password    

- hosts: all
  tasks:
  - name: Set password as fact
    set_fact:
      my_global_var: "{{ hostvars['localhost'].new_password.stdout }}"

- hosts: db
  tasks:
  - debug: msg={{my_global_var}}

- hosts: web
  tasks:
  - debug: msg={{my_global_var}}

我知道这是一个老问题,但我选择了一种替代方法,该方法结合了此处提供的两个答案和 this issue,通过使用隐式本地主机引用并在同一个游戏中完成所有操作。我 认为 它更优雅一些。测试 2.8.4.

这是我的上下文中的工作解决方案,我希望在我的所有主机上有一个带时间戳的通用备份目录,以供以后恢复:

---
tasks:
  - name: Set local fact for the universal backup string
    set_fact:
      thisHostTimestamp: "{{ ansible_date_time.iso8601 }}"
    delegate_to: localhost
    delegate_facts: true

  - name: Distribute backup datestring to all hosts in group
     set_fact:
       backupsTimeString: "{{ hostvars['localhost']['thisHostTimestamp'] }}"

我相信这应该像这样翻译成 OP 的原始示例,但我还没有测试过:

---
- hosts: all
  tasks:
  - name: Generate new password
    shell: "tr -dc _[:alnum:] < /dev/urandom | head -c${1:-20}"
    register: new_password  
    delegate_to: localhost
    delegate_facts: true

  - name: Set password as fact
    set_fact:
      my_global_var: "{{ hostvars['localhost'].new_password.stdout }}"