Ansible Variables
group_vars 概述
参考:
虽然通过自动化可以使事情更简单、更可重复,但是并非所有系统都完全相同。在某些情况下,观察到一个系统的行为或状态可能会影响到配置其他系统的方式。比如,我们可能需要找出一个系统的 IP 地址,并将这个 IP 地址作为另一个系统中配置的值。
基于上述目的,Ansible 可以通过 Variables(变量) 来管理各个系统之间的差异。
Ansible 的变量就跟编程语言中的变量概念一样,同样可以定义、引用。我们使用标准的 YAML 语法创建变量,包括列表和字典;可以这么说,YAML 中每个字段的 key 就是变量名,value 就是变量的值。我们可以在 Playbooks、Inventory、甚至命令行中定义与引用变量。我们还可以在 Playbooks 运行期间,将任务的返回值注册为变量,以创建一个新的变量。
创建变量后,我们可以在 模块的参数、模板、控制结构 中使用这些变量。在 GitHub 中有一个 Ansible 示例的目录,可以看到很多 Ansible 使用变量的例子
下面的示例就是在命令行中使用 debug 模块,查看了一下 inventory_hostname 这个默认变量的值
~]$ ansible -i ../inventory/ all -m debug -a 'msg={{inventory_hostname}}'
hw-cloud-xngy-jump-server-linux-2 | SUCCESS => {
"msg": "hw-cloud-xngy-jump-server-linux-2"
}
变量的优先级
变量可以是自带的,就是由人们自行定义的,可以在多个地方定义变量,(e.g.在某些文件里定义变量、通过命令行传递变量等等。由于 ansible 所要处理的的文件有很多,不同类型的文件下定义的变量的优先级也不同)
下面的优先级列表由低到高,最下面的变量优先级最高
- command line values (eg “-u user”)
- role defaults # 定义在
${ROLE}/defaults/main.yaml中的默认变量 - inventory file or script group vars # Inventory 文件中的组变量,即.
[XXX:vars] - inventory group_vars/all # Inventory 文件所在目录下的
group_vars/all文件。也可以是group_vars/all.yaml文件 - playbook group_vars/all # Playbook 根目录下的
group_vars/all文件。也可以是group_vars/all.yaml文件 - inventory group_vars/ # Inventory 文件所在目录下的
group_vars/目录 - playbook group_vars/ # Playbook 根目录下的
group_vars/目录 - inventory file or script host vars # Inventory 文件中的主机变量
- inventory host_vars/ # Inventory 文件所在目录下的
host_vars/目录 - playbook host_vars/ # Playbook 根目录下的
host_vars/目录 - host facts / cached set_facts #
- play vars #
- play vars_prompt #
- play vars_files #
- role vars # 定义在
${ROLE}/vars/main.yml中的变量 - block vars (only for tasks in block) #
- task vars (only for the task) #
- include_vars #
- set_facts / registered vars #
- role (and include_role) params #
- include params #
- extra vars # 通过 ansible-playbook 命令行工具的
-e, --extra-vars参数指定的变量
Note:可以说 ansible playbook 中写的所有内容都是变量。都是可以引用的,只不过引用的方式不同。
变量的定义与引用
变量名应为字母、数字、下划线。并且始终应该以字母开头。可以在 Inventory、Playbooks、命令行 中定义变量。Ansible 会加载它找到的每个可能的变量,然后根据变量优先级规则选择要应用的变量
可以通过 -e 选项直接定义一个变量,比如 ansible -e "test_var=hello_world",这里定义了 test_var 变量,变量的值为 hello_world。
Ansible 使用 Jinja2 语法引用变量。Jinjia2 使用 {{ VarName }} 来引用变量,比如
~/projects/DesistDaydream/ansible/playbooks]$ ansible -i ../inventory/ all --extra-vars "test_var=hello_world" -m debug -a 'msg={{test_var}}'
hw-cloud-xngy-jump-server-linux-2 | SUCCESS => {
"msg": "hello_world"
}
上面的例子中,我们定义了一个名为 test_var 的变量,变量的值为 hello_world,并使用 debug 模块,引用 test_var 变量。
这只是最简单的变量的使用方式,命令行中不适合设置复杂格式的变量,更为复杂的类型的变量,通常在 YAML 或 JSON 格式的文件中定义,并直接引用文件即可定义变量(比如使用 --extra-vars "@./test_var.yaml" 选项,即可通过 test_var.yaml 文件定义变量)
变量的类型
List(列表)变量
[desistdaydream@hw-cloud-xngy-jump-server-linux-2 ~/projects/DesistDaydream/ansible/playbooks]$ cat test_var.yaml
region:
- northeast
- southeast
- midwest
[desistdaydream@hw-cloud-xngy-jump-server-linux-2 ~/projects/DesistDaydream/ansible/playbooks]$ ansible -i ../inventory/ all --extra-vars "@./test_var.yaml" -m debug -a 'msg={{region[1]}}'
hw-cloud-xngy-jump-server-linux-2 | SUCCESS => {
"msg": "southeast"
}
Dictionary(字典)变量
可以通过两种方式引用字典变量
- 使用方
[]进行引用- foo[‘field1’]
- 使用
.进行引用(不推荐使用该方式引用变量,可能会与 Python 语法产生冲突)- foo.field1
[desistdaydream@hw-cloud-xngy-jump-server-linux-2 ~/projects/DesistDaydream/ansible/playbooks]$ cat test_var.yaml
foo:
field1: one
field2: two
[desistdaydream@hw-cloud-xngy-jump-server-linux-2 ~/projects/DesistDaydream/ansible/playbooks]$ ansible -i ../inventory/ all --extra-vars "@./test_var.yaml" -m debug -a msg="{{foo['field1']}}"
hw-cloud-xngy-jump-server-linux-2 | SUCCESS => {
"msg": "one"
}
[desistdaydream@hw-cloud-xngy-jump-server-linux-2 ~/projects/DesistDaydream/ansible/playbooks]$ ansible -i ../inventory/ all --extra-vars "@./test_var.yaml" -m debug -a msg="{{foo.field1}}"
hw-cloud-xngy-jump-server-linux-2 | SUCCESS => {
"msg": "one"
}
Note:如果使用 . 引用变量可能会引起问题,因为会与 python 字典的属性和方法冲突。所以,尽量使用 [] 来引用变量
Registering(注册)变量
Registering 类型的变量适用于 Playbooks 中,通过 register 关键字将任务中的返回值注册为指定的变量,然后可以在 Playbooks 的后续任务中,引用注册的变量
比如
[desistdaydream@hw-cloud-xngy-jump-server-linux-2 ~/projects/DesistDaydream/ansible/playbooks]$ cat roles/variables/tasks/main.yaml
- name: test
command: whoami
register: info
- name: debug
debug:
msg: "{{info}}"
[desistdaydream@hw-cloud-xngy-jump-server-linux-2 ~/projects/DesistDaydream/ansible/playbooks]$ ansible-playbook -i ../inventory/ variables.yaml
PLAY [test] **********************************************************************************************************************************************************************************************************************************************************************************************************************************************************
TASK [variables : test] **********************************************************************************************************************************************************************************************************************************************************************************************************************************************
changed: [hw-cloud-xngy-jump-server-linux-2]
TASK [variables : debug] *********************************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [hw-cloud-xngy-jump-server-linux-2] => {
"msg": {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"cmd": [
"whoami"
],
"delta": "0:00:00.002390",
"end": "2021-10-11 22:57:18.455061",
"failed": false,
"rc": 0,
"start": "2021-10-11 22:57:18.452671",
"stderr": "",
"stderr_lines": [],
"stdout": "root",
"stdout_lines": [
"root"
]
}
}
PLAY RECAP ***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************
hw-cloud-xngy-jump-server-linux-2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
在 test 任务中,我们将 command 模块执行的任务返回值,注册到 info 变量中;然后再 debug 任务中,引用了 info 变量。
有关在后续任务的条件中使用注册变量的更多示例,请参阅条件。注册变量可以是简单变量、列表变量、字典变量或复杂的嵌套数据结构。每个模块的文档包括 RETURN 描述该模块返回值的部分。要查看特定任务的值,请使用-v. 注册的变量存储在内存中。您不能缓存已注册的变量以供将来使用。注册的变量仅在当前 playbook 运行的其余部分在主机上有效。
注册变量是主机级变量。当您使用循环在任务中注册变量时,注册的变量包含循环中每个项目的值。循环期间放置在变量中的数据结构将包含一个 results 属性,即来自模块的所有响应的列表。有关其工作原理的更深入示例,请参阅有关将寄存器与循环一起使用的循环部分。
注意:如果任务失败或被跳过,Ansible 仍会注册一个处于失败或跳过状态的变量,除非根据标签跳过该任务。有关添加和使用标签的信息,请参阅标签。
Nested(嵌套)变量
[desistdaydream@hw-cloud-xngy-jump-server-linux-2 ~/projects/DesistDaydream/ansible/playbooks]$ cat test_var.yaml
foo:
- field1:
name: one
- field2:
name: two
[desistdaydream@hw-cloud-xngy-jump-server-linux-2 ~/projects/DesistDaydream/ansible/playbooks]$ ansible -i ../inventory/ all --extra-vars "@./test_var.yaml" -m debug -a msg="{{foo[0].field1.name}}"
hw-cloud-xngy-jump-server-linux-2 | SUCCESS => {
"msg": "one"
}
变量的定义方式
在命令行中定义变量
在使用 ansible 或 ansible-playbook 命令时,可以通过 –extra-vars 或 -e 选项,以在命令行中定义变量
可以通过多种方式在命令行定义变量
- KEY=VALUE
~/projects/DesistDaydream/ansible/playbooks]$ ansible -i ../inventory/ all --extra-vars "test_var=hello_world" -m debug -a 'msg={{test_var}}'
hw-cloud-xngy-jump-server-linux-2 | SUCCESS => {
"msg": "hello_world"
}
- JSON 字符串
~/projects/DesistDaydream/ansible/playbooks]$ ansible -i ../inventory/ all --extra-vars '{"test_var":"hello world"}' -m debug -a 'msg={{test_var}}'
hw-cloud-xngy-jump-server-linux-2 | SUCCESS => {
"msg": "hello world"
}
- 来自 JSON 或 YAML 文件
~/projects/DesistDaydream/ansible/playbooks]$ cat test_var.yaml
test_var: 'hello world'
~/projects/DesistDaydream/ansible/playbooks]$ ansible -i ../inventory/ all --extra-vars "@./test_var.yaml" -m debug -a 'msg={{test_var}}'
hw-cloud-xngy-jump-server-linux-2 | SUCCESS => {
"msg": "hello world"
}
在 Inventory 中定义变量
详见 Inventory 文件
在 Playbooks 中定义变量
基础的定义方式是在一个 play 中使用 vars 关键字定义变量,示例如下
- host: webservers
vars:
http_port: 80 # 定义一个名为http_port的变量,值为80
tasks:
- debug
Note: vars 关键字可以用在 host 环境中,也可以用在 tasks 环境中,用在 tasks 环境时,则变量仅对当前任务生效
下面是一个在角色中定义字典类型变量的样例:
[root@cobbler playbook]# cat roles/test/defaults/main.yml
docker:
version: 18.06.2
dataDir: /var/lib/docker
registryMirrors:
- https://ac1rmo5p.mirror.aliyuncs.com
execOpts:
- 'native.cgroupdriver=systemd'
insecureRegistries:
- 100.64.2.52:9999
- 100.64.1.31:9999
变量的引用方式
特殊情况不用加 {{ }} 而可以直接引用,比如在某些控制结构(比如 when)的语句中。
Registering Variables(注册变量)
通常在剧本中,将给定命令的结果存储在变量中并在以后访问它可能很有用。
注意:
- 注册变量只适用于执行本注册任务的 host。假如在 host_A 注册了 Var_A,那么 host_B 想要引用 Var_A,则必须使用
hostvars变量。
应用示例:
- hosts: all
tasks:
- name: list contents of directory
command: ls /root/
register: contents # 将该任务执行后的ansible报告的信息保存在名为contents变量中
- debug:
msg: "{{contents}}" # 输出contents变量
- debug:
msg: "{{contents.stdout}}" # 输出contents下的stdout变量的值,值为anaconda-ks.cfg\nScripts
比如下面,就是是 contents 变量的值。这其中包括要执行的命令、命令执行的日期、执行结果,等等 ansible 执行该 playbook 后的信息。
TASK [debug] *************************************************************
ok: [10.10.100.200] => {
"msg": {
"changed": true,
"cmd": [
"ls",
"/root/"
],
"delta": "0:00:00.004220",
"end": "2019-11-11 15:02:17.326659",
"failed": false,
"rc": 0,
"start": "2019-11-11 15:02:17.322439",
"stderr": "",
"stderr_lines": [],
"stdout": "anaconda-ks.cfg\nScripts",
"stdout_lines": [
"anaconda-ks.cfg",
"Scripts"
]
}
}
还可以将 register 与循环配合使用,通过命令获取的多个值注册到变量中,然后使用循环逐一读取变量的值
- name: retrieve the list of home directories
command: ls /home
register: home_dirs
- name: add home dirs to the backup spooler
file:
path: /mnt/bkspool/{{ item }}
src: /home/{{ item }}
state: link
loop: "{{ home_dirs.stdout_lines }}" # loop也可以使用这样的方式来获取每一行的值: "{{ home_dirs.stdout.split() }}"
这个例子就是查看/mnt/bkspool/目录下的内容,然后将其中所有文件注意拷贝到/home/目录下
Special Variables(特殊的变量)
参考:
无论是否定义任何变量,都可以使用 Ansible 提供的特殊变量访问有关主机的信息,一共有如下几种变量类型:
- magic variables(魔法变量)
- facts variables(事实变量)
- connection variables(连接变量)
Magic Variables
官方文档:https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html#magic
魔术变量不能随意覆盖并且也没法覆盖,这是一种 Ansbie 提供的"内部变量" ,可以反映 Ansible 所管理主机的最简单的基本状态,比如该主机的主机名、在 inventory 文件中的定义都会转换成这里面变量的值、等等。
可以通过目标主机获取到 ansible 管理的所有主机的信息。最常用的魔术变量有以下几个
- hostvars # 每个目标主机下面都包含类似下图的信息。其中是每个组所包含的 hosts
- 注意:通过 hostvars 变量,我们还可以获取到其他主机在执行任务是注册的变量,比如在 kubernetes 集群的 master-1 上生成了加入集群的指令,并注册为变量 join_cmd,正常是无法在其他主机直接使用的。这时候就要用到 hostvars 变量了。

