ansible playbook 中变量引用

摘要

本文记录ansible中常用的变量的定义、引用方式。

Inventory 定义主机、主机组变量

主机变量

1
2
3
4
5
6
7
8
9
10
11
# cat inventory 
192.168.79.129 key=129
192.168.79.130 key=130
192.168.79.131 key=131
192.168.79.132 key=132

[nginx]
192.168.79.1[29:32]

[nginx:vars]
ansible_python_interpreter=/usr/bin/python2.6

通过playbook验证变量的引用

1
2
3
4
5
6
7
# cat variable.yaml 
---
- hosts: all
gather_facts: False
tasks:
- name: diplay Host Variable from hostfile
debug: msg="The {{ inventory_hostname }} Value is {{ key }}"

运行playbook

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# ansible-playbook variable.yaml

PLAY [all] *******************************************************************************************************************

TASK [diplay Host Variable from hostfile] *******************************************************************************************************************
ok: [192.168.79.129] => {
"msg": "The 192.168.79.129 Value is 129"
}
ok: [192.168.79.130] => {
"msg": "The 192.168.79.130 Value is 130"
}
ok: [192.168.79.131] => {
"msg": "The 192.168.79.131 Value is 131"
}
ok: [192.168.79.132] => {
"msg": "The 192.168.79.132 Value is 132"
}

PLAY RECAP *******************************************************************************************************************
192.168.79.129 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.130 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.131 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.132 : ok=1 changed=0 unreachable=0 failed=0

可以看到,每台主机都引用了自己的主机变量key;

主机组变量

1
2
3
4
5
6
7
8
9
10
[root@zero01 inventory]# cat host_playbook 
#192.168.79.129 key=129 
#192.168.79.130 key=130
#192.168.79.131 key=131
#192.168.79.132 key=132
[nginx]
192.168.79.1[29:32]
[nginx:vars]
ansible_python_interpreter=/usr/bin/python2.6
key=zero_gg

运行playbook文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@zero01 playbook]# ansible-playbook variable.yaml 

PLAY [all] *******************************************************************************************************************

TASK [diplay Host Variable from hostfile] *******************************************************************************************************************
ok: [192.168.79.129] => {
"msg": "The 192.168.79.129 Value is zero_gg"
}
ok: [192.168.79.130] => {
"msg": "The 192.168.79.130 Value is zero_gg"
}
ok: [192.168.79.131] => {
"msg": "The 192.168.79.131 Value is zero_gg"
}
ok: [192.168.79.132] => {
"msg": "The 192.168.79.132 Value is zero_gg"
}

PLAY RECAP *******************************************************************************************************************
192.168.79.129 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.130 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.131 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.132 : ok=1 changed=0 unreachable=0 failed=0

可以看到,主机组变量针对组内所有的主机都生效。

注意

  • 如果主机同时定义了主机变量和主机组变量,名字相同时,主机变量生效,主机组变量不生效;名字不同时,都可以调用。
  • 如果主机同时属于多个主机组,多个主机组定义了同一个变量,一般只有第一个生效

内置目录结构定义主机、主机组变量

  • 文件夹host_vars定义主机变量
  • 文件夹group_vars定义主机组变量
  • 存放位置
    • 默认在/etc/ansible/
    • 自定义可以放在inventory目录下,或者也可以放在playbook目录下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@zero01 ansible]# tree
.
├── ansible.cfg
├── hosts
├── inventory
│   ├── group_vars
│   │   └── nginx
│   ├── host_vars
│   │   ├── 192.168.79.129
│   │   ├── 192.168.79.130
│   │   ├── 192.168.79.131
│   │   └── 192.168.79.132
│   ├── host
│   └── host_playbook
├── playbook
│   ├── nginx.yaml
│   ├── tasks
│   │   └── main.yaml
│   ├── variable.retry
│   └── variable.yaml
└── roles

[root@zero01 inventory]# cat host
192.168.79.129
192.168.79.130
192.168.79.131
192.168.79.132
[nginx]
192.168.79.1[29:32]

创建主机组变量文件和主机变量文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@zero01 ansible]# cat group_vars/nginx
---
key: zero_gg
[root@zero01 ansible]# head host_vars/*
==> host_vars/192.168.79.129 <==
---
key: 192.168.79.129

==> host_vars/192.168.79.130 <==
---
key: 192.168.79.130

==> host_vars/192.168.79.131 <==
---
key: 192.168.79.131

==> host_vars/192.168.79.132 <==
---
key: 192.168.79.132

运行playbook文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@zero01 playbook]# ansible-playbook variable.yaml 

PLAY [all] *******************************************************************************************************************

TASK [diplay Host Variable from hostfile] *******************************************************************************************************************
ok: [192.168.79.129] => {
"msg": "The 192.168.79.129 Value is 192.168.79.129"
}
ok: [192.168.79.130] => {
"msg": "The 192.168.79.130 Value is 192.168.79.130"
}
ok: [192.168.79.131] => {
"msg": "The 192.168.79.131 Value is 192.168.79.131"
}
ok: [192.168.79.132] => {
"msg": "The 192.168.79.132 Value is 192.168.79.132"
}

