2016-03-03 84 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! –