在我的Ansible剧本中,我在一台服务器上设置了许多网站。每个网站都在apps
变量中设置了一些配置:
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
的{{1}}设置了默认值。然后在每个与应用相关的任务上添加:
false
这应该可行,但是必须将其添加到每个任务中似乎很费力且容易出错。是否有一种更优雅的方式可以避免这么多的重复?
答案 0 :(得分: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
match
中使用的selectattr
过滤器实际上采用了正则表达式。因此,您可以提供要处理的应用程序的非常详细的表达式。
--extra-vars "app=app1"
--extra-vars "app=app[12]"
--extra-vars "app=app.*"
--extra-vars "app=app1|app2"
...
但要小心这一点。 --extra-vars "app=app1"
也会匹配app10
等。