YAML文件技巧
YAML是Ansible,k8s,Docker等软件大量使用的文件格式,也是当今最流行的配置文件格式。今天就聊聊几个在写YAML文件时注意的小技巧或者问题
请尽量参考官方的YAML spec,目前是1.2版 https://yaml.org/spec/1.2/spec.html
Lint
和Python,Java等编程语言一样,YAML也有对应的lint工具帮大家检查文件的语法和结构问题。个人建议一定要把lint的检查部署到CI中。在本地开发,你也可以:
- 借助一些IDE插件做lint的辅助检查,比如VS Code等都有关于YAML的插件
- 在push代码到仓库之前,本地运行下lint的检查,对于YAML,可以使用yamllint工具,通过
pip install yamllint
进行安装,如果是Ansible的项目,可以直接使用ansible-lint
# all.yml
- tabitha:
name: Tabitha Bitumen
job: Developer
skills:
- lisp
- fortran
- erlang
- test
执行的效果。
(yaml) ➜ yaml-tips yamllint all.yml
all.yml
10:5 error syntax error: expected <block end>, but found '-' (syntax)
10:11 error no new line character at the end of file (new-line-at-end-of-file)
(yaml) ➜ yaml-tips
Space vs Tab
对于代码缩进用空格还是Tab,这个一直都有争论。但是由于目前的IDE都可以设置tab键的空格个数,并且可以根据文件的不同类型而不同。所以基本争议主要在使用几个空格的问题上。
我个人本身认为自己不是程序员,毕竟不是每天都写代码,偶尔写写Python和Ansible,我的VS Code里设置的是Python 4空格缩进,Ansible(YAML)是2空格缩进,这基本也是官方spec推荐的。
缩进的这个问题,最关键的我个人认为是要和team成员沟通好,大家达成一致最好,剩下的就交给IDE和lint工具即可。
如果文件里的缩进出现不一致的情况,lint工具一般会帮我们指出。
(yaml) ➜ yaml-tips yamllint all.yml
all.yml
7:9 error wrong indentation: expected 6 but found 8 (indentation)
(yaml) ➜ yaml-tips
行最大的长度
一行的最大长度规定也不是死的,之所以很多lint检查工具都会检查行最大长度,主要是问了提高代码的可阅读性,如果一行太长,则需要拉动左右的滑动条进行代码阅读,无疑会影响代码阅读的体验。
yamllint设置的默认行最大长度是80个字符,如果超过了,则会报错。
(yaml) ➜ yaml-tips yamllint all.yml
all.yml
7:81 error line too long (86 > 80 characters) (line-length)
(yaml) ➜ yaml-tips
80个人觉得有点短,特是大家现在的显示器都很大,分辨率很高。和Python一样,我个人推荐**>=120**个字符每行。 这个可以修改yamllint的rule规则。
但是即使设置了120个字符,个别情况下,我们的行的字符可能超过这个长度,这时候就要考虑换行了。基本有三种情况
- |
-
include_newlines: |
exactly as you see
will appear these three
lines of poetry
结果就是 (每一行最后包括最后一行都会有换行) 'exactly as you see\nwill appear these three\nlines of poetry\n'
fold_newlines: >
this is really a
single line of text
despite appearances
结果是(只有最后 一行有换行,其它以空格连接) 'this is really a single line of text despite appearances\n'
fold_newlines_without_newlines_at_the_end: >-
this is really a
single line of text
despite appearances
结果是(和上一个不同之处在于最后一行没有换行) 'this is really a single line of text despite appearances'
Anchors and References
这个可能用的不多,但是真正需要的时候确实能你给解决大的问题。
有时候在YAML文件里我们可能需要定义复杂的一些数据结构,这个结构中可能有部分的key-value存在重复引用的问题。举个例子
比如下面这个prefix_list
的值实际是一样,存在重复。
ip_prefix_list:
- name: permit_func_xyz
prefix_list:
- seq: 10
prefix: 192.168.1.0/24
- seq: 20
prefix: 192.168.2.0/24
- seq: 30
prefix: 192.168.3.0/24
- name: permit_func_abc
prefix_list:
- seq: 10
prefix: 192.168.1.0/24
- seq: 20
prefix: 192.168.2.0/24
- seq: 30
prefix: 192.168.3.0/24
通过YAML的anchors reference语法,可以改成下面这样,类似定义一个变量,下面去引用
prefix_list_value: &prefix_list_value
- seq: 10
prefix: 192.168.1.0/24
- seq: 20
prefix: 192.168.2.0/24
- seq: 30
prefix: 192.168.3.0/24
ip_prefix_list:
- name: permit_func_xyz
prefix_list: *prefix_list_value
- name: permit_func_abc
prefix_list: *prefix_list_value
更重要的是,这个功能不止可以做到这个,还可以实现部分变量的共享和引用,比如:
foo:
<<: &anchor
K1: "One"
K2: "Two"
bar:
<<: *anchor
K3: "Three"
最终的结果会是
{
'bar': {
'K1': 'One',
'K3': 'Three'
},
'foo': {
'K1': 'One',
'K2': 'Two'
}
}
Validator
当你不确定自己的YAML格式(数据层面)是否有问题的时候,最简单的办法就是用检查工具,这种工具有很多。
另外因为YAML和JSON有着天然的密切关系,可以通过工具(比如python pyyaml)把YAML文件转成JSON,对比一下,也是不错的办法。
Discussion