所有主机的全局 Ansible 增量变量

Nas*_*asr 5 ansible

我的库存中有两台服务器(主机)

[server]
10.23.12.33
10.23.12.40
Run Code Online (Sandbox Code Playgroud)

和剧本(play.yml)

---
- hosts: all
  roles:
    web
Run Code Online (Sandbox Code Playgroud)

在 vars 目录中的 web 角色内部,我有 main.yml

---
file_number : 0
Run Code Online (Sandbox Code Playgroud)

在任务目录中的 web 角色内部我有 main.yml

---
- name: Increment variable
  set_fact: file_number={{ file_number | int + 1 }}

- name: create file
  command: 'touch file{{ file_number }}'
Run Code Online (Sandbox Code Playgroud)

现在我希望在第一台机器上我会有file1而在第二台机器上我会有file2但在两台机器上我都有文件1

所以这个变量对于每台机器都是本地的,我怎么能让它对所有机器都是全局的。

我的文件结构是:

hosts
play.yml
roles/
  web/
    tasks/
      main.yml
    vars/
      main.yml
Run Code Online (Sandbox Code Playgroud)

Bru*_*e P 5

现在我希望在第一台机器上我将有 file1,在第二台机器上我将有 file2,但在两台机器上我都有 file1

您需要记住,Ansible 中的变量不是全局的。变量(又名“事实”)唯一地应用于每个主机,因此主机 1 与主机 2file_number不同。file_number这是一个大致基于您发布的内容的示例:

角色/测试/vars/main.yml:

---
file_number: 0
Run Code Online (Sandbox Code Playgroud)

角色/测试/任务/main.yml:

---
- name: Increment variable
  set_fact: file_number={{ file_number | int + 1 }}

- name: debug
  debug: msg="file_number is {{ file_number }} on host {{ inventory_hostname }}"
Run Code Online (Sandbox Code Playgroud)

现在假设您只定义了两个主机,并且您在如下所示的剧本中多次运行此角色:

---
- hosts: all
  roles:
    - { role: test }

- hosts: host1
  roles:
    - { role: test }

- hosts: all
  roles:
    - { role: test }
Run Code Online (Sandbox Code Playgroud)

因此,在第一个角色中,该角色适用于主机 1 和主机 2。在第二个游戏中,它仅针对主机 1 运行,而在第三个游戏中,它再次针对主机 1 和主机 2 运行。该剧本的输出是:

PLAY [all] ********************************************************************

TASK: [test | Increment variable] *********************************************
ok: [host1]
ok: [host2]

TASK: [test | debug] **********************************************************
ok: [host1] => {
    "msg": "file_number is 1 on host host1"
}
ok: [host2] => {
    "msg": "file_number is 1 on host host2"
}

PLAY [host1] **************************************************

TASK: [test | Increment variable] *********************************************
ok: [host1]

TASK: [test | debug] **********************************************************
ok: [host1] => {
    "msg": "file_number is 2 on host host1"
}

PLAY [all] ********************************************************************

TASK: [test | Increment variable] *********************************************
ok: [host1]
ok: [host2]

TASK: [test | debug] **********************************************************
ok: [host1] => {
    "msg": "file_number is 3 on host host1"
}
ok: [host2] => {
    "msg": "file_number is 2 on host host2"
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,host1 和 host2 的 值file_number是不同的,因为增加该值的角色在 host1 上运行的次数比在 host2 上运行的次数多。

不幸的是,确实没有一种干净的方法global在 Ansible 中创建变量。Ansible 能够针对大量主机并行运行任务,这使得此类事情变得非常棘手。除非您对并行环境中的全局变量非常小心,否则您很容易触发竞争条件,这可能会导致不可预测(不一致)的结果。


Nas*_*asr 5

尽管我使用 shell 为所有主机创建全局变量,但我还没有找到 ansible 的解决方案。

  1. 在本地主机的 /tmp 中创建临时文件并将起始计数放入其中
  2. 读取每个主机的文件并增加文件内的数字

我创建了该文件并在剧本中对其进行了初始化(play.yml)

- name: Manage localhost working area
  hosts: 127.0.0.1
  connection: local
  tasks:
    - name: Create localhost tmp file
      file: path={{ item.path }} state={{ item.state }}
      with_items:
       - { path: '/tmp/file_num', state: 'absent' }
       - { path: '/tmp/file_num', state: 'touch' }

    - name: Managing tmp files
      lineinfile: dest=/tmp/file_num line='0'
Run Code Online (Sandbox Code Playgroud)

然后在 main.tml 任务的 Web 角色中,我读取该文件并递增它。

- name: Get file number
  local_action: shell file=$((`cat /tmp/file_num` + 1)); echo $file | tee /tmp/file_num
  register: file_num

- name: Set file name
  command: 'touch file{{ file_num.stdout }}'
Run Code Online (Sandbox Code Playgroud)

现在我有第一个主机文件 1和第二个主机文件 2