2015-12-13 20 views
3

我有兩臺服務器(主機)Ansible增加全球變量在我的清單中的所有主機

[server] 
10.23.12.33 
10.23.12.40 

和劇本(play.yml)

--- 
- hosts: all 
    roles: 
    web 

裏面瓦爾目錄Web角色,我有主.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 }}' 

現在我希望在第一臺機器,我將有文件1和第二臺機器,我將有文件2但在這兩種機器我有文件1

所以這個變量是本地爲每臺機器,我怎麼能使它成爲全球所有機器。

我的文件結構是:

hosts 
play.yml 
roles/ 
    web/ 
    tasks/ 
     main.yml 
    vars/ 
     main.yml 
+0

這是一個全局變量,但Ansible只評估'file_number'上一次'set_fact'任務,所以無論您運行多少個節點,它都只能設置爲'1'。你能解釋你的用例稍寬嗎?這可能是有更好的方式來做你想做的事情(看起來你想在所有主機上有一個唯一的文件名)? – ydaetskcoR

+0

@ydaetskcoR我正在做的是改變文件中的配置行,在第一臺機器中它將具有'用戶名= client1',而在第二臺機器中它將具有'用戶名=客戶機2'等所有主機。因此我需要爲每臺機器增加變量。 – Nasr

+1

但是您不知道該任務的運行順序。每次運行的主機順序可能不同。除非我錯過了關於你的用例的東西,否則你可能會更好地將它指定爲主變量 – ydaetskcoR

回答

1

我還沒有找到解決方案,雖然我使用shell爲所有主機制作全局變量。

  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' 

然後在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 }}' 

現在我在第一臺主機文件1和第二主機文件2

1

現在我希望在第一臺機器,我將有file1和在第二臺機器,我將有文件2,但在這兩種機器我有文件1

你需要記住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 & host2。在第二場比賽中,它僅對host1運行,在第三場比賽中,它再次針對host1 & host2運行。這個劇本的輸出是:

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值是因爲這增加值撞上了主機1次的確要比主機2的作用host1和host2不同。

不幸的是,Ansible中並沒有一個乾淨的方法來製作變量global。 Ansible與大量主機並行運行任務的能力的全部性質使得這一點非常棘手。除非在並行環境中對全局變量非常小心,否則很容易觸發race condition,這可能會導致不可預知(不一致)的結果。

0

您可以使用馬特·馬茨的解決方案從here。基本上,你的任務是這樣的:

- name: Set file name command: 'touch file{{ play_hosts.server.index(inventory_hostname) }}'

而且你可以刪除所有的代碼維護全局變量和外部文件: