Ansible - 当没有指定参数时默认为一切
Ansible - default to everything when no arguments are specified
我有一个相当大的剧本,能够在给定主机上更新多达 10 个服务。
假设我有服务 a b c d,我希望能够通过传递命令行参数来选择性地更新服务,但默认情况下在没有传递参数时更新所有内容。你怎么能在 Ansible 中做到这一点而不能进入任意脚本?
现在我拥有的是 when 检查每个服务并定义该服务在 playbook 调用时是否为真。考虑到我可能有多达 10 个服务,我无法编写布尔逻辑来适应所有可能性。
我希望 bash 中可能有一个像 $@ 这样的内置函数,它列出了所有参数,我可以按照 when: $@.length = 0
进行检查
ansible-playbook deploy.yml -e "a=true b=true d=true"
when: a == "true"
when: b == "true"
when: c == "true"
when: d == "true"
我建议使用标签。假设我们有两个服务,例如 nginx 和 fpm。然后用 nginx 标记 nginx 的播放,用 fpm 标记 fpm 的播放。下面是任务级别标记的示例,假设其名称为 play.yml
- name: tasks for nginx
service: name=nginx state=reloaded
tags:
- nginx
- name: tasks for php-fpm
service: name=php-fpm state=reloaded
tags:
- fpm
执行 ansible-playbook play.yml 默认情况下 运行 这两个任务。但是,如果我将命令更改为
ansible-playbook play.yml --tags "nginx"
那么只执行带有nginx标签的任务。标签也可以应用于游戏级别或角色级别。
播放级别标记看起来像
- hosts: all
remote_user: user
tasks:
- include: play1.yml
tags:
- play1
- include: play2.yml
tags:
- play2
在这种情况下,剧本 play1.yml 中的所有任务都将继承标签 play1,play2 也一样。当 运行ning 带有标签 play1 的 ansible-playbook 时,play1.yml 中的所有任务都会被执行。相反,如果我们不指定任何标签,则执行 play1 和 play2 中的所有任务。
注意:一项任务不限于只有一个标签。
如果您有一个要循环播放的服务,请在 group_vars/all 或其他有意义的地方定义该列表:
services:
- first
- second
- third
- fourth
那么你在 start_services.yml 剧本中的任务可以是这样的:
- name: Ensure passed variables are in services list
fail:
msg: "{{ item }} not in services list"
when: item not in services
with_items: "{{ varlist | default(services) }}"
- name: Start services
service:
name: "{{ item }}"
state: started
with_items: "{{ varlist | default(services) }}"
将 varlist 作为 JSON 数组传入:
$ ansible-playbook start_services.yml --extra-vars='{"varlist":[first,third]}'
我有一个相当大的剧本,能够在给定主机上更新多达 10 个服务。
假设我有服务 a b c d,我希望能够通过传递命令行参数来选择性地更新服务,但默认情况下在没有传递参数时更新所有内容。你怎么能在 Ansible 中做到这一点而不能进入任意脚本?
现在我拥有的是 when 检查每个服务并定义该服务在 playbook 调用时是否为真。考虑到我可能有多达 10 个服务,我无法编写布尔逻辑来适应所有可能性。
我希望 bash 中可能有一个像 $@ 这样的内置函数,它列出了所有参数,我可以按照 when: $@.length = 0
ansible-playbook deploy.yml -e "a=true b=true d=true"
when: a == "true"
when: b == "true"
when: c == "true"
when: d == "true"
我建议使用标签。假设我们有两个服务,例如 nginx 和 fpm。然后用 nginx 标记 nginx 的播放,用 fpm 标记 fpm 的播放。下面是任务级别标记的示例,假设其名称为 play.yml
- name: tasks for nginx
service: name=nginx state=reloaded
tags:
- nginx
- name: tasks for php-fpm
service: name=php-fpm state=reloaded
tags:
- fpm
执行 ansible-playbook play.yml 默认情况下 运行 这两个任务。但是,如果我将命令更改为
ansible-playbook play.yml --tags "nginx"
那么只执行带有nginx标签的任务。标签也可以应用于游戏级别或角色级别。
播放级别标记看起来像
- hosts: all
remote_user: user
tasks:
- include: play1.yml
tags:
- play1
- include: play2.yml
tags:
- play2
在这种情况下,剧本 play1.yml 中的所有任务都将继承标签 play1,play2 也一样。当 运行ning 带有标签 play1 的 ansible-playbook 时,play1.yml 中的所有任务都会被执行。相反,如果我们不指定任何标签,则执行 play1 和 play2 中的所有任务。
注意:一项任务不限于只有一个标签。
如果您有一个要循环播放的服务,请在 group_vars/all 或其他有意义的地方定义该列表:
services:
- first
- second
- third
- fourth
那么你在 start_services.yml 剧本中的任务可以是这样的:
- name: Ensure passed variables are in services list
fail:
msg: "{{ item }} not in services list"
when: item not in services
with_items: "{{ varlist | default(services) }}"
- name: Start services
service:
name: "{{ item }}"
state: started
with_items: "{{ varlist | default(services) }}"
将 varlist 作为 JSON 数组传入:
$ ansible-playbook start_services.yml --extra-vars='{"varlist":[first,third]}'