文章目录
环境
- 管理节点:Ubuntu 22.04
- 控制节点:CentOS 8
- Ansible:2.15.6
YAML基础
---
:文件开头(可选)...
:文件结尾(可选)-
:哈希(hash),注意-
后面要有空格:
:字典(dictionary),注意:
后面要有空格#
:注释,注意如果是行内注释,则#
前面要有空格
比如:
yaml
---
- name: Tom # some comment
age: 20
sport:
- football
- basketball
# another comment
- name: Jerry
age: 18
sport:
- swim
- tennis
- football
...
Dictionary也可以写成如下形式:
yaml
{name: Tom, age: 20}
List也可以写成如下形式:
yaml
[football, basketball]
换行
一个字符串可以跨多行:
\n
:换行符|
:多行,把换行转换为\n
>
:多行,把换行转换为空格
比如:
yaml
---
- hosts: all
vars:
var1: |
abcdefg
hijklmn
opqrst
uvwxyz
var2: >
abcdefg
hijklmn
opqrst
uvwxyz
tasks:
- name: task1
debug:
msg: "{{ var1 }}"
- name: task2
debug:
msg: "{{ var2 }}"
运行结果如下:
powershell
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"
}
注意:所有行的缩进要一致。
这两种方式下:
- 缩进都会被忽略
- 行末的空白符都会保留
使用 >
的时候,如果所有行的缩进不一致,或者有空行,则会保留换行符,比如:
yaml
---
- hosts: all
vars:
var1: >
a
b
c
d
e
f
g
tasks:
- name: task1
debug:
msg: "{{ var1 }}"
运行结果如下:
powershell
TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {
"msg": "a b\nc d\n e\nf g\n"
}
当然,也可以直接使用 \n
来表示换行。
引号
一般情况下,字符串可以不用引号,比如:
yaml
description: Hello world!
但是有一些特例:若不用引号,则有一些字符不能出现在字符串开头处:
[
]
{
}
>
|
*
&
!
%
#
-
@
,
此外,对于以下符号:
?
:
-
如果其后不是空格,才可以出现在字符串开头处。
yaml
---
- hosts: all
tasks:
- name: task1
debug:
msg: ?abc
- name: task2
debug:
msg: :abc
- name: task3
debug:
msg: -abc
说了半天这么麻烦,不如还是加上引号吧,省事。
单引号或者双引号都可以,二者区别在于,单引号包含的是literal的内容,而双引号的内容可以转义。
比如:
yaml
var1: 'ab\ncd\tef'
var2: "ab\ncd\tef"
var1
:literal的字符串var2
:包含了一个换行和一个制表符
下面写法是错误的:
yaml
var1: "ab\c"
因为在双引号里, \
后面要跟一个转义符,比如 n
、 t
、 b
、 \
等。
考一考
如何用双引号表示literal的 ab\ncd\tef
?
答:
yaml
var1: "ab\\ncd\\tef"
注意literal的 \
在双引号里要写成 \\
。
Ansible变量
语法: {``{ <variable> }}
在单引号和双引号中都可以使用变量,比如:
yaml
---
- 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的字符串:
yaml
---
- hosts: all
tasks:
- name: task1
debug:
msg: "{{ '{{ var2 }}' }}" # {{ var2 }}
应该还有别的简单方法吧(比如转义什么的),暂时没有深究。
布尔值
很简单,想要字符串就加上引号,想要布尔值就不要加引号,比如:
"yes"
/"no"
/"true"
/"false"
:字符串yes
/no
/true
/false
:布尔值
比如:
yaml
---
- 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