Ansible的YAML语法
环境
- 管理节点:Ubuntu 22.04
- 控制节点:CentOS 8
- Ansible:2.15.6
YAML基础
- ---:文件开头(可选)
- ...:文件结尾(可选)
- -:哈希(hash),注意- -后面要有空格
- ::字典(dictionary),注意- :后面要有空格
- #:注释,注意如果是行内注释,则- #前面要有空格
比如:
---
- name: Tom # some comment
  age: 20
  sport:
    - football
    - basketball
# another comment
- name: Jerry
  age: 18
  sport:
    - swim
    - tennis
    - football
...
Dictionary也可以写成如下形式:
{name: Tom, age: 20}
List也可以写成如下形式:
[football, basketball]
换行
一个字符串可以跨多行:
- \n:换行符
- |:多行,把换行转换为- \n
- >:多行,把换行转换为空格
比如:
---
- hosts: all
  vars:
    var1: |
            abcdefg
            hijklmn
            opqrst
            uvwxyz
    var2: >
            abcdefg
            hijklmn
            opqrst
            uvwxyz
  tasks:
    - name: task1
      debug:
        msg: "{{ var1 }}"
    - name: task2
      debug:
        msg: "{{ var2 }}"
运行结果如下:
TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "abcdefg\nhijklmn\nopqrst\nuvwxyz\n"
}
TASK [task2] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "abcdefg hijklmn opqrst uvwxyz\n"
}
注意:所有行的缩进要一致。
这两种方式下:
- 缩进都会被忽略
- 行末的空白符都会保留
使用 > 的时候,如果所有行的缩进不一致,或者有空行,则会保留换行符,比如:
---
- hosts: all
  vars:
    var1: >
            a
            b
            c
            d
              e
            f
            g
  tasks:
    - name: task1
      debug:
        msg: "{{ var1 }}"
运行结果如下:
TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "a b\nc d\n  e\nf g\n"
}
当然,也可以直接使用 \n 来表示换行。
引号
一般情况下,字符串可以不用引号,比如:
description: Hello world!
但是有一些特例:若不用引号,则有一些字符不能出现在字符串开头处:
- [
- ]
- {
- }
- >
- |
- *
- &
- !
- %
- #
- `
- @
- ,
此外,对于以下符号:
- ?
- :
- -
如果其后不是空格,才可以出现在字符串开头处。
---
- hosts: all
  tasks:
    - name: task1
      debug:
        msg: ?abc
    - name: task2
      debug:
        msg: :abc
    - name: task3
      debug:
        msg: -abc
说了半天这么麻烦,不如还是加上引号吧,省事。
单引号或者双引号都可以,二者区别在于,单引号包含的是literal的内容,而双引号的内容可以转义。
比如:
var1: 'ab\ncd\tef'
var2: "ab\ncd\tef"
- var1:literal的字符串
- var2:包含了一个换行和一个制表符
下面写法是错误的:
var1: "ab\c"
因为在双引号里, \ 后面要跟一个转义符,比如 n 、 t 、 b 、 \ 等。
考一考
如何用双引号表示literal的 ab\ncd\tef ?
答:
var1: "ab\\ncd\\tef"
注意literal的 \ 在双引号里要写成 \\ 。
Ansible变量
语法: {{ <variable> }}
在单引号和双引号中都可以使用变量,比如:
---
- hosts: all
  vars:
    var1: "aaa"
    var2: "bbb\nccc {{ var1 }}"
    var3: 'bbb\nccc {{ var1 }}'
  tasks:
    - name: task1
      debug:
        msg: "{{ var2 }}" # bbb\nccc aaa
    - name: task2
      debug:
        msg: '{{ var2 }}' # bbb\nccc aaa
    - name: task3
      debug:
        msg: "{{ var3 }}" # bbb\\nccc aaa
    - name: task4
      debug:
        msg: '{{ var3 }}' # bbb\\nccc aaa
可见,在单引号和双引号里,变量都可以被解析。
注:这一点是和shell脚本不同的,shell脚本里只能在双引号里使用变量,而单引号里都是literal的字符串。
注意:输出结果相当于是双引号的内容,而变量里单引号里的 \ 是literal字符,所以在输出结果里被转义为 \\ 。
那么问题来了,如果是literal的 {{ var2 }} ,要如何处理呢?
一种方式是在template里使用literal的字符串:
---
- hosts: all
  tasks:
    - name: task1
      debug:
        msg: "{{ '{{ var2 }}' }}" # {{ var2 }}
应该还有别的简单方法吧(比如转义什么的),暂时没有深究。
布尔值
很简单,想要字符串就加上引号,想要布尔值就不要加引号,比如:
- "yes"/- "no"/- "true"/- "false":字符串
- yes/- no/- true/- false:布尔值
比如:
---
- hosts: all
  vars:
    var1: "yes"
    var2: yes
  tasks:
    - name: task1
      debug:
        msg: "{{ var1 | type_debug }}" # AnsibleUnicode
    - name: task2
      debug:
        msg: "{{ var2 | type_debug }}" # bool
    - name: task3
      debug:
        msg: "{{ 'yes' | type_debug }}" # str
    - name: task4
      debug:
        msg: "{{ yes | type_debug }}" # AnsibleUndefined
注意:在task2里,把 yes 赋值给变量,其类型被隐式转换为 bool 。在task4里,literal的 yes ,其类型是 AnsibleUndefined 。而literal的 true ,其类型则直接就是 bool 。
参考
- https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!