- ansible_play_hosts # 一个列表,是当前 play 中活动的主机列表,受序号限制,无法访问的主机不会被当做“活动”主机。
- 该变量可以用于 for 循环,对列表中的主机进行遍历,逐一操作。
- 等同于 ansible_play_batch
- ansible_play_name # 当前执行 paly 的名称。i.e.playbook 中 hosts 这个键的值,也就是当前的主机组名称
- groups # 默认值为 inbentory 下所有组及其组内的 host
- group_names # 默认值为当前主机所属组的列表。
- inventory_hostname # 默认值为 inventory 文件中配置的主机名称。i.e. ansible 的 hosts 文件的第一列内容
- inventory_dir # 默认值为 ansible 保存 hosts 文件的目录的绝对路径。默认路径为/etc/ansible/
- play_hosts # 默认值为当前 play 范围中可用的一组主机名
- role_path # 默认值为当前 role 的目录的绝对路径
应用实例:
groups["{{ansible_play_name}}"] # 获取当前 play 下的主机列表
Fact Variables
Ansible 在执行任务之前,会收集被控制节点的系统及应用程序的 facts(可以理解为:事实信息)。并将这些信息存储到 ${ansible_facts} 变量中以供后续使用。
详见 《Fact Variables》
Connection Variables
应用示例
获取组中的主机数量
vars:
HOST_COUNT: "{{ groups['组名'] | length }}"
获取 test 组中主机的总数量
~]$ ansible -i ../inventory/ all -m debug -a "msg={{ groups['test'] | length }}"
hw-cloud-xngy-jump-server-linux-2 | SUCCESS => {
"msg": "1"
}
反馈
此页是否对你有帮助?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.