Ansible的YAML语法

文章目录

  • 环境
  • YAML基础
  • 换行
  • 引号
    • 考一考
  • Ansible变量
  • 布尔值
  • 参考

环境

  • 管理节点: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"
}

注意:所有行的缩进要一致。

这两种方式下:

  1. 缩进都会被忽略
  2. 行末的空白符都会保留

使用 > 的时候,如果所有行的缩进不一致,或者有空行,则会保留换行符,比如:

---
- 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"

因为在双引号里, \ 后面要跟一个转义符,比如 ntb\ 等。

考一考

如何用双引号表示literal的 ab\ncd\tef

答:

var1: "ab\\ncd\\tef"

注意literal的 \ 在双引号里要写成 \\

Ansible变量

语法: {{ }}

在单引号和双引号中都可以使用变量,比如:

---
- 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

你可能感兴趣的:(Ansible,ansible,yaml)