一、ansible变量的作用
所谓的变量就是一个会变的值。
如果你有一个值,被后面的task,频繁的调用,那么你就可以将这个值定义成一个变量,然后将后面task只用的这个值换成变量。比如有10处调用了。在playbook开头定义这个变量。当开头的变量值改变之后,10处被使用这个值的地方,就都做了改变。
Ansible支持变量功能,能将value存储到变量中,这样就能在Ansible项目中重复使用了。这样就可以简化项目的创建和维护,减少错误率 。
变量提供了一个变量提供了一种方便的方法来管理ansible项目中给定环境的动态值。 变量可以是要创建的用户,要安装的包,要启动的服务,要删除的文件,要从互联网下载的文件等等。
变量由必须以字母开头的字符串组成,并且只能包含字母,数字和下划线组成。
二、定义变量
变量几乎可以定义在ansible项目中的任意位置。然而这有三种基本的范围级别:
-
Globe scope:从命令行设置变量或Ansible配置文件中设置变量
-
play scope:在play和相关结构中设置变量
-
host scope:通过inventory在主机组或单个主机中设置变量,fact采集变量或者register
如果在一个级别上定义了名字相同的两个变量,会选择先定义的那个。 在inventory中定义的变量会被playbook中定义的覆盖,playbook中定义的变量会被命令行定义的变量覆盖。
bash
cmd > playbook > inventory
1、在playbook中定义变量
bash
[root@control ansible_manage]# cat play_book/debug2.yaml
---
- name: this is a var test
hosts: all
vars:
user: nana
tasks:
- name: debug moudle text
debug:
msg: "{{ user }} is very handsome man ,but {{user}} is very pool"
vars
这里可以定义变量的值,在这里定义的变量是"user=nana
"
引用变量必须以"{``{ vars }}"
的格式来写
bash
[root@control ansible_manage]# ansible-playbook play_book/debug2.yaml
...
ok: [manage1] => {
"msg": "nana is very handsome man ,but nana is very pool"
}
ok: [manage3] => {
"msg": "nana is very handsome man ,but nana is very pool"
}
ok: [manage2] => {
"msg": "nana is very handsome man ,but nana is very pool"
}
...
可以看到输出的结果是变量引用的值
2、在cmd中定义变量
bash
[root@control ansible_manage]# ansible-playbook play_book/debug2.yaml -e user=cui
...
ok: [manage1] => {
"msg": "cui is very handsome man ,but cui is very pool"
}
ok: [manage3] => {
"msg": "cui is very handsome man ,but cui is very pool"
}
ok: [manage2] => {
"msg": "cui is very handsome man ,but cui is very pool"
}
...
在yaml文件中的变量是uesr=nana
,但是在cmd命令行中的定义了user=cui
,这个时候变量就使用的是cmd
中定义的变量,cmd中定义的变量优先级最高
3、在inventory中定义变量
单个设置
bash
[root@control ansible_manage]# cat inventory
manage1 user=jojo
manage2 user=dio
manage3 user=haha
bash
[root@control ansible_manage]# ansible-playbook play_book/debug2.yaml
...
ok: [manage1] => {
"msg": "nana is very handsome man ,but nana is very pool"
}
ok: [manage3] => {
"msg": "nana is very handsome man ,but nana is very pool"
}
ok: [manage2] => {
"msg": "nana is very handsome man ,but nana is very pool"
...
由于在playbook中变量的优先级比较高,先将play中的变量删除
bash
[root@control ansible_manage]# cat play_book/debug2.yaml
---
- name: this is a var test
hosts: all
vars:
tasks:
- name: debug moudle text
debug:
msg: "{{ user }} is very handsome man ,but {{user}} is very pool"
再次执行
bash
[root@control ansible_manage]# ansible-playbook play_book/debug2.yaml
"msg": "jojo is very handsome man ,but jojo is very pool"
}
ok: [manage2] => {
"msg": "dio is very handsome man ,but dio is very pool"
}
ok: [manage3] => {
"msg": "haha is very handsome man ,but haha is very pool"
}
使用组来设置
查看inventory文件
bash
[root@control ansible_manage]# cat inventory
manage1
manage2
manage3 user=nana
[computer]
manage1
manage2
manage3
[computer:vars] ## vars 表示定义这个组的变量,下面跟变量
user=mooooom
在这里定义了组的变量,computer
组的变量user=mooooom
,还定义了manage3用户的变量uers=nana
playbook文件
bash
[root@control ansible_manage]# cat play_book/debug2.yaml
---
- name: this is a var test
hosts: computer
vars:
tasks:
- name: debug moudle text
debug:
msg: "{{ user }} is very handsome man ,but {{ user }} is very pool"
执行文件
bash
[root@control ansible_manage]# ansible-playbook play_book/debug2.yaml
...
"msg": "mooooom is very handsome man ,but mooooom is very pool"
}
ok: [manage2] => {
"msg": "mooooom is very handsome man ,but mooooom is very pool"
}
ok: [manage3] => {
"msg": "nana is very handsome man ,but nana is very pool"
}
...
当inventory文件中有重复的变量出现的时候,有限范围小的变量
4、变量文件
将变量放在playbook和inventory中是非常不可取的一种方案,容易有很多的问题,管理也不方便,但是将变量单独放在一个文件中的话,就不会有这样的问题
inventory文件
bash
[root@control ansible_manage]# cat inventory
manage1
manage2
manage3 user=nana
[computer]
manage1
manage2
manage3
playbook文件
bash
[root@control ansible_manage]# cat play_book/debug2.yaml
---
- name: this is a var test
hosts: all
vars_files:
- ./debug2_vars.yaml
tasks:
- name: debug moudle text
debug:
msg: "{{ user1 }} is very {{ state1 }} man ,but {{ user2 }} is very {{ state2 }}"
变量文件
bash
[root@control ansible_manage]# cat play_book/debug2_vars.yaml
user1: nana
user2: cui
state1: handsome
state2: poor
执行结果
bash
[root@control ansible_manage]# ansible-playbook play_book/debug2.yaml
...
*******************************************************************************************ok: [manage1] => {
"msg": "nana is very handsome man ,but cui is very poor"
}
ok: [manage2] => {
"msg": "nana is very handsome man ,but cui is very poor"
}
ok: [manage3] => {
"msg": "nana is very handsome man ,but cui is very poor"
}
三、主机变量与主机组变量
playbook
文件中放的就是task
inventory
文件中放的就是host and group
variables
文件中放的就是var files
每个文件都放自己应该放的内容,如果将变量放进其他两个文件中,就会变得非常不好管理。
如何定义主机变量和主机组变量,在ansible中定义了两个文件,用来存放主机变量和组变量, group_vars
和host_vars
两个文件
-
host_vars
文件下面创建对应主机的文本,创建的文本名称名称 是与inventory
文件中host
对应的文本 -
gruop _vars
文件下面创建对应主机组的文本,创建的文本名称 必须是inventory
文件中gruop
对应的文本
1、inventory
文件与host_vars
和gruop _vars
之间的关系
-
inventory
、host_vars
、gruop _vars
在同一目录下,或与对应playbook同于目录下 -
host_vars
文件的命名必须是"host_vars
",否则识别不到 -
gruop _vars
文件的命名必须是"gruop _vars
",否则识别不到 -
host_vars
下的文件名必须与inventory
文件中的主机名对应 -
gruop _vars
下的文件必须与inventory
文件中的主机组对应
bash
[root@control ansible_manage]# cat inventory
manage1
manage2
manage3 user=nana
[computer]
manage1
manage2
manage3
bash
[root@control ansible_manage]# tree
.
├── ansible.cfg
├── group_vars
│ └── computer
├── host_vars
│ ├── manage1
│ ├── manage2
│ └── manage3
├── inventory
└── play_book
└── debug3.yaml
比如在这个group_vars
文件中的文件名就与inventory
中的computer
组的名字相同
2、实例
inventory文件
bash
[root@control ansible_manage]# cat inventory
manage1
manage2
manage3 user=nana
[computer]
manage1
manage2
manage3
host_vars
文件
bash
[root@control ansible_manage]# cat host_vars/manage{1..3}
hello: wordssssssssssssssssssssssss # manage1
hello: china # manage2
hello: ansible # manage3
group_vars
文件
bash
[root@control ansible_manage]# cat group_vars/computer
user1: cui
state1: handsome
yaml
文件
bash
[root@control ansible_manage]# cat play_book/debug3.yaml
---
- name: this is a var test
hosts: all
tasks:
- name: debug moudle text
debug:
var: user1 ## var后面可以直接跟变量,不需要"{{}}"
- debug:
var: state1
- debug:
var: hello
- debug:
var: nihao
执行文件
bash
[root@control ansible_manage]# ansible-playbook play_book/debug3.yaml
...
TASK [debug moudle text] *******************************************************************************************ok: [manage1] => {
"user1": "cui"
}
ok: [manage2] => {
"user1": "cui"
}
ok: [manage3] => {
"user1": "cui"
}
TASK [debug] *******************************************************************************************************ok: [manage1] => {
"state1": "handsome"
}
ok: [manage2] => {
"state1": "handsome"
}
ok: [manage3] => {
"state1": "handsome"
}
TASK [debug] *******************************************************************************************************ok: [manage1] => {
"hello": "wordssssssssssssssssssssssss"
}
ok: [manage2] => {
"hello": "china"
}
ok: [manage3] => {
"hello": "ansible"
}
TASK [debug] *******************************************************************************************************ok: [manage1] => {
"nihao": "VARIABLE IS NOT DEFINED!"
}
ok: [manage2] => {
"nihao": "VARIABLE IS NOT DEFINED!"
}
ok: [manage3] => {
"nihao": "VARIABLE IS NOT DEFINED!"
}
...
四、变量矩阵
如果需要设置许多十分近似的变量,就可以使用变量矩阵的方式来写
例如:
bash
user_nana_name=jinzhuren
user_nana_money=10000w
user_nana_home=sxpi
user_cui_name=cheng
user_cui_money=1k
user_cui_home=scdd
就可以写成这种模式
bash
user:
nana:
name: jinzhuren
money: 10000w
home: sxpi
cui:
name: cheng
money: 1k
home: scdd
在playbook中定义变量
bash
---
- name: this is a var test
hosts: manage1
vars_files:
./debug4_var.yaml
tasks:
- name: debug moudle text
debug:
var: user['nana']['name'] ## 建议使用这种方式写变量,虽然这种写法真麻烦
- debug:
var: user['nana']['money']
- debug:
var: user['nana']['home']
- debug:
var: user.cui.name ## 也可以使用这种方式写变量,但是容易与python冲突。
- debug:
var: user.cui.home
- debug:
var: user.cui.money
执行
bash
[root@control ansible_manage]# ansible-playbook play_book/debug4.yaml
...
TASK [debug moudle text] *******************************************************************************************ok: [manage1] => {
"user['nana']['name']": "jinzhuren"
}
TASK [debug] *******************************************************************************************************ok: [manage1] => {
"user['nana']['money']": "10000w"
}
TASK [debug] *******************************************************************************************************ok: [manage1] => {
"user['nana']['home']": "sxpi"
}
TASK [debug] *******************************************************************************************************ok: [manage1] => {
"user.cui.name": "cheng"
}
TASK [debug] *******************************************************************************************************ok: [manage1] => {
"user.cui.home": "scdd"
}
TASK [debug] *******************************************************************************************************ok: [manage1] => {
"user.cui.money": "1k"
}
...
五、register变量
可以将tasks运行状态记录下来
写一个install.yaml
bash
[root@control ansible_manage]# cat play_book/install.yaml
---
- name: install a pkg
hosts: manage1
tasks:
- name: install httpd
yum:
name: httpd
state: present
register: ergou ## 使用ergou这个变量,记录运行状态
- name: degue ergou
debug:
var: ergou ## 条用这个二狗
bash
[root@control ansible_manage]# ansible-playbook play_book/install.yaml
...
TASK [degue ergou] *****************************************************************************************************************************ok: [manage1] => {
"ergou": {
"changed": true,
"failed": false,
"msg": "",
"rc": 0,
"results": [
"Installed: mod_http2-1.15.19-5.el9.x86_64",
"Installed: httpd-2.4.57-5.el9.x86_64"
]
}
}
PLAY RECAP *************************************************************************************************************************************manage1 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
运行之后可以看到使用register
变量,搭配debug
显示出了运行状态
rc
的值为0,表示运行正常,若不为0,则表示出现了问题。常常使用rc
的返回值来做条件判断
六、facts变量
能够轻松的获取到被控制节点主机的信息
获取其他host节点的信息
bash
[root@control ansible_manage]# ansible manage1 -m setup
生成的是一个json
文件,它里面包含了被管理主机的绝大多数信息,可以很轻易的知到被管理主机的资源信息等。它使用的是ansible
的setup
模块
在每次运行playbook
的时候,ansible
会默认的自动运行这个模块
1、使用debug
模块获取主机的内存
使用ansible manage1 -m setup
获取到合适的变量,进行筛选,编写playbook
bash
[root@control ansible_manage]# cat play_book/debug5.yaml
---
- name: this is a var test
hosts: all
tasks:
- name: debug moudle text
debug:
msg: "{{ ansible_hostname }}'s current free mem is {{ ansible_memfree_mb }}"
bash
[root@control ansible_manage]# ansible-playbook play_book/debug5.yaml
PLAY [this is a var test] ***************************************************************************************
## [Gathering Facts] 这个就是自动执行了setup模块获取信息
TASK [Gathering Facts] ******************************************************************************************
ok: [manage1]
ok: [manage3]
ok: [manage2]
TASK [debug moudle text] ****************************************************************************************
ok: [manage1] => {
"msg": "manage1's current free mem is 69"
}
ok: [manage2] => {
"msg": "manage2's current free mem is 67"
}
ok: [manage3] => {
"msg": "manage3's current free mem is 872"
}
...
运行结束后,可以看到返回的信息,获取到了三台主机的内存信息
2、关闭facts变量的采集
如果集群过于大的情况下,采集信息是非常消耗时间的一件事情。
在playbook中使用gather_facts: no
就可以变比变量的采集
bash
[root@control ansible_manage]# cat play_book/debug6.yaml
---
- name: this is a var test
hosts: all
gather_facts: no
tasks:
- name: debug moudle text
debug:
var:
- ansible_hostname
- ansible_memfree_mb
bash
[root@control ansible_manage]# ansible-playbook play_book/debug6.yaml
PLAY [this is a var test] ***************************************************************************************
TASK [debug moudle text] ****************************************************************************************
ok: [manage1] => {
"<class 'list'>": "VARIABLE IS NOT DEFINED!"
}
ok: [manage2] => {
"<class 'list'>": "VARIABLE IS NOT DEFINED!"
}
ok: [manage3] => {
"<class 'list'>": "VARIABLE IS NOT DEFINED!"
}
...
可以看到已经没有使用setbug
模块
3、自定义faces的变量
在faces中有一个"ansible_local": {},
的变量,这个变量是提供给用户自定义变量使用的
bash
[root@control ansible_manage]# ansible manage1 -m setup
...
"ansible_local": {},
...
自定义变量默认的目录是/etc/ansible/facts.d/
目录,创建的文件必须是以.fact
结尾,这个目录如果没有,就需要自己创建(必须要在被管理主机上创建,必须有root的权限)
定义一个文件
bash
[root@manage1 ~]# mkdir -p /etc/ansible/facts.d/
[root@manage1 ~]# vim /etc/ansible/facts.d/test.fact
[root@manage1 ~]# cat /etc/ansible/facts.d/test.fact
[nana]
name=nananananananananana
bash
[root@control ansible_manage]# ansible manage1 -m setup | grep -A 5 ansible_local
"ansible_local": {
"test": {
"nana": {
"name": "nananananananananana"
}
}
可以看到ansible_local
已经出现了值
playbook使用debug
调用一下
bash
[root@control ansible_manage]# cat play_book/debug7.yaml
---
- name: this is a var test
hosts: manage1
tasks:
- name: debug moudle text
debug:
var: ansible_local['test']['nana']['name']
bash
[root@control ansible_manage]# ansible-playbook play_book/debug7.yaml
PLAY [this is a var test] ***************************************************************************************
TASK [Gathering Facts] ******************************************************************************************
ok: [manage1]
TASK [debug moudle text] ****************************************************************************************
ok: [manage1] => {
"ansible_local['test']['nana']['name']": "nananananananananana"
}
PLAY RECAP ******************************************************************************************************
manage1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=
0
七、magic变量
就是主机变量和主机组变量
bash
[root@control ansible_manage]# ansible manage1 -m debug -a "var=hostvars['manage1']"
manage1 | SUCCESS => {
"hostvars['manage1']": {
"ansible_check_mode": false,
"ansible_config_file": "/root/ansible_manage/ansible.cfg",
"ansible_diff_mode": false,
"ansible_facts": {},
"ansible_forks": 5,
"ansible_inventory_sources": [
"/root/ansible_manage/inventory"
],
"ansible_playbook_python": "/usr/bin/python3",
"ansible_verbosity": 0,
"ansible_version": {
"full": "2.14.9",
"major": 2,
"minor": 14,
"revision": 9,
"string": "2.14.9"
},
"group_names": [
"computer"
],
"groups": {
"all": [
"manage1",
"manage2",
"manage3"
],
"computer": [
"manage1",
"manage2",
"manage3"
],
"ungrouped": []
},
"hello": "wordssssssssssssssssssssssss",
"inventory_dir": "/root/ansible_manage",
"inventory_file": "/root/ansible_manage/inventory",
"inventory_hostname": "manage1",
"inventory_hostname_short": "manage1",
"omit": "__omit_place_holder__1d6935aaefc1e64ad57756c57c90f8ad4cc240af",
"playbook_dir": "/root/ansible_manage",
"state1": "handsome",
"user1": "cui"
}
}
最有用的是inventory_hostname
和groups
,它可以将用于条件判断