2016-03-03 49 views
2

在我的Ansible手冊中,我在一臺服務器上設置了多個網站。每個網站都有一些配置在apps變量設置:在Ansible中,基於變量在循環中只運行一個項目

apps: 
    - name: 'app1' 
    git_repo: 'https://github.com/philgyford/app1.git' 
    - name: 'app2' 
    git_repo: 'https://github.com/philgyford/app2.git' 

然後某些任務在一個循環中運行每一個應用程序/網站:

- name: Set up git repos for apps 
    git: 
    repo: '{{ item.git_repo }}' 
    version: 'master' 
    dest: "/webapps/{{ item.name }}" 
    accept_hostkey: yes 
    with_items: apps 

這是所有罰款。但理想情況下,我希望能夠運行劇本並僅爲特定應用運行這些任務。

一種方法是在命令行中傳入--extra-vars "app=app1"。在劇本中,我會設置app的默認值false。然後在每一個應用程序相關的任務添加:

when: item.name == app or app == false 

這應該工作,但它似乎費力又容易出錯不得不說添加到每一個任務。有沒有更好的方法可以避免這麼多的重複?

回答

3

您可以用selectattr filter像這樣過濾列表:

apps | selectattr('name', 'match', app) 

除了你apps定義你可以有一個過濾列表,默認爲完整列表:

vars: 
    apps: 
    - name: 'app1' 
     git_repo: 'https://github.com/philgyford/app1.git' 
    - name: 'app2' 
     git_repo: 'https://github.com/philgyford/app2.git' 

    active_apps: "{{ apps if app is not defined else apps | selectattr('name', 'match', app) | list }}" 

然後在循環你可以循環使用active_apps而不需要進一步的條件。

- name: Set up git repos for apps 
    git: 
    repo: '{{ item.git_repo }}' 
    version: 'master' 
    dest: "/webapps/{{ item.name }}" 
    accept_hostkey: yes 
    with_items: active_apps 

selectattr中使用的過濾器match其實需要一個正則表達式。所以你可以提供非常詳細的表達式來處理應用程序。

--extra-vars "app=app1" 
--extra-vars "app=app[12]" 
--extra-vars "app=app.*" 
--extra-vars "app=app1|app2" 
... 

但請注意這一點。 --extra-vars "app=app1"也會匹配app10

+0

這聽起來像是我需要的,謝謝!我想知道是否有這樣的事情,但無法完成。我將不會有機會嘗試幾天,但它會在工作時標記正確。 –

+0

它工作的很好 - 非常感謝udondan! –