![Ansible:在运行剧本之前检查提供的标签是否有效](https://linux22.com/image/726527/Ansible%EF%BC%9A%E5%9C%A8%E8%BF%90%E8%A1%8C%E5%89%A7%E6%9C%AC%E4%B9%8B%E5%89%8D%E6%A3%80%E6%9F%A5%E6%8F%90%E4%BE%9B%E7%9A%84%E6%A0%87%E7%AD%BE%E6%98%AF%E5%90%A6%E6%9C%89%E6%95%88.png)
我怀疑这太过聪明(并且失败了),但是 - 特别是在开发 PB 时,使用标签来限制运行的角色确实很有用 - 例如我们有:(剧本片段)...
- { role: yum, tags: [ 'yum' ] }
- { role: proxy, tags: [ 'proxy' ] }
- { role: firewall, tags: [ 'firewall' ] }
现在偶尔,我会使用拼写错误的标签运行 - 例如
$ ansible-playbook servername, user=fred my_playbook --tags=firewal
前置任务和后置任务都会运行,这看起来好像有事情正在发生,但当然,没有任务与错误输入的标签匹配。我确实在日志中发现了这一点(每个角色都会这样做:
- include_tasks: includes/log_role_completion.yml this_role={{ role_name }}
其解析结果如下:
- name: "Setup completed_roles list"
set_fact:
completed_roles: "{{ this_role }}"
changed_when: false
when: completed_roles is not defined
- name: "Add role to list of completed roles"
set_fact:
completed_roles: "{{ completed_roles }} {{ this_role }}"
changed_when: false
when: completed_roles != this_role
然后,post_tasks 角色会写入已完成角色的列表 - 或者一条消息,说明由于标签拼写错误,没有角色运行。这很好用 - 我知道 ansible 会写入日志,但它们要么冗长,要么晦涩难懂,我喜欢在目标上使用 /var/log/ansible,如下所示:
Ansible version 2.6.2 run commenced at 2018-08-31: 20:23:40 GMT using account vmw-user
Ansible version 2.6.2 run completed at 2018-08-31: 20:23:40 GMT for roles chrony, proxy, and log_complete
这确实很有用,但是(最后,问题是)我宁愿让剧本检查所提供的标签是否与剧本中使用的任何标签不匹配,然后停止 - 从而警告我拼写错误。这也可以防止剧本不完整运行 - 带有拼写错误标签的角色根本无法运行,这可能会导致问题。
变量 vars.ansible_run_tags 包含用户提供的标签:有没有办法查看剧本中设置了哪些标签?我不想先在检查模式下运行,然后手动解析输出 - 我希望它是自动的。
答案1
恕我直言,没有这样的变量来“查看剧本中设置了哪些标签”。只有ansible_run_tags和ansible_skip_tags。恐怕唯一的选择就是编写一个 ansible-playbook 包装器来检查所提供的标签是否存在于剧本中(“首先以检查模式运行,然后手动解析输出”)。
顺便说一句。以下是已完成角色的简化列表。
completed_roles: "{{ completed_roles|default('') }} {{ this_role }}"
为了避免“前置任务和后置任务同时运行,让人觉得好像有事正在发生”,你可能需要使用导入角色和什么时候条件而不是标签。下面是 role3.yml 和 role4.yml 仅打印消息的示例。
播放文件
- hosts:
- localhost
tasks:
- import_role: name=role3
when: selector|default('') in [ 'role3', 'all_roles' ]
- import_role: name=role4
when: selector|default('') in [ 'role4', 'all_roles' ]
。
> ansible-playbook -e selector=role4 play.yml | grep msg
"msg": "role4"
。
> ansible-playbook -e selector=all_roles play.yml | grep msg
"msg": "role3"
"msg": "role4"