PLAY RECAP *******************************************************************************************************************
192.168.79.129 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.130 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.131 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.132 : ok=1 changed=0 unreachable=0 failed=0

由上可验证,当主机变量和主机组变量同时存在且名字相同时,只有主机变量生效,主机组变量不生效;

主机组变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@zero01 playbook]# rm -rf host_vars/*
[root@zero01 playbook]# ansible-playbook variable.yaml

PLAY [all] *******************************************************************************************************************

TASK [diplay Host Variable from hostfile] *******************************************************************************************************************
ok: [192.168.79.129] => {
"msg": "The 192.168.79.129 Value is zero_gg"
}
ok: [192.168.79.130] => {
"msg": "The 192.168.79.130 Value is zero_gg"
}
ok: [192.168.79.131] => {
"msg": "The 192.168.79.131 Value is zero_gg"
}
ok: [192.168.79.132] => {
"msg": "The 192.168.79.132 Value is zero_gg"
}

PLAY RECAP *******************************************************************************************************************
192.168.79.129 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.130 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.131 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.132 : ok=1 changed=0 unreachable=0 failed=0

ansible-playbook 命令行传入

通过ansible-playbook命令行传参的方式定义变量,默认传进去的都是全局变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@zero01 playbook]# ansible-playbook variable.yaml -e "key=ZERO"

PLAY [all] *******************************************************************************************************************

TASK [diplay Host Variable from hostfile] *******************************************************************************************************************
ok: [192.168.79.129] => {
"msg": "The 192.168.79.129 Value is ZERO"
}
ok: [192.168.79.130] => {
"msg": "The 192.168.79.130 Value is ZERO"
}
ok: [192.168.79.131] => {
"msg": "The 192.168.79.131 Value is ZERO"
}
ok: [192.168.79.132] => {
"msg": "The 192.168.79.132 Value is ZERO"
}

PLAY RECAP *******************************************************************************************************************
192.168.79.129 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.130 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.131 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.132 : ok=1 changed=0 unreachable=0 failed=0

这种方式同时支持传入多个变量,还支持指定文件的方式传入变量,变量的文件内容支持两种格式:YAML和JSON

YAML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[root@zero01 tmp]# cat var.yaml 
---
key: YAML
[root@zero01 playbook]# ansible-playbook variable.yaml -e "@/tmp/var.yaml"

PLAY [all] *******************************************************************************************************************

TASK [diplay Host Variable from hostfile] *******************************************************************************************************************
ok: [192.168.79.129] => {
"msg": "The 192.168.79.129 Value is YAML"
}
ok: [192.168.79.130] => {
"msg": "The 192.168.79.130 Value is YAML"
}
ok: [192.168.79.131] => {
"msg": "The 192.168.79.131 Value is YAML"
}
ok: [192.168.79.132] => {
"msg": "The 192.168.79.132 Value is YAML"
}

PLAY RECAP *******************************************************************************************************************
192.168.79.129 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.130 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.131 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.132 : ok=1 changed=0 unreachable=0 failed=0

JSON:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@zero01 tmp]# cat var.json 
{"key": "JSON"}
[root@zero01 playbook]# ansible-playbook variable.yaml -e "@/tmp/var.json"

PLAY [all] *******************************************************************************************************************

TASK [diplay Host Variable from hostfile] *******************************************************************************************************************
ok: [192.168.79.129] => {
"msg": "The 192.168.79.129 Value is JSON"
}
ok: [192.168.79.130] => {
"msg": "The 192.168.79.130 Value is JSON"
}
ok: [192.168.79.131] => {
"msg": "The 192.168.79.131 Value is JSON"
}
ok: [192.168.79.132] => {
"msg": "The 192.168.79.132 Value is JSON"
}

PLAY RECAP *******************************************************************************************************************
192.168.79.129 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.130 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.131 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.132 : ok=1 changed=0 unreachable=0 failed=0

在playbook文件内使用vars

1
2
3
4
5
6
7
8
9
[root@zero01 playbook]# vi variable.yaml 
---
- hosts: all
gather_facts: False
vars:
key: Ansible
tasks:
- name: diplay Host Variable from hostfile
debug: msg="The {{ inventory_hostname }} Value is {{ key }}"

直接运行,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@zero01 playbook]# ansible-playbook variable.yaml

PLAY [all] *******************************************************************************************************************

TASK [diplay Host Variable from hostfile] *******************************************************************************************************************
ok: [192.168.79.129] => {
"msg": "The 192.168.79.129 Value is Ansible"
}
ok: [192.168.79.130] => {
"msg": "The 192.168.79.130 Value is Ansible"
}
ok: [192.168.79.131] => {
"msg": "The 192.168.79.131 Value is Ansible"
}
ok: [192.168.79.132] => {
"msg": "The 192.168.79.132 Value is Ansible"
}

PLAY RECAP *******************************************************************************************************************
192.168.79.129 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.130 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.131 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.132 : ok=1 changed=0 unreachable=0 failed=0

如上,playbook文件中定义的变量对所有主机都有效,可理解为主机组变量。

在playbook文件内使用vars_files

1
2
3
4
5
6
7
8
9
[root@zero01 playbook]# cat variable.yaml 
---
- hosts: all
gather_facts: False
vars_files:
- /tmp/var.yaml
tasks:
- name: diplay Host Variable from hostfile
debug: msg="The {{ inventory_hostname }} Value is {{ key }}"

vars_files默认搜索当前路径,如果文件不在当前目录,需要指出绝对路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@zero01 playbook]# ansible-playbook variable.yaml 

PLAY [all] *******************************************************************************************************************

TASK [diplay Host Variable from hostfile] *******************************************************************************************************************
ok: [192.168.79.129] => {
"msg": "The 192.168.79.129 Value is YAML"
}
ok: [192.168.79.130] => {
"msg": "The 192.168.79.130 Value is YAML"
}
ok: [192.168.79.131] => {
"msg": "The 192.168.79.131 Value is YAML"
}
ok: [192.168.79.132] => {
"msg": "The 192.168.79.132 Value is YAML"
}

PLAY RECAP *******************************************************************************************************************
192.168.79.129 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.130 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.131 : ok=1 changed=0 unreachable=0 failed=0
192.168.79.132 : ok=1 changed=0 unreachable=0 failed=0

使用register内的变量

Ansible playbook内task之间还可以互相传递数据,比如我们总共有两个tasks,其中第2个task是否执行是需要判断第1个task运行后的结果,这个时候我们就得在task之间传递数据,需要把第1个task执行的结果传递给第2个task。

使用register传递数据

1
2
3
4
5
6
7
8
9
10
[root@zero01 playbook]# cat register.yaml 
---
- hosts: all
gather_facts: False
tasks:
- name: register variable
shell: hostname
register: info
- name: display variable
debug: msg="The variable is {{ info }}"

这里把第1个task执行hostname的结果register给info这个变量,然后第2个task把这个结果使用debug模板打印出来,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@zero01 playbook]# ansible-playbook register.yaml -l 192.168.79.129

PLAY [all] *******************************************************************************************************************

TASK [register variable] *******************************************************************************************************************
changed: [192.168.79.129]

TASK [display variable] *******************************************************************************************************************
ok: [192.168.79.129] => {
"msg": "The variable is {'stderr_lines': [], u'changed': True, u'end': u'2017-12-23 17:46:05.777637', 'failed': False, u'stdout': u'zero02', u'cmd': u'hostname', u'rc': 0, u'start': u'2017-12-23 17:46:05.768962', u'stderr': u'', u'delta': u'0:00:00.008675', 'stdout_lines': [u'zero02']}"
}

PLAY RECAP *******************************************************************************************************************
192.168.79.129 : ok=2 changed=1 unreachable=0 failed=0

info的结果是一段Python字典数据,存储着很多信息,包括执行时间状态变化输出等信息。从字典中,取出想要的值

1
2
3
4
5
6
7
8
9
10
[root@zero01 playbook]# cat register.yaml 
---
- hosts: all
gather_facts: False
tasks:
- name: register variable
shell: hostname
register: info
- name: display variable
debug: msg="The variable is {{ info['stdout'] }}"

修改register.yaml文件内容,info[‘stdout’]是一个标准的Python语言在字典中取值的用法,执行playbook,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@zero01 playbook]# ansible-playbook register.yaml -l 192.168.79.129

PLAY [all] *******************************************************************************************************************

TASK [register variable] *******************************************************************************************************************
changed: [192.168.79.129]

TASK [display variable] *******************************************************************************************************************
ok: [192.168.79.129] => {
"msg": "The variable is zero02"
}

PLAY RECAP *******************************************************************************************************************
192.168.79.129 : ok=2 changed=1 unreachable=0 failed=0

使用vars_prompt传入

Ansible支持在运行playbook的时,通过交互式的方式给定义好的参数传入参数值,只需在playbook中定义vars_prompt的变量名和交互式提示内容即可。

Ansible可以对输入的变量值进行加密处理,比如采用SHA512和MD5算法加密。需要注意:如果要对变量值进行加密,ansible机器上要安装passlib python库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@zero01 playbook]# cat prompt.yaml 
---
- hosts: all
gather_facts: False
vars_prompt:
- name: "one"
prompt: "Please input one value"
private: no
- name: "two"
prompt: "Please input two value"
default: 'good'
private: yes
tasks:
- name: display one value
debug: msg="one value is {{ one }}"
- name: display two value
debug: msg="two value is {{ two }}"

one为非私有变量,two为私有变量,private的作用是交互模式下是否显示输入的变量值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@zero01 playbook]# ansible-playbook prompt.yaml -l 192.168.79.129
Please input one value: Ansible
Please input two value [good]:

PLAY [all] *******************************************************************************************************************

TASK [display one value] *******************************************************************************************************************
ok: [192.168.79.129] => {
"msg": "one value is Ansible"
}

TASK [display two value] *******************************************************************************************************************
ok: [192.168.79.129] => {
"msg": "two value is zero"
}

PLAY RECAP *******************************************************************************************************************
192.168.79.129 : ok=2 changed=0 unreachable=0 failed=0