我的广告资源中有两台服务器(主机)
[server]
10.23.12.33
10.23.12.40
和playbook(play.yml)
---
- hosts: all
roles:
web
vars目录中的web角色我有main.yml
---
file_number : 0
任务目录中的内部Web角色我有main.yml
---
- name: Increment variable
set_fact: file_number={{ file_number | int + 1 }}
- name: create file
command: 'touch file{{ file_number }}'
现在我希望在第一台机器上我会有 file1 ,在第二台机器上我会有 file2 ,但在这两台机器上我都有 file1
所以这个变量对于每台机器来说都是本地的,我怎么能让它对所有机器都是全局的。
我的文件结构是:
hosts
play.yml
roles/
web/
tasks/
main.yml
vars/
main.yml
答案 0 :(得分:2)
现在我希望在第一台机器上我将拥有file1而在第二台机器中我将拥有file2但在两台机器中我都有file1
您需要记住,Ansible中的变量不是全局变量。变量(又名“事实”)唯一地应用于每个主机,因此host1的file_number
与host2的file_number
不同。这是一个基于你发布的内容的例子:
角色/测试/瓦尔/ main.yml:
---
file_number: 0
角色/测试/任务/ 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 }}"
现在假设您只定义了两个主机,并且您在一个看起来像这样的剧本中多次运行此角色:
---
- hosts: all
roles:
- { role: test }
- hosts: host1
roles:
- { role: test }
- hosts: all
roles:
- { role: test }
因此,在第一次播放中,角色适用于host1和amp;主机2。在第二场比赛中,它仅针对host1运行,而在第三场比赛中,它再次针对host1和amp;主机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"
}
正如您所看到的,file_number
的值对于host1和host2是不同的,因为增加值的角色对host1的运行次数比对host2的运行次数多。
不幸的是,Ansible中的变量global
确实没有干净的方法。 Ansible与大量主机并行运行任务的能力的全部性质使得这样的事情变得非常棘手。除非您在并行环境中非常小心全局变量,否则很容易触发race condition,这可能会导致不可预测(不一致)的结果。
答案 1 :(得分:2)
我还没有找到一个带有ansible的解决方案,尽管我已经开始使用shell为所有主机创建全局变量。
我创建了该文件并在playbook(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'
然后在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 }}'
现在我有第一个主机 file1 和第二个主机 file2
答案 2 :(得分:0)
您可以使用来自here的Matt Martz解决方案。基本上你的任务就像:
- name: Set file name
command: 'touch file{{ play_hosts.server.index(inventory_hostname) }}'
您可以删除所有用于维护全局变量和外部文件的代码:)