第 31 章 变量的使用(一)
31.1 手动定义变量
通过vars
来定义变量,vars和tasks对齐,格式如下,
vars:
var1: value1
var2: value2
...
定义变量时,不可有重复的变量,否则后面定义的变量值会覆盖前面的,会有提示信息
[root@node-137 ansible]# ansible-playbook test6.yml
[WARNING]: While constructing a mapping from /opt/ansible/test6.yml, line 6, column 5, found a duplicate dict key (v1). Using last
defined value only.
PLAY [echo vars] **********************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [node-138] => {
"msg": 456
}
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node-137 ansible]# cat test6.yml
---
- hosts: db1
name: echo vars
gather_facts: false
vars:
v1: 123
v2: 321
v1: 456
tasks:
- debug: msg={{v1}}
引用变量时用{{ 变量名 }}
,大括号内存两边有无空格均可,但相同大括号之间不能有空格
{{ var }}
{{var}}
{{ var}}
{ {var}}#错误
[root@node-137 ansible]# ansible-playbook test6.yml
...
The offending line appears to be:
tasks:
- debug: msg={ {v1}}
^ here
[root@node-137 ansible]# cat test6.yml
---
- hosts: db1
name: echo vars
gather_facts: false
vars:
v1: 123
v2: 321
v3: 456
tasks:
- debug: msg={ {v1}}
31.2 变量文件
如果定义的变量太多,可以把变量拿出来单独放在一个文件中,然后在vars_files
引用此变量文件,就可以直接使用文件中的变量了。该文件中变量的格式要和在playbook的vars中变量的结构一致
[root@node-137 ansible]# ansible-playbook test6.yml
PLAY [echo vars] **********************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [node-138] => {
"msg": 123
}
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node-137 ansible]# cat vars.yaml
v1: 123
v2: 456
v3: 789
[root@node-137 ansible]# cat test6.yml
---
- hosts: db1
name: echo vars
gather_facts: false
vars_files:
- vars.yaml
tasks:
- debug: msg={{v1}}
也可以这样写
[root@node-137 ansible]# cat test6.yml
---
- hosts: db1
name: echo vars
gather_facts: false
vars_files: vars.yaml
tasks:
- debug: msg={{v1}}
31.3 字典变量
所谓字典(dictionaries简写为dict),这里和python中含义相同,键不能重复。
字典中如果出现了相同的变量名,则后面定义的变量的值会覆盖前面的
字典是在vars中定义的,语法,
字典名:
var1: value1
var2: value2
...
在字典中定义变量时,变量前面是不加
-
的,且定义变量没有先后顺序
通过字典名.变量名
引用变量,如,
[root@node-137 ansible]# cat test6.yml
---
- hosts: db1
name: echo vars
gather_facts: false
vars:
dict1:
v1: 123
v2: 345
v3: 456
dict2:
v1: 321
v2: 543
v3: 654
tasks:
- debug: msg={{dict1.v1}}
- debug: msg={{dict2.v1}}
[root@node-137 ansible]# ansible-playbook test6.yml
PLAY [echo vars] **********************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [node-138] => {
"msg": "123"
}
TASK [debug] **************************************************************************************************************************
ok: [node-138] => {
"msg": "321"
}
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
31.4 列表变量
在playbook中列表变量和字典变量比较容易混淆,语法,
列表名:
- var1: value1
var2: value2
var3: value1
- var1: value1
var2: value2
var3: value1
- var1: value1
var2: value2
var3: value1
...
- 列表中变量通过索引来引用变量,所以前后变量名相同,并不会覆盖。
- 每个元素的第一个变量前都加上
-
,表示它是该元素的第一个变量。 - 获取
元素
值通过列表名[n]
,n从0开始。获取变量
值通过列表名[n].var1
。
例如,
[root@node-137 ansible]# cat test6.yml
---
- hosts: db1
name: echo vars
gather_facts: false
vars:
list1:
- v1: 123
v2: 345
v3: 456
- v1: 789
v2: 987
list2:
- v1: 321
v2: 543
v3: 654
- v1: 000
v2: 222
tasks:
- debug: msg={{list1[0]}}
- debug: msg={{list2[1].v1}}
[root@node-137 ansible]# ansible-playbook test6.yml
PLAY [echo vars] **********************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [node-138] => {
"msg": {
"v1": 123,
"v2": 345,
"v3": 456
}
}
TASK [debug] **************************************************************************************************************************
ok: [node-138] => {
"msg": "0"
}
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
这里变量值为整数类型,所以打印的是0,而非000,可以在定义时改为"000"试试
定义列表时,可以直接写值,而不写变量名,如,
vars:
list1:
- 123
- 345
- 456
这种定义方式可以转换成如下内容,
list1: [v1, v2, v3]
不过这种方式
好像
只能表示一维列表,笔者也不太确定
[root@node-137 ansible]# cat test6.yml
---
- hosts: db1
name: echo vars
gather_facts: false
vars:
list1:
- "123,431"
- 345
- 456
tasks:
- debug: msg={{list1[0]}}
- debug: msg={{list1[0][1]}}
[root@node-137 ansible]# ansible-playbook test6.yml
PLAY [echo vars] **********************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [node-138] => {
"msg": "123,431"
}
TASK [debug] **************************************************************************************************************************
ok: [node-138] => {
"msg": "2"
}
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
31.5 数字变量的运算
在YAML文件中定义的变量,其值如果时数字,则可以进行数学运算。常见的数学运算符包括:+
,-
,*
,/
和**
(幂)。
计算变量aa
*2和aa
的3次幂
[root@node-137 ansible]# ansible-playbook 4-vars.yaml
PLAY [vars] ***************************************************************************************************************************
TASK [aa*2] ***************************************************************************************************************************
ok: [node-138] => {
"msg": "6"
}
TASK [debug] **************************************************************************************************************************
ok: [node-138] => {
"msg": "27"
}
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node-137 ansible]# cat 4-vars.yaml
---
- hosts: db1
name: vars
gather_facts: false
vars:
aa: 3
tasks:
- name: aa*2
debug: msg={{aa*2}}
- debug: msg={{aa**3}}
31.6 注册变量
在playbook中用shell模块执行某个系统命令后,在结果中时不会显示这个命令结果的,这和在命令行中用ansible命令调用shell模块不一样
[root@node-137 ansible]# cat 5_reg1.yml
---
- hosts: db1
name: hostname
gather_facts: false
tasks:
- name: display hostname
shell: hostname
[root@node-137 ansible]# ansible-playbook 5_reg1.yml
PLAY [hostname] ***********************************************************************************************************************
TASK [display hostname] ***************************************************************************************************************
changed: [node-138]
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
如果想要查看shell命令的结果,可以把shell命令的结果保存在一个变量中,这个变量就是注册变量,然后打印这个变量的值即可。
修改上面的yaml文件
[root@node-137 ansible]# cat 5_reg1.yml
---
- hosts: db1
name: hostname
gather_facts: false
tasks:
- name: display hostname
shell: hostname
register: aa
- name: display aa
debug: msg={{aa}}
[root@node-137 ansible]# ansible-playbook 5_reg1.yml
PLAY [hostname] ***********************************************************************************************************************
TASK [display hostname] ***************************************************************************************************************
changed: [node-138]
TASK [display aa] *********************************************************************************************************************
ok: [node-138] => {
"msg": {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"cmd": "hostname",
"delta": "0:00:00.032575",
"end": "2023-12-19 17:04:41.632157",
"failed": false,
"rc": 0,
"start": "2023-12-19 17:04:41.599582",
"stderr": "",
"stderr_lines": [],
"stdout": "node-138",
"stdout_lines": [
"node-138"
]
}
}
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
结果中msg
后面的内容就是aa
的值,可以看到aa
是一个字典。其中cmd
是执行的系统命令,rc
是此命令的返回值,stdout
表示此命令的结果。
如果只获取命令结果,只要打印字典aa
中的stdout
变量即可
[root@node-137 ansible]# cat 5_reg1.yml
---
- hosts: db1
name: hostname
gather_facts: false
tasks:
- name: display hostname
shell: hostname
register: aa
- name: display aa
debug: msg={{aa.stdout}}
[root@node-137 ansible]# ansible-playbook 5_reg1.yml
PLAY [hostname] ***********************************************************************************************************************
TASK [display hostname] ***************************************************************************************************************
changed: [node-138]
TASK [display aa] *********************************************************************************************************************
ok: [node-138] => {
"msg": "node-138"
}
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
31.7 facts变量
ansible通过setup模块是可以获取到被管理主机的所有信息的,这些信息都是以变量的方式存在的,这些变量称为facts
,另外如果要获取facts
不能把gather_facts
设置为false
,可以不设置(默认为true
),或者设置为true
[root@node-137 ansible]# cat 6-fact.yaml
---
- hosts: db1
name: display ipv4.address
gather_facts: true
tasks:
- name: display ip
debug: msg={{ansible_default_ipv4.address}}
- name: display fqdn
debug: msg={{ansible_fqdn}}
[root@node-137 ansible]# ansible-playbook 6-fact.yaml
PLAY [display ipv4.address] ***********************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************
ok: [node-138]
TASK [display ip] *********************************************************************************************************************
ok: [node-138] => {
"msg": "192.168.81.138"
}
TASK [display fqdn] *******************************************************************************************************************
ok: [node-138] => {
"msg": "node-138"
}
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
在本系列文章 九 29.20 使用 setup 模块获取被管理服务器信息
中提到
命令行中如果filter含有子键,结果不会显示,所以上面命令未看到IP。不过如果把这个键写入ansible-playbook(剧本)中,会显示哦,关于playbook后面会介绍。
在此解决