七、变量的定义和引用
七、变量的定义和引用
7.1 变量的引用和调试
变量的调试
在ansible中有一个debug模块,专门用来打印输出调试信息。它只有两个参数msg和var。
- msg:打印信息,类似于shell的echo和python的print
- var:只能打印变量信息
- name: install httpd
hosts: all
vars:
username: zhangsan
password: 123456
tasks:
- name: print msg
debug:
msg: "username is {{ username }}"
- name: print var
debug:
var: password

变量的引用
如上面的例子,变量的引用,在绝大部分场景下,都需要用"{{ 变量名 }}"的方式来引用。
- 引用变量
- name: test vars
hosts: node1
vars:
username: zhangsan
uid: 2000
shell: /sbin/nologin
tasks:
- name: create user
user:
name: "{{ username }}"
uid: "{{ uid }}"
shell: "{{ shell }}"
state: present
- 引用数组
- name: test list
hosts: node1
vars:
names:
- zhangsan
- lisi
- wangwu
tasks:
- name: print all
debug:
msg: "{{ names }}"
- name: print first value
debug:
msg: "{{ names[0] }}"
- name: print second value
debug:
msg: "{{ names[1] }}"
引用数组的时候,和python列表一样需要用到下标,也就是索引,第一个元素索引为0,第二个元素为1,以此类推...

- 引用对象
- name: test object
hosts: node1
vars:
names:
zhangsan:
uid: 2000
shell: /bin/bash
lisi:
uid: 2001
shell: /sbin/nologin
wangwu:
uid: 2002
shell: /bin/bash
tasks:
- name: print zhangsan
debug:
msg: "{{ names.zhangsan.uid }}"
- name: print lisi
debug:
msg: "{{ names['lisi']['uid'] }}"
引用对象的时候,用.来引用,也可以使用python的字典风格,用key来当做索引引用。

7.2 变量的定义
在Ansible中一共有7种方式可以定义变量。分别为:
- 在主机清单中定义
- 在playbook中vars定义
- 在playbook中vars_files引入变量文件
- 在host_vars和group_vars目录中定义
- 将任务的执行结果注册到变量
- 通过命令行设置临时变量
7.2.1 主机清单中定义
在ansible中有许多内置的变量,他们都以ansible开头,例如ansible_port,这些变量的值通常取的ansible配置文件的配置项,如果ansible.cfg没有配置,则会使用默认配置。
覆盖内置变量
在ansible连接主机的时候,往往会遇到这种场景,不同的主机ssh端口不同、主机的管理用户不同、甚至密码不同,而这些信息都在ansible的配置文件中定义,只能全局定义成同一种,不能做到一台主机一个配置,这时候我们可以在主机清单文件中定义ansbile的内置变量去覆盖ansible的配置文件配置。
如下面的主机清单,表示ansible在连接这两台主机的时候,连接的用户名和ssh端口将用主机清单中定义的值。
192.168.1.1 ansible_user=admin ansible_port=2222
192.168.1.2 ansible_user=devops ansible_port=2223
常用的其他内置主机变量
-
ansible_host:用于指定被管理的主机的真实IP
-
ansible_port:用于指定连接到被管理主机的ssh端口号
-
ansible_user:用于指定ssh连接时使用的用户名
-
ansible_become:是否开启提权
-
ansible_become_user:指定提权到的用户
-
ansible_become_pass:指定提权到的用户密码
定义普通变量
[root@master ansible]# cat hosts
node1 server_name=httpd # 定义主机变量
[test]
node2
[test:vars] # 定义主机组变量
server_name=nginx
[root@master ansible]# cat test.yml
- name: install httpd
hosts: all
tasks:
- name: print vars
debug:
msg: "{{ server_name }}"

需要注意主机清单中的变量,仅对主机和主机组生效,task在执行到其他未定义变量主机的时候,则会找不到该变量。
7.2.2 playbook中定义
这里在第六章Variable section介绍过,不再赘述。
7.2.3 特定目录中定义
在Ansible中,有两个特殊的目录,ansible会自动引用这两个目录下对应文件中的变量。
- host_vars:该目录下存放主机的变量,文件名应该以主机清单中的主机名命名
- group_vars:该目录下存放主机组的变量,文件名应该以主机清单中的主机组名命名
实验
- 创建目录和变量文件,目录结构如下

- 编辑变量文件,文件内容如下
[root@master ansible]# cat host_vars/node1
content: This is node1 var
[root@master ansible]# cat group_vars/test
content: This is test group var
- playbook中直接调用变量
- name: test vars
hosts: all
tasks:
- name: print var
debug:
var: content

7.2.4 注册变量
在有些时候,可能需要将某一条任务执行的结果保存下来,以便在接下的任务中调用或者判断,可以通过register关键字来实现将某一任务的结果保存到变量中。
下面是个简单的例子,将ls /opt/命令执行的结果注册到变量files:
- name: register variables
hosts: node1
tasks:
- name: list files
shell: ls /opt
register: files
- name: print var
var: files

可以看到注册变量返回的是一个对象,其中的属性说明如下:
- files:注册变量名,register后边定义的
- changed:Ansible基于此字段判断是否发生了状态改变
- start:任务执行的开始时间
- end:任务执行的结束时间
- delta:任务执行的总时长
- failed:任务是否执行失败
- rc:任务的返回值,0代表正常,非0代表异常。
- stderr:错误输出,输出一个字符串,不换行
- stderr_lines:错误输出,输出一个列表,以换行分割
- stdout:标准输出,输出一个字符串,不换行
- stdout_lines:标准输出,输出一个列表,以换行分割
注:红色为常用属性
如果我们要获取ls /opt返回的结果,则可以调用stdout_lines属性
- name: register variables
hosts: node1
tasks:
- name: list files
shell: ls /opt
register: files
- name: print var
var: files.stdout_lines

7.2.5 命令中定义
我们也可以在执行playbook的时候通过参数定义变量。
如,我们在执行playbook的时候定义了一个username和uid变量,playbook通过访问临时变量去创建用户。
[root@master ansible]# cat test.yml
- name: test var
hosts: node1
tasks:
- name: create user
user:
name: "{{ username }}"
uid: "{{ uid }}"
state: present
[root@master ansible]# ansible-playbook test.yml --extra-vars "username=tom uid=3000"
PLAY [test var] ****************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************
ok: [node1]
TASK [create user] *************************************************************************************************************************
changed: [node1]
PLAY RECAP *********************************************************************************************************************************
node1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@master ansible]# ansible node1 -m shell -a 'id tom'
node1 | CHANGED | rc=0 >>
uid=3000(tom) gid=2001(tom) groups=2001(tom)

浙公网安备 33010602011771号