一、Playbook中vars关键字定义的变量

Playbook中定义和使用的变量的方法

用户可以在Playbook中,通过vars关键字自定义变量,使用时用{{ }}引用以来即可。

下面的例子中,用户定义变量名为http_port,其值为为80。在tasks firewalld中,通过{{ }}引用

1
2
3
4
5
6
7
- hosts: web
vars:
http_port: 80
remote_user: root
tasks:
- name: insert firewalld rule for httpd
firewalld: port={{ http_port }}/tcp permanent=true state=enabled immediate=yes

把变量放在单独的文件中

当变量比较多的时候,或者变量需要在多个playbook中重用的时候,可以把变量放到一个单独的文件中。通过关键字var_files把文件中定义的变量引入playbook中,使用变量的方法和在本文件中定义的变量相同。

1
2
3
4
5
6
7
- hosts: web
remote_user: root
vars_files:
- vars/server_vars.yml
tasks:
- name: insert firewalld rule for httpd
firewalld: port={{ http_port }}/tcp permanent=true state=enabled immediate=yes

变量文件vars/server_vars.yml的内容为:

1
http_port: 80

定义和使用复杂变量

有时候我们需要使用的变量的值不是简单的字符串或者数字,而是一个对象。这时候定义的语法如下,格式为YAML的字典格式:

1
2
3
foo:
field1: one
field2: two

访问复杂变量中的子属性,可以利用中括号或者点号:

1
2
foo['field1']
foo.field1

YAML的陷阱

YAML的陷阱是某些时候YAML和Ansible Playbook的变量语法不能在一起好好工作了。这里仅发生在指冒号后面的值不能以{开头的时候,如果有必要以{开头,必须加上引号。总之在YAML值的定义中,如果提示YMAL语法错误,都可以尝试下加入引号来解决。
下面的代码会报错:

1
2
3
- hosts: app_servers
vars:
app_path: {{ base_path }}/22

解决办法:要在”{ “开始的值加上引号:

1
2
3
- hosts: app_servers
vars:
app_path: "{{ base_path }}/22"

二、主机的系统变量(gather_facts)

ansible会通过module setup来收集主机的系统信息,这些收集到的系统信息叫做facts,这些facts信息可以直接以变量的形式使用。
哪些facts变量可以引用呢?在命令行上通过调用setup module命令可以查看

1
$ ansible all -m setup -u root

怎样在playbook中使用facts变量呢,答案是直接使用:

1
2
3
4
5
6
7
8
9
10
11
12
---
- hosts: all
user: root
tasks:
- name: echo system
shell: echo {{ ansible_os_family }}
- name install ntp on Debian linux
apt: name=git state=installed
when: ansible_os_family == "Debian"
- name install ntp on redhat linux
yum: name=git state=present
when: ansible_os_family == "RedHat"

使用复杂facts变量
一般在系统中收集到如下的信息,复杂的、多层级的facts变量如何使用呢?

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
...
"ansible_ens3": {
"active": true,
"device": "ens3",
"ipv4": {
"address": "10.66.192.234",
"netmask": "255.255.254.0",
"network": "10.66.192.0"
},
"ipv6": [
{
"address": "2620:52:0:42c0:5054:ff:fef2:e2a3",
"prefix": "64",
"scope": "global"
},
{
"address": "fe80::5054:ff:fef2:e2a3",
"prefix": "64",
"scope": "link"
}
],
"macaddress": "52:54:00:f2:e2:a3",
"module": "8139cp",
"mtu": 1500,
"promisc": false,
"type": "ether"
},
...

那么可以通过下面的两种方式访问复杂的变量中的子属性:
中括号:

1
{{ ansible_ens3["ipv4"]["address"] }}

点号:

1
{{ ansible_ens3.ipv4.address }}

关闭facts

在Playbook中,如果写gather_facts来控制是否收集远程系统的信息.如果不收集系统信息,那么上面的变量就不能在该playybook中使用了.

1
2
- hosts: whatever
gather_facts: no

三、template文件模板中使用的变量

template变量的定义(more)

在playbook中定义的变量,可以直接在template中使用,同时facts变量也可以直接在template中使用,当然也包含在inventory里面定义的host和group变量。只要是在playbook中可以访问的变量,都可以在template文件中使用。


四、把task运行结果进行注册变量

把task的执行结果也可以作为一个变量值。这个时候就需要用到register关键字实现注册变量,将执行结果注册到一个变量中,待后面的action使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
---

- hosts: web

tasks:
- shell: ls
register: result
ignore_errors: True

- shell: echo "{{ result.stdout }}"
when: result.rc == 5

- debug: msg="{{ result.stdout }}"

注册变量经常和debug module一起使用,这样可以得到更多action的输出信息,帮助用户调试。


五、playbook 命令行变量传值

为了使Playbook更灵活、通用性更强,允许用户在执行的时候传入变量的值,这个时候就需要用到“额外变量”。

定义命令行变量

在release.yml文件里,hosts和user都定义为变量,需要从命令行传递变量值。

1
2
3
4
5
6
7
---

- hosts: '{{ hosts }}'
remote_user: '{{ user }}'

tasks:
- ...

使用命令行变量

在命令行里面传值得的方法:
ansible-playbook e33_var_in_command.yml --extra-vars "hosts=web user=root"
还可以用json格式传递参数:
ansible-playbook e33_var_in_command.yml --extra-vars "{'hosts':'vm-rhel7-1', 'user':'root'}"
还可以将参数放在文件里面:
ansible-playbook e33_var_in_command.yml --extra-vars "@vars.json"