全局变量
全局变量是我们使用 Ansible 或 Playbook 时,手动通过 -e 参数传递给 Ansible 的变量。获取具体格式和使用方法:
[root@wpf ~]# ansible -h |grep var
path for many features including roles/ group_vars/
-e EXTRA_VARS, --extra-vars EXTRA_VARS
set additional variables as key=value or YAML/JSON, if
[root@wpf ~]# ansible-playbook -h |grep var
-e EXTRA_VARS, --extra-vars EXTRA_VARS
set additional variables as key=value or YAML/JSON, if
示例一:普通形式的变量传参
#-e "var=wpf"
[root@wpf ~]# ansible all -i wpf002, -m debug -a "msg='my name is {{ var }}'" -e "var=wpf"
wpf002 | SUCCESS => {
"msg": "my name is wpf"
}
示例二:JSON 文件形式的变量传参
#-e @test.json
cat << EOF > test.json
{"var":"wpf","age":18}
EOF
[root@wpf ~]# ansible all -i wpf002, -m debug -a "msg='my name is {{ var }} ,my {{ age }} years old'" -e @test.json
wpf002 | SUCCESS => {
"msg": "my name is wpf ,my 18 years old"
}
示例三:YAML 文件形式的变量传参
# -e @test.yml
cat << EOF > test.yml
var: wpf
age: 18
EOF
[root@wpf ~]# ansible all -i wpf002, -m debug -a "msg='my name is {{ var }} ,my {{ age }} years old'" -e @test.yml
wpf002 | SUCCESS => {
"msg": "my name is wpf ,my 18 years old"
}
·
剧本变量
剧本变量定义在 Playbook 中。
注意: Playbook 中的变量必须要引起来。例如:"{{ user }}"。
示例一:通过 Play 属性 vars 定义剧本变量
---
- name: A simple paly example
hosts: wpf002
remote_user: root
vars:
user: wpf
group: ansible
tasks:
- name: create user "{{ user }}"
user:
name: "{{ user }}"
groups: "{{ group }}"
示例二:通过 Play 属性 vars_files 定义剧本变量
cat << EOF > user_test.yml
user: wpf
group: ansible
EOF
---
- name: A simple paly example
hosts: wpf003
remote_user: root
vars_files:
- /root/user_test.yml
tasks:
- name: create user "{{ user }}"
user:
name: "{{ user }}"
groups: "{{ group }}"
·
资产变量
资产变量分为主机变量和组变量,分别针对资产中的单个主机和组。
主机变量
cat << EOF > test_inventory.ini
[wpf]
wpf002 user=pwf002
wpf003
wpf004
EOF
[root@wpf ~]# ansible wpf002 -i test_inventory.ini -m debug -a "msg='user is {{ user }}'"
wpf002 | SUCCESS => {
"msg": "user is pwf002"
}
组变量
cat << EOF > test_inventory.ini
[wpf]
wpf002
wpf003
wpf004
[wpf:vars]
user=wpf
EOF
[root@wpf ~]# ansible wpf002 -i test_inventory.ini -m debug -a "msg='user is {{ user }}'"
wpf002 | SUCCESS => {
"msg": "user is wpf"
}
·
主机变量 VS 组变量
当主机变量和组变量发生冲突时,以主机变量为准。 可以理解为全局变量和局部变量,以局部变量为准。
cat << EOF > test_inventory.ini
[wpf]
wpf002 user=wpf002
wpf003
wpf004
[wpf:vars]
user=wpf
EOF
[root@wpf ~]# ansible all -i test_inventory.ini -m debug -a "msg='user is {{ user }}'"
wpf004 | SUCCESS => {
"msg": "user is wpf"
}
wpf002 | SUCCESS => {
"msg": "user is wpf002"
}
wpf003 | SUCCESS => {
"msg": "user is wpf"
}
·
资产内置变量
内置变量几乎都是以 ansible_ 为前缀。
- ansible_ssh_host:将要连接的远程主机名与你想要设定的主机的别名不同的话,可通过此变量设置。
- ansible_ssh_port:ssh 端口号。如果不是默认端口,通过此变量设置。
- ansible_ssh_user:默认 ssh 用户名。
- ansible_ssh_pass:ssh 密码。这种方式不安全,官方建议使用
--ask-pass
或秘钥。 - ansible_sudo_pass:sudo 密码。这种方式不安全,官方建议使用
--ask-pass
或秘钥。 - ansible_sudo_exe:sudo 命令路径。
- ansible_python_interpreter:目标主机的 python 路径。适用于系统中有多个 python 的情况。或者 python 不在/usr/bin/下。
- ansible_ssh_private_key_file:ssh使用的私钥文件。适用于多个秘钥,而你不想使用SSH代理的情况。
cat << EOF > test_inventory.ini
[wpf]
wpf002 ansible_ssh_port=2222
wpf003
wpf004
[wpf:vars]
user=wpf
EOF
·
Facts 变量
Facts 变量不需要人为去声明,它的声明和赋值完全由 Ansible 中的 setup 模块完成。它收集了有关被管理服务器的操作系统版本、IP地址、主机名、磁盘使用率、CPU、内存使用率等信息。
在每次 Playbook 运行的时候,会发现在 Playbook 执行前都会有一个 Gathering Facts 的过程,这个过程就是收集被管理节点的 Facts 信息过程。
·
手动收集 Facts 变量
ansible all -i wpf002, -m setup
·
使用 filter 过滤 Facts 变量
[root@wpf ~]# ansible all -i wpf002, -m setup -a "filter=*memory*"
wpf002 | SUCCESS => {
"ansible_facts": {
"ansible_memory_mb": {
"nocache": {
"free": 3551,
"used": 238
},
"real": {
"free": 3161,
"total": 3789,
"used": 628
},
"swap": {
"cached": 0,
"free": 3967,
"total": 3967,
"used": 0
}
},
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
·
在 Playbook 中使用 Facts 变量(无需定义,直接引用即可)
---
- name: A simple paly example
hosts: wpf002
remote_user: root
tasks:
- name: debug test var
debug: msg='python path is {{ discovered_interpreter_python }} '
·
在 Playbook 中关闭 Facts 变量的获取(可以加速 Playbook 的执行速度)
---
- name: A simple paly example
hosts: wpf002
remote_user: root
gather_facts: no
tasks:
...
·
注册变量
Absible 的模块在运行之后,其实都会返回一些"返回值",只是默认情况下,不会显示而已,我们可以把这些"返回值"写入到某个变量中,这样我们就能通过引用对应的变量从而获取到这些返回值,这种将模块值写入到变量中的方法被称为"注册变量"。
所以,它的作用很明显,就是用于保存一个 task 任务的执行结果,以便于 debug 时使用。或者将此次 task 任务的结果作为条件,去判断是否执行其他的 task 任务。在 Playbook 中通过 register 关键字实现。
---
- name: A simple paly example
hosts: wpf002
remote_user: root
tasks:
- name: shell test
shell: "echo test > /tmp/testfile"
register: echo_result
- name: print result
debug:
var: echo_result
·
[root@wpf ~]# ansible-playbook playbook.yml
...
TASK [print result] ************************************************
ok: [wpf002] => {
"echo_result": {
"changed": true,
"cmd": "echo test > /tmp/testfile",
"delta": "0:00:00.006247",
"end": "2021-02-21 18:20:26.088126",
"failed": false,
"rc": 0,
"start": "2021-02-21 18:20:26.081879",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}
}
...
从上述返回信息可以看出,返回值是 json 格式的。如果想要返回某一些特定值,只需要指定键值对中的 key 即可。例如:获取cmd
---
- name: A simple paly example
hosts: wpf002
remote_user: root
tasks:
- name: shell test
shell: "echo test > /tmp/testfile"
register: echo_result
- name: print result
debug:
msg: "{{ echo_result.cmd }}"
·
变量优先级
目前介绍了全局变量、剧本变量、资产变量、Facts 变量和注册变量。其中 Facts 变量不需要人为去声明、复制;注册变量只需要通过关键字 register 声明,而不需要赋值。
所以变量的优先级讨论,将着重从全局变量、剧本变量、资产变量这三类变量去分析。
示例一:全局变量、剧本变量、资产变量三类变量都定义的优先级
cat << EOF > ansiblehosts
[wpf]
wpf002
wpf003
wpf004
[wpf:vars]
user=wpf_hosts
EOF
---
- name: A simple paly example
hosts: wpf002
remote_user: root
vars:
user: wpf_play
tasks:
- name: debug var test
debug:
msg: 'user is {{ user }}'
[root@wpf ~]# ansible-playbook -i ansiblehosts playbook.yml -e "user=wpf_adhoc"
...
TASK [debug var test] ***************
ok: [wpf002] => {
"msg": "user is wpf_adhoc"
}
...
·
示例二:剧本变量、资产变量都定义的优先级
[root@wpf ~]# ansible-playbook -i ansiblehosts playbook.yml
...
TASK [debug var test] ****************
ok: [wpf002] => {
"msg": "user is wpf_play"
}
...
·
变量优先级总结
全局变量 > 剧本变量 > 资产变量