一、 变量介绍
变量可以说是一个语言的基石,也是灵魂。没有变量,一个程序就变成了一个死的程序了,就不能灵活运用了。
二、变量名的规则
- 变量的名字由大小写字母、下划线和数字组成
- 必须以字母开头
正确:
username: shark
age: 18
错误:
_name: shark
3_age: 18
不能使用如下关键字作为变量名称
add, append, as_integer_ratio, bit_length, capitalize, center, clear,
conjugate, copy, count, decode, denominator, difference,
difference_update, discard, encode, endswith, expandtabs,
extend, find, format, fromhex, fromkeys, get, has_key, hex,
imag, index, insert, intersection, intersection_update, isalnum,
isalpha, isdecimal, isdigit, isdisjoint, is_integer, islower,
isnumeric, isspace, issubset, issuperset, istitle, isupper,
items, iteritems, iterkeys, itervalues, join, keys, ljust, lower,
lstrip, numerator, partition, pop, popitem, real, remove,
replace, reverse, rfind, rindex, rjust, rpartition, rsplit, rstrip,
setdefault, sort, split, splitlines, startswith, strip, swapcase,
symmetric_difference, symmetric_difference_update, title,
translate, union, update, upper, values, viewitems, viewkeys,
viewvalues, zfill
三、变量的定义和使用
1 在资产清单中定义变量
定义主机变量
[slb]
192.168.122.10 app=xiuyun sn=001
[webNginx]
192.168.122.20
192.168.122.30
[nginx]
[nginx:children]
slb
webNginx
输出变量:
[root@master ~]# ansible slb -m debug -a "msg='{{app}} {{ sn }}'"
192.168.122.10 | SUCCESS => {
"msg": "xiuyun 1"
}
定义组变量
[webNginx:vars]
n=10
webNginx
是组名
输出变量:
- name: 测试变量
hosts: webNginx
gather_facts: no
tasks:
- name: 输出变量
debug:
msg: "{{ n }}"
资产清单中的默认变量
这些变量不能由用户设置。Ansible将始终覆盖它们以反映内部状态。
- name: 测试变量
hosts: webNginx
gather_facts: no
tasks:
- name: 输出变量
debug:
msg: |
资产名称: {{ inventory_hostname }}
当前主机所在的组: {{ group_names }}
此 playbook 所在的目录 {{ playbook_dir }}
还有一些变量用户设置后,默认直接调用的。
ansible_ssh_user
连接到远程主机的远程用户ansible_ssh_pass
连接到远程主机的远程用户的密码
示例:
下面的示例中我们定义了
主机 master 的远程用户为 root 密码为 upsa
主机 node1 的远程用户为 shark 密码为 456
/etc/ansible/hosts
[slb]
master sn=100 user=root ansible_ssh_user=root ansible_ssh_pass=upsa
[webNginx]
node1 sn=200 user=shark ansible_ssh_user=shark ansible_ssh_pass=456
[nginx]
[nginx:children]
slb
webNginx
[nginx:vars]
app=xiuyu
适用场景:
当不同的主机有不同的用户名或者不同的密码的情况下,就可以使用以上变量。
比如我们对一组主机做免密操作,就可以使用下面的 playbook
sendpub.yml
- name: 免密
hosts: all
tasks:
- name: xxx
#authorized_key: "user={{user}} state=present key={{ lookup('file', '/root/.ssh/id_rsa.pub') }}"
authorized_key:
user: "{{ user }}" # 这个变量已经在上面的 hosts 文件中定义过了
state: present
key: "{{ lookup('file', '/root/.ssh/id_rsa.pub') }}"
执行:
ansible-playbook sendpub.yml
2 在 playbook 中定义变量
直接写在 playbook 中
- name: 测试变量
hosts: webNginx
gather_facts: no
vars:
# 这里定义变量,一行一个
pkgs: ["tree", "vim"]
download_path: /opt/docker-pkgs
tasks:
- name: 输出变量
debug:
msg: "{{ pkgs }} {{ download_path }}"
写到一个单独的文件中,之后在 playbook 中引用
变量文件内容:
some.yaml
users:
- tom
- shark
enable: false
引用变量文件
- name: 测试变量
hosts: webNginx
gather_facts: no
vars_files:
# 引用变量文件
- ./some.yaml
tasks:
- name: 输出变量
debug:
msg: "{{ enable }} {{ users }}"
3 我希望变量从命令行里传递
接上例, 执行 playbook 的时候使用选项 -e
-e "key1=var1 key2=var2"
-e
传递的是全局变量,可以覆盖已经定义的自定义变量。
[root@master ~]# ansible-playbook t.yml -e "enable=true users=[1,2]"
PLAY [测试变量] ********************************************************************
TASK [输出变量] ********************************************************************
ok: [192.168.122.30] => {
"msg": "true [1,2]"
}
ok: [192.168.122.20] => {
"msg": "true [1,2]"
}
PLAY RECAP *********************************************************************
192.168.122.20 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.122.30 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
四、变量的优先级
全局 > Playbook 变量 > 资产清单中定义的变量
五、Facts 变量
默认情况下,每次执行 playbook 都有一个默认的 task, 这个就是
...
TASK [Gathering Facts] ****
...
这个任务是获取此次 playbook 中每个主机的基础系统信息的。
包括: 主机名、主机 IP,主机网卡信息、主机分区挂载信息等。
或者到后就可以在 palybook 中使用了。
Facts 变量也可以通过命令行获取
ansible 192.168.122.10 -m setup
使用 Facts 变量
- name: 测试变量
hosts: 192.168.122.26
vars_files:
- ./some.yaml
tasks:
- name: 输出变量
debug:
msg: "{{ ansible_all_ipv4_addresses.0 }} {{ansible_apparmor.status}}"
关闭
如果在 playbook 中用不到这些变量,就可以关闭它:
- name: 测试变量
hosts: webNginx
gather_facts: no # 关闭
...
验证:
[root@master ~]# ansible-playbook t.yml -i 192.168.122.26,
PLAY [测试变量] ********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.122.26]
TASK [输出变量] ********************************************************************
ok: [192.168.122.26] => {
"msg": "CPU: 2 内存: 3951"
}
PLAY RECAP *********************************************************************
192.168.122.26 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
六、注册变量
默认情况下,在执行 playbook 中的某个任务时候,我们并不能得到这个任务执行的结果,比如执行一条命令,命令的结果不论正确与否,都不能看到执行结果。
Ansible 提供一个变量注册的功能,可以把某个 task 执行的结果赋值给一个变量,之后在接下来的 task 中就可以使用这个变量了。
使用场景,判断上一个 task 是否执行成功,或者使用上一个 task 执行的结果来进行判断。
这个功能就是在某个 task 中添加 register: 变量名
来实现。
示例:
- name: 测试变量
hosts: slb
gather_facts: no
tasks:
- name: 执行 shell 命令
shell: getenforce
register: ret
- name: 输出变量
debug:
msg: "{{ ret }}"
输出结果:
...
TASK [输出变量] **********************************************************************
ok: [192.168.122.26] => {
"msg": {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"cmd": "getenforce",
"delta": "0:00:00.014309",
"end": "2021-05-25 14:41:42.742676",
"failed": false,
"rc": 0,
"start": "2021-05-25 14:41:42.728367",
"stderr": "",
"stderr_lines": [],
"stdout": "Disabled",
"stdout_lines": [
"Disabled"
]
}
}
....
优化:
- name: 测试变量
hosts: slb
gather_facts: no
tasks:
- name: 执行 shell 命令
shell: getenforce
register: ret
- name: 输出变量
debug:
msg: "{{ ret.rc }} {{ ret.stdout }}"
输出:
TASK [输出变量] **********************************************************************
ok: [192.168.122.26] => {
"msg": "0 Disabled"
}