高级 Playbook 语法
本页中的高级 YAML 语法示例让您能够更灵活地控制 Ansible 所使用的 YAML 文件中的数据。关于 Python 特定 YAML 的更多信息,请参阅官方的 PyYAML 文档。
不安全或原始字符串 (Unsafe or raw strings)
在处理 lookup 插件返回的值时,Ansible 使用一种名为 unsafe 的数据类型来阻止模板渲染。将数据标记为 unsafe 可以防止恶意用户滥用 Jinja2 模板在目标机器上执行任意代码。Ansible 的实现确保了 unsafe 值永远不会被渲染。这比使用 {% raw %} ... {% endraw %} 标签来转义 Jinja2 更加全面。
您可以在定义的变量中使用同样的 unsafe 数据类型,以防止模板渲染错误和信息泄露。您可以将 vars_prompts 提供的某些值标记为 unsafe。您也可以在 playbook 中使用 unsafe。最常见的用例包括允许包含 { 或 % 等特殊字符的密码,以及看起来像模板但不应被渲染的 JSON 参数。例如:
---
mypassword: !unsafe 234%234{435lkj{{lkjsdf
在 playbook 中
---
hosts: all
vars:
my_unsafe_variable: !unsafe 'unsafe % value'
tasks:
...
对于哈希 (hashes) 或数组 (arrays) 等复杂变量,请在单个元素上使用 !unsafe
---
my_unsafe_array:
- !unsafe 'unsafe element'
- 'safe element'
my_unsafe_hash:
unsafe_key: !unsafe 'unsafe value'
YAML 锚点和别名:共享变量值
YAML 锚点 (anchors) 和别名 (aliases) 能帮助您定义、维护并灵活地使用共享的变量值。您使用 & 定义锚点,然后使用以 * 开头的别名来引用它。以下是一个示例,通过一个锚点设置三个值,使用别名引用其中两个值,并覆盖第三个值:
---
# ...
vars:
app1:
jvm: &jvm_opts
opts: '-Xms1G -Xmx2G'
port: 1000
path: /usr/lib/app1
app2:
jvm:
<<: *jvm_opts
path: /usr/lib/app2
# ...
在这里,app1 和 app2 通过锚点 &jvm_opts 和别名 *jvm_opts 共享 opts 和 port 的值。path 的值是通过 << 或 合并运算符 (merge operator) 合并的。
锚点和别名还允许您共享复杂的变量值集,包括嵌套变量。如果您有一个变量值包含另一个变量值,您可以分别定义它们:
vars:
webapp_version: 1.0
webapp_custom_name: ToDo_App-1.0
这样做效率低下,且在规模扩大时意味着更多的维护工作。为了在名称中包含版本值,您可以在 app_version 中使用锚点,并在 custom_name 中使用别名:
vars:
webapp:
version: &my_version 1.0
custom_name:
- "ToDo_App"
- *my_version
现在,您可以在 custom_name 的值中复用 app_version 的值,并在模板中使用其输出:
---
- name: Using values nested inside dictionary
hosts: localhost
vars:
webapp:
version: &my_version 1.0
custom_name:
- "ToDo_App"
- *my_version
tasks:
- name: Using Anchor value
ansible.builtin.debug:
msg: My app is called "{{ webapp.custom_name | join('-') }}".
您使用 &my_version 锚点固定了 version 的值,并使用 *my_version 别名对其进行复用。锚点和别名让您可以访问字典内部的嵌套值。