傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。——–王小波 
 
写在前面  
嗯,学习Ansible高级特性,整理这部分笔记 
博文内容涉及
Ansible ploybook 中变量定义的基本原则 
不同位置定义变量的优先级 Demo 
如何实现变量和清单解耦 
 
 
食用方式:
大量Demo,所以适合收藏温习查阅变量优先级 
需要有ansible基础 
了解角色剧本基本结构 
能够使用Ansible解决实际问题 
 
 
理解不足小伙伴帮忙指正 
 
 傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。——–王小波 
 
管理清单变量 描述变量的基本原则 在Ansible中,利用变量,可以编写任务、角色和 playbook,使它们可重复使用并且灵活多变。变量可以指定不同系统之间的配置差异。ansilbe可以在许多不同的位置设置变量:
在角色的defaults和vars目录中 
在主机清单文件中,作为主机变量或组变量 
在Playbook或清单的 group_vars 或host_vars子目录下的变量文件中 
在 Play、角色或任务中 
 
在项目定义和管理变量时,做好规划以遵循下列原则: 
保持简单:尽管可以通过许多不同的⽅式定义 Ansible 变量,但尽量仅使用一两种不同方式并且仅在几个地方定义变量。
 
不要重复:如果⼀组系统具有相同的配置,则将它们组织到⼀个组中,并在 group_vars 目录下的文件中为它们设置清单变量。
 
在可读的小文件中组织变量:如果有一个包含许多主机组和变量的大型项目,请将变量拆分成多个文件。
 
 
变量合并和优先级 当使用多种方式定义相同变量时,Ansible 将使用优先级规则为变量选取值。以下讨论优先级从低到高:
配置文件(ansible.cfg) 
命令行选项 
角色defaults变量 
host和group变量 
Play变量 
Extra变量(全局变量) 
 
下面就这几种变量一起简单梳理下:
配置文件 配置文件的变量拥有最低的优先级,通过在ansible.cfg 中提供到的一个KV的键值对,我们看一个Demo
1 2 3 4 5 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat  ansible.cfg | grep remote_user remote_user=root ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
这里的配置文件中的remote_user=root为连接受管机器的远程用户名,对应保存到ansible中的ansible_user变量中
1 2 3 4 5 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible  vms82.liruilongs.github.io -m debug -a 'var=ansible_user'  -i ./inventorys/hosts vms82.liruilongs.github.io | SUCCESS => {     "ansible_user" : "root"  } 
 
把配置文件中的变量删除,
1 2 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$sed  -i '/remote_user=root/d'  ansible.cfg 
 
在次打印变量会提示变量没有定义
1 2 3 4 5 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible vms82.liruilongs.github.io -m debug -a 'var=ansible_user' -i ./inventorys/hosts vms82.liruilongs.github.io | SUCCESS => {     "ansible_user": "VARIABLE IS NOT DEFINED!" } 
 
添加之后也可以正常打印
1 2 3 4 5 6 7 8 9 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$sed  '4a remote_user=root'  ansible.cfg -i ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible  vms82.liruilongs.github.io -m debug -a 'var=ansible_user'  -i ./inventorys/hosts vms82.liruilongs.github.io | SUCCESS => {     "ansible_user" : "root"  } ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
当然这里需要注意的是,当不指定主机清单的时候,默认情况下ansible会忽略带有后缀的文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -config  dump | grep -i inventory DEFAULT_HOST_LIST(/root/ansible/ansible.cfg) = [u'/root/ansible/inventory' ] DEFAULT_INVENTORY_PLUGIN_PATH(default) = [u'/root/.ansible/plugins/inventory' , u'/usr/share/ansible/plugins/inventory' ] INVENTORY_ANY_UNPARSED_IS_FAILED(default) = False INVENTORY_CACHE_ENABLED(default) = False INVENTORY_CACHE_PLUGIN(default) = None INVENTORY_CACHE_PLUGIN_CONNECTION(default) = None INVENTORY_CACHE_PLUGIN_PREFIX(default) = ansible_facts INVENTORY_CACHE_TIMEOUT(default) = 3600 INVENTORY_ENABLED(default) = ['host_list' , 'script' , 'auto' , 'yaml' , 'ini' , 'toml' ] INVENTORY_EXPORT(default) = False INVENTORY_IGNORE_EXTS(default) = {{(BLACKLIST_EXTS + ( '.orig' , '.ini' , '.cfg' , '.retry' ))}} INVENTORY_IGNORE_PATTERNS(default) = [] INVENTORY_UNPARSED_IS_FAILED(default) = False VARIABLE_PRECEDENCE(default) = ['all_inventory' , 'groups_inventory' , 'all_plugins_inventory' , 'all_plugins_play' , 'groups_plugins_inventory' , 'groups_plugins_play' ] ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
命令行选项: 可在命令行中传递给ansible-playbook的选项(非 -e )具有最低优先级。这里讲的主要是通过其他参数来定义变量,还是用我们之前定义的ansible_user变量
1 2 3 4 5 6 7 8 9 10 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible  all -m debug -a "var=ansible_user"  vms82.liruilongs.github.io | SUCCESS => {     "ansible_user" : "root"  } ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible  all -m debug -a "var=ansible_user"  -u liruilong vms82.liruilongs.github.io | SUCCESS => {     "ansible_user" : "liruilong"  } 
 
当然这里需要注意的是通过临时命令的方式执行 debug 模块.默认不会连接受管机,所以这里不会报错,我们的 sanheyiwuyang 用户是一个没有被受管机定义的用户。
1 2 3 4 5 6 7 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible  all -m debug -a "var=ansible_user"  -u sanheyiwuyang vms82.liruilongs.github.io | SUCCESS => {     "ansible_user" : "sanheyiwuyang"  } ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
角色default值: role_name/defaults/ 文件中由角色设置的默认值具有非常低的优先级。相对于角色中的vars目录下的变量,会覆盖defaults变量值。这里我们还是用remote_user这个变量
先来新建一个角色
1 2 3 4 5 6 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -galaxy init vars_demo --init-path=roles - Role vars_demo was created successfully ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -galaxy list | grep var - vars_demo, (unknown version) 
 
编写角色中的默认变量,这里我们定义远程用户名是一个没有在受管机定义的sanheyiwuyang
1 2 3 4 5 6 7 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$echo  -e "ansible_user: sanheyiwuyang"  > ./roles/vars_demo/defaults/main.yml ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat  ./roles/vars_demo/defaults/main.yml ansible_user: sanheyiwuyang ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
编写角色任务
1 2 3 4 5 6 7 8 9 10 11 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$vim  ./roles/vars_demo/tasks/main.yml ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat  ./roles/vars_demo/tasks/main.yml --- - name: default_vars demo   debug:     var: ansible_user ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
编写执行角色的剧本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$vim   vars_demo.yaml ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat  vars_demo.yaml --- - name: vars_demo roles demo   hosts: all   roles:     - vars_demo   tasks:     - name: show vars       debug:         var: ansible_user ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
当前的ansible_user变量定义,我们可以看到,配置文件的优先级最低,其次是 命令行非(-e)的方式
1 2 3 4 5 6 7 8 9 10 11 12 13 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml  -u liruilong PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* fatal: [vms82.liruilongs.github.io]: UNREACHABLE! => {"changed" : false , "msg" : "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password)." , "unreachable" : true } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0   ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
执行调用角色的剧本,报错了,通过 -u 的方式指定liruilong用户,但是角色中使用的并不是liruilong用户,而是没有被受管机定义的sanhewuyang用户,因为命名行非-e的变量优先级小于角色中/roles/var_demo/default/main.yaml定义的变量,所以liruilong用户被覆盖,所以会报错
修改 ./roles/vars_demo/defaults/main.yml中的ansible_user变量,我们也可以发现使用的是root用户,而不是命令行的liruilong
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 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$echo  "ansible_user: root"  >  ./roles/vars_demo/defaults/main.yml ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml  -u liruilong PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
主机变量和组变量: 关于主机变量和组变量这是相对应主机清单文件来讲的,主机清单的定义方式有很多种,我们可以直接通过inventory文件定义,也可以创建 inventory目录中的文件来定义,也可以在项目中指定目录下定义,场景比较多,我们分别看下
以下列表从最低到最高列出了这些变量的确切优先顺序:
直接在清单文件中或通过动态清单脚本设置的all组变量。 
直接在清单文件中或通过动态清单脚本设置的其他组变量。 
在inventory/group_vars/all文件或子目录中设置的all组的变量。 
在项目的group_vars/all文件或子目录中设置的all组的变量。 
在inventory/group_vars子目录中设置的其他组变量。 
在项目的group_vars子目录中设置的其他组变量。 
直接在清单文件中或通过动态清单脚本设置的主机变量。 
在inventory/host vars子目录中设置的主机变量。 
在项目的host vars子目录中设置的主机变量。 
主机facts和缓存的facts。 
 
我们分别来看下:
直接在清单文件中或通过动态清单脚本设置的all组变量 1 2 3 4 5 6 7 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$vim  inventory/inventory ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat  inventory/inventory vms82.liruilongs.github.io [all:vars] ansible_user=liruilong 
 
当前角色中的默认值为root
1 2 3 4 5 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat  ./roles/vars_demo/defaults/main.yml ansible_user: root ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
通过剧本的执行我们可以看到all中的组变量优先级要大于default目录下的变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
直接在清单文件中或通过动态清单脚本设置的其他组变量。 在上面的基础上我们新建一个组变量[lb:vars]。定义ansible_user的值为root
1 2 3 4 5 6 7 8 9 10 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$vim  inventory/inventory ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat  inventory/inventory [lb] vms82.liruilongs.github.io [lb:vars] ansible_user=root [all:vars] ansible_user=liruilong 
 
执行剧本发现,通过ansible_user的值为root,说明覆盖了all组中的定的变量
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 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$vim  inventory/inventory ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
在inventory/group_vars/all文件或子目录中设置的all组的变量 1 2 3 4 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$mkdir  -p inventory/group_vars ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$echo  "ansible_user: liruilong"  > inventory/group_vars/all 
 
会发现inventory/group_vars/all覆盖了上面的inventory/inventory定义的变量,ansible_user的值为liruilong
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
在项目的group_vars/all文件或子目录中设置的all组的变量。 1 2 3 4 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$mkdir  group_vars ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$echo  "ansible_user: root"  >  group_vars/all 
 
我们会发现项目group_vars/all下面变量会覆盖主机清单文件inventory/group_vars/all下的变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
在inventory/group_vars子目录中设置的其他组变量 这里需要说明的是,创建lb组变量inventory/group_vars/lb.yaml文件的前提是,需要在inventory/inventory文件中定义分组
1 2 3 4 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat  ./inventory/inventory [lb] vms82.liruilongs.github.io 
 
可以看到在inventory/group_vars/lb.yaml文件中定义覆盖了
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 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$echo  "ansible_user: liruilong"  >  inventory/group_vars/lb.yaml ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
在项目的group_vars子目录中设置的其他组变量 可以看到项目的./group_vars/lb.yaml的变量优先级要高于inventory/group_vars/lb.yaml下的
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 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$echo  "ansible_user: root"  > ./group_vars/lb.yaml ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
前面我们分析的都是组变量,下面下面我们看看主机变量
直接在清单文件中或通过动态清单脚本设置的主机变量 1 2 3 4 5 6 7 8 9 10 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$sed   "s/vms82.liruilongs.github.io/& ansible_user=liruilong/"  ./inventory/inventory [lb] vms82.liruilongs.github.io ansible_user=liruilong [lb:vars] ansible_user=root [all:vars] ansible_user=liruilong ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$sed   "s/vms82.liruilongs.github.io/& ansible_user=liruilong/"  ./inventory/inventory -i 
 
设置主机变量为ansible_user=liruilong优先级大于上面的组变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
在inventory/host_vars子目录中设置的主机变量 1 2 3 4 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$mkdir  inventory/host_vars ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$echo  "ansible_user: root"  > inventory/host_vars/vms82.liruilongs.github.io.yaml 
 
inventory/host_vars子目录中设置的主机变量优先级大于./inventory/inventory 中的主机变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
在项目的host_vars子目录中设置的主机变量 1 2 3 4 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$mkdir   host_vars ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$echo  "ansible_user: liruilong"  > host_vars/vms82.liruilongs.github.io.yaml 
 
项目的host_vars子目录中设置的主机变量优先级大于清单host_vars子目录的变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ 
 
主机facts和缓存的facts 主机facts,可以看到set_fact设置的变量具有最高的优先级
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat  vars_demo.yaml --- -  name:  vars_demo  roles  demo   hosts:  all    roles:      -  vars_demo    tasks:      -  name:  show  vars        debug:          var:  ansible_user      -  name:  set  fact  ansible_user        set_fact:           ansible_user:  root      -  name:  show  vars        debug:          var:  ansible_user  
 
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 29 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [set  fact ansible_user] *************************************************************************************** ok: [vms82.liruilongs.github.io] TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
 
对于其他的一些通过gather_facts收集的变量,相对于剧本之外具有很高的优先级
相对于清单inventory的group_vars和host_vars子目录与相对于 playbook 项目的子目录之间的优先级比较好区分,相同类型,项目下总是比清单里的优先级要高,。
如果在 playbook 的相同目录中有group_vars 和 host_vars子目录,则这些组和主机变量将被自动包含在内。
简单总结一下ansible清单文件变量优先级。在facts优先级最高,其次是主机变量,包含清单变量文件的host_vars目录和inventory清单变量目录和inventory文件,项目下要高于清单目录下,清单目录要高于清单文件,之后是组变量,group_vars目录下的文件,inventory清单变量目录,inventory文件,整体上,inventory文件优先级小于目录下的优先级,同样是inventory目录下要小于项目目录下。
Play 变量: 准备工作,我们还用之前的角色和剧本
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 29 30 31 32 33 34 35 36 37 38 39 40 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat  vars_demo.yaml --- - name: vars_demo roles demo   hosts: all   roles:     - vars_demo   tasks:     - name: show vars       debug:         var: ansible_user     - name: show vars       debug:         var: ansible_user ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
 
Play 的优先级高于主机或组变量、角色默认值,除 -e 以外的命令行选项。以下列表从最低到最高列出了这些变量的优先顺序:
由 play 的 vars 部分进行设置。 
通过 play 中的 vars_prompt 部分提示用户来进行设置。 
通过 play 的 vars_files 部分从外部文件列表进行设置。 
由角色的 rolename/vars/ 子目录中的文件进行设置。 
通过这个块的 vars 部分为当前的 block 进行设置。 
通过这个任务的 vars 部分为当前的任务进行设置。 
通过 include_vars 模块动态加载。 
通过使用 set_fact 模块或通过使用 register 记录任务在主机上执行的结果,为特定的主机进行设置。 
在 play 的 role 部分加载时或通过使用 include_role 模块 playbook 中为角色设置的参数。 
由 vars 部分为通过 include_tasks 模块包含的任务进行设置。 
 
我们分别梳理下:
由 play 的 vars 部分进行设置。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 --- -  name:  vars_demo  roles  demo   hosts:  all    vars:      ansible_user:  root    roles:      -  vars_demo    tasks:      -  name:  show  vars        debug:          var:  ansible_user      -  name:  show  vars        debug:          var:  ansible_user  
 
play 的 vars 部分进行设置的变量要高于前面设置的变量
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 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
 
通过 play 中的vars_prompt部分提示用户来进行设置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 --- -  name:  vars_demo  roles  demo   hosts:  all    vars:      ansible_user:  root    vars_prompt:      -  name:  ansible_user        prompt:  "input ansible_user name"    roles:      -  vars_demo    tasks:      -  name:  show  vars        debug:          var:  ansible_user      -  name:  show  vars        debug:          var:  ansible_user  
 
这里默认情况下输入数据是不显示,可以添加参数private: no来显示输入变量值
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 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml input ansible_user name: PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
 
通过 play 的 vars_files 部分从外部文件列表进行设置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 --- -  name:  vars_demo  roles  demo   hosts:  all    vars:      ansible_user:  root    vars_files:      -  vars_files    vars_prompt:      -  name:  ansible_user        prompt:  "input ansible_user name"        private:  no    roles:      -  vars_demo    tasks:      -  name:  show  vars        debug:          var:  ansible_user      -  name:  show  vars        debug:          var:  ansible_user  
 
定义引入的变量文件
1 2 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$echo  "ansible_user: liruilong"  > vars_files 
 
执行剧本,可以看到我们输入的是root但是打印的是liruilong,即vars_files的优先级高于vars_prompt
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 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml input ansible_user name: root PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
 
由角色的rolename/vars/子目录中的文件进行设置 当前剧本执行返回的变量值为 liruilong,我们定义roles/vars_demo/vars/main.yml目录的ansible_user变量为root.执行剧本
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 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$echo  "ansible_user: root"  > roles/vars_demo/vars/main.yml ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars] *************************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } PLAY RECAP ********************************************************************************************************* vms82.liruilongs.github.io : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
 
通过这个任务块的 vars 部分为当前的 block 进行设置。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 --- -  name:  vars_demo  roles  demo   hosts:  all    roles:      -  vars_demo    tasks:      -  block:          -  name:  show  vars  in  block            debug:              var:  ansible_user        vars:          ansible_user:  liruilong      -  name:  show  vars        debug:          var:  ansible_user  
 
我们可以看到,在block所在的块的内部,通过vars定义的变量具有最高的优先级,打印的ansible_usern的变量的为liruilong,而在剧本的其他位置的打印的变量为root
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 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook var_demos.yaml PLAY [vars_demo roles demo] **************************************************************** TASK [Gathering Facts] ********************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars in  block] ****************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } PLAY RECAP ********************************************************************************* vms82.liruilongs.github.io : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
 
show vars任务为角色中的任务,所以依旧使用角色中的vars/main.yml定义root。
通过这个任务的 vars 部分为当前的任务进行设置 即不是写在block块内的vars变量,而是写在对应 任务中的vars的变量中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 --- -  name:  vars_demo  roles  demo   hosts:  all    roles:      -  vars_demo    tasks:      -  block:          -  name:  show  vars  in  block            debug:              var:  ansible_user            vars:              ansible_user:  root          -  name:  show  vars   in  block  no  vars            debug:              var:  ansible_user        vars:          ansible_user:  liruilong  
 
执行我们可以看到在block内部,任务内部的变量优先级要高于任务外部的变量。
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 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************** TASK [Gathering Facts] ********************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars in  block] ****************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars  in  block no vars] ********************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } PLAY RECAP ********************************************************************************* vms82.liruilongs.github.io : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
 
通过 include_vars 模块动态加载 在ansible中,我们可以使用include_vars模块来加载外部的变量。加载方式很简单,和通过 play 的 vars_files 部分从外部文件列表进行设置很类似。
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 --- -  name:  vars_demo  roles  demo   hosts:  all    roles:      -  vars_demo    tasks:      -  block:          -  name:  show  vars  in  block            debug:              var:  ansible_user            vars:              ansible_user:  root          -  name:  show  vars   in  block  no  vars            debug:              var:  ansible_user        vars:          ansible_user:  liruilong      -  name:  show  vars        debug:           var:  ansible_user      -  name:  include_vars  vars  file        include_vars:           file:  vars_files      -  name:  show  vars  after  include  vars  files        debug:           var:  ansible_user  
 
但是变量的优先级还是有很大的区别的,我们先把include_vars模块放到最后看看。
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat  vars_files ansible_user: liruilong ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************** TASK [Gathering Facts] ********************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars in  block] ****************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars  in  block no vars] ********************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [include_vars vars file] ************************************************************** ok: [vms82.liruilongs.github.io] TASK [show vars after include vars files] ************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } PLAY RECAP ********************************************************************************* vms82.liruilongs.github.io : ok=7    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
 
发现模块执行前是没有变化的,只会影响执行后的。
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 --- -  name:  vars_demo  roles  demo   hosts:  all    roles:      -  vars_demo    tasks:      -  name:  include_vars  vars  file        include_vars:           file:  vars_files      -  block:          -  name:  show  vars  in  block            debug:              var:  ansible_user            vars:              ansible_user:  root          -  name:  show  vars   in  block  no  vars            debug:              var:  ansible_user        vars:          ansible_user:  liruilong      -  name:  show  vars        debug:           var:  ansible_user      -  name:  show  vars  after  include  vars  files        debug:           var:  ansible_user  
 
把include_vars模块放到最前面,我们发现剧本中变量全部被替换为liruilong了,除了角色变量,因为剧本中,角色最先执行。
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 29 30 31 32 33 34 35 36 37 38 39 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************** TASK [Gathering Facts] ********************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [include_vars vars file] ************************************************************** ok: [vms82.liruilongs.github.io] TASK [show vars in  block] ****************************************************************** ok: [vms82.liruilongs.github.io] =>     "ansible_user" : "liruilong"  } TASK [show vars  in  block no vars] ********************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars] *************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [show vars after include vars files] ************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } PLAY RECAP ********************************************************************************* vms82.liruilongs.github.io : ok=7    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
 
通过使用 set_fact 模块或通过使用register记录任务在主机上执行的结果,为特定的主机进行设置。 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 29 30 --- -  name:  vars_demo  roles  demo   hosts:  all    roles:      -  vars_demo    tasks:      -  name:  set  facts        set_fact:          ansible_user:  root      -  name:  include_vars  vars  file        include_vars:           file:  vars_files      -  block:          -  name:  show  vars  in  block            debug:              var:  ansible_user            vars:              ansible_user:  root          -  name:  show  vars   in  block  no  vars            debug:              var:  ansible_user        vars:          ansible_user:  liruilong      -  name:  show  vars        debug:           var:  ansible_user      -  name:  show  vars  after  include  vars  files        debug:           var:  ansible_user  
 
嗯,不多解释。
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************** TASK [Gathering Facts] ********************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [set  facts] *************************************************************************** ok: [vms82.liruilongs.github.io] TASK [include_vars vars file] ************************************************************** ok: [vms82.liruilongs.github.io] TASK [show vars in  block] ****************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars  in  block no vars] ********************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars] *************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars after include vars files] ************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } PLAY RECAP ********************************************************************************* vms82.liruilongs.github.io : ok=8    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
 
在 play 的 role 部分加载时或通过使用 include_role 模块playbook中为角色设置的参数。 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 29 30 31 --- -  name:  vars_demo  roles  demo   hosts:  all    roles:      -  role:  vars_demo        ansible_user:  liruilong    tasks:      -  name:  set  facts        set_fact:          ansible_user:  root      -  name:  include_vars  vars  file        include_vars:           file:  vars_files      -  block:          -  name:  show  vars  in  block            debug:              var:  ansible_user            vars:              ansible_user:  root          -  name:  show  vars   in  block  no  vars            debug:              var:  ansible_user        vars:          ansible_user:  liruilong      -  name:  show  vars        debug:           var:  ansible_user      -  name:  show  vars  after  include  vars  files        debug:           var:  ansible_user  
 
剧本设置角色变量后,角色内置的变量被覆盖掉,但是只对当前角色生效
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 29 30 31 32 33 34 35 36 37 38 39 40 41 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************** TASK [Gathering Facts] ********************************************************************************* ok: [vms82.liruilongs.github.io] TASK [vars_demo : default_vars demo] ******************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [set  facts] *************************************************************************************** ok: [vms82.liruilongs.github.io] TASK [include_vars vars file] ************************************************************************** ok: [vms82.liruilongs.github.io] TASK [show vars in  block] ****************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars  in  block no vars] ********************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars] *************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars after include vars files] ************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } PLAY RECAP ********************************************************************************************* vms82.liruilongs.github.io : ok=8    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
 
或者也可以
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 29 30 31 32 33 34 35 36 --- -  name:  vars_demo  roles  demo   hosts:  all          tasks:      -  name:  include  role        include_role:          name:  vars_demo        vars:           ansible_user:  liruilong      -  name:  set  facts        set_fact:          ansible_user:  root      -  name:  include_vars  vars  file        include_vars:           file:  vars_files      -  block:          -  name:  show  vars  in  block            debug:              var:  ansible_user            vars:              ansible_user:  root          -  name:  show  vars   in  block  no  vars            debug:              var:  ansible_user        vars:          ansible_user:  liruilong      -  name:  show  vars        debug:           var:  ansible_user      -  name:  show  vars  after  include  vars  files        debug:           var:  ansible_user  
 
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************** TASK [Gathering Facts] ********************************************************************************* ok: [vms82.liruilongs.github.io] TASK [include role] ************************************************************************************ TASK [vars_demo : default_vars demo] ******************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "liruilong"  } TASK [set  facts] *************************************************************************************** ok: [vms82.liruilongs.github.io] TASK [include_vars vars file] ************************************************************************** ok: [vms82.liruilongs.github.io] TASK [show vars in  block] ****************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars  in  block no vars] ********************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars] *************************************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } TASK [show vars after include vars files] ************************************************************** ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } PLAY RECAP ********************************************************************************************* vms82.liruilongs.github.io : ok=8    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
 
由 vars 部分为通过 include_tasks 模块包含的任务进行设置 1 2 3 4 5 6 7 8 9 10 11 12 13 --- -  name:  vars_demo  roles  demo   hosts:  all          tasks:      -  name:  include_tasks  demo        include_tasks:  task.yaml        vars:          ansible_user:  root      -  name:  include  role  ... 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat  task.yaml - name: vars demo 2   debug:     var: ansible_user ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible -playbook vars_demo.yaml PLAY [vars_demo roles demo] **************************************************************************** TASK [Gathering Facts] ********************************************************************************* ok: [vms82.liruilongs.github.io] TASK [include_tasks demo] ****************************************************************************** included: /root/ansible/task.yaml for  vms82.liruilongs.github.io TASK [vars demo 2] ************************************************************************************* ok: [vms82.liruilongs.github.io] => {     "ansible_user" : "root"  } .... 
 
使用 ansible-playbook 命令的 -e 选项设置的额外变量始终具有最高的优先级。或者--extra-vars也可以以JSON形式定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible  vms82.liruilongs.github.io -m debug -a 'var=ansible_user'  vms82.liruilongs.github.io | SUCCESS => {     "ansible_user" : "root"  } ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible  all -m debug -a "var=ansible_user"  --extra-vars "{'ansible_user':'liruilong'}"  vms82.liruilongs.github.io | SUCCESS => {     "ansible_user" : "liruilong"  } ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible  all -m debug -a "var=ansible_user"  --e "{'ansible_user':'liruilong'}"  vms82.liruilongs.github.io | SUCCESS => {     "ansible_user" : "liruilong"  } 
 
可以发现当使用 --extra-vars 在命令行定义变量的时候,会覆盖ansible.cfg 的变量配置,使用了liruilong这个受管机用户
将变量与清单分离 随着环境在规模和种类上扩展,清单文件会变得很大且难以阅读。
更好的做法是将变量定义从清单文件转移到单独的变量文件中,每个主机组分别对应一个,每个变量文件都已主机组命令,且包含该主机组的变量定义:
对于多样化的大型化环境而言,更好的方法是在group_vars目录下为每个主机组创建子目录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ┌──[root@vms82.liruilongs.github.io]-[~/inventory-variables] └─$ls  ansible.cfg        deploy_haproxy.yml  group_vars     roles deploy_apache.yml  deploy_webapp.yml   inventory.yml  site.yml ┌──[root@vms82.liruilongs.github.io]-[~/inventory-variables] └─$cd  group_vars/ ┌──[root@vms82.liruilongs.github.io]-[~/inventory-variables/group_vars] └─$tree  . ├── lb_servers │   ├── firewall.yml │   └── haproxy.yml └── web_servers 2 directories, 2 files 
 
group_vars 目录下各目录的文件中存在的所有变量都与其余变量合并在⼀起。通过将变量分隔到按功能分组的文件中,可以使整个 playbook 项目更易于理解和维护。
特殊清单变量 可以使用多个变量来更改Ansible连接到清单中列出的主机的方式。其中⼀些对于主机特定变量最为有用,但另⼀些可能与组中或清单中的所有主机相关。
ansible_connection:主机的连接类型,用于访问受管主机的连接插件。默认情况下,ssh 用于除 localhost 外的所有主机,后者使用 local。
1 2 3 4 5 6 7 8 9 10 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible  all -m debug -a "msg={{ansible_connection}}"  vms82.liruilongs.github.io | SUCCESS => {     "msg" : "ssh"  } ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible  127.0.0.1  -m debug -a "msg={{ansible_connection}}"  127.0.0.1 | SUCCESS => {     "msg" : "local"  } 
 
ansible_host:要连接的主机名称。实际 IP 地址或完全限定域名,在连接受管主机时使用,而不使来用自清单文件(inventory_hostname)  中的名称。默认情况下,此变量具有与清单主机名相同的值。
1 2 3 4 5 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible  all -m debug -a "msg={{ansible_host}}"  vms82.liruilongs.github.io | SUCCESS => {     "msg" : "vms82.liruilongs.github.io"  } 
 
ansible_port:Ansible 用于连接受管主机的端口。对于(默认)SSH 连接插件,其值默认为 22。 
ansible_user:Ansible 以此用户身份连接受管主机。作为 Ansible 的默认行为,它会使用与控制节点上运行 Ansible Playbook 的用户相同的用户名来连接受管主机。 
ansible_become_user:Ansible 连接到受管主机后,它将使用 ansible_become_method(默认情况下为sudo)切换到此用户。 
ansible_python_interpreter:Ansible 应在受管主机上使用的 Python 可执行文件的路径。 
 
系统变量:通过剧本的gather_facts=yes自动搜集(默认调用setup模块),对任务主机有效,系统指标
1 2 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible   all  -m  setup 
 
使用变量识别当前主机 ansible魔法变量,指的是ansible为管理目的而预设的特殊变量,通过adhoc方式或者playbook方式,都可以调用/或者msg查看
inventory_hostname:当前正在处理的受管主机的名称,从清单中获取。 
ansible_host:用于连接受管主机的实际 IP 地址或主机名。 
ansible_facts[‘hostname’]:作为事实,从受管主机手机的完全限定域名。 
ansible_play_hosts:当前 Play 期间尚未失败的所有主机的列表。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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible   all  -m  debug -a "var=hostvars"  vms82.liruilongs.github.io | SUCCESS => {     "hostvars" : {         "vms82.liruilongs.github.io" : {             "ansible_check_mode" : false ,             "ansible_diff_mode" : false ,             "ansible_facts" : {},             "ansible_forks" : 5,             "ansible_inventory_sources" : [                 "/root/ansible/inventory"              ],             "ansible_playbook_python" : "/usr/bin/python2" ,             "ansible_user" : "liruilong" ,             "ansible_verbosity" : 0,             "ansible_version" : {                 "full" : "2.9.25" ,                 "major" : 2,                 "minor" : 9,                 "revision" : 25,                 "string" : "2.9.25"              },             "group_names" : [                 "lb"              ],             "groups" : {                 "all" : [                     "vms82.liruilongs.github.io"                  ],                 "lb" : [                     "vms82.liruilongs.github.io"                  ],                 "ungrouped" : []             },             "inventory_dir" : "/root/ansible/inventory" ,             "inventory_file" : "/root/ansible/inventory/hosts" ,             "inventory_hostname" : "vms82.liruilongs.github.io" ,             "inventory_hostname_short" : "vms82" ,             "omit" : "__omit_place_holder__fbd943e37b3564fcd7926f8926da009ae4e9e4ab" ,             "playbook_dir" : "/root/ansible"          }     } } 
 
 
一个完整的Demo 嗯,我们来看一个具体的Demo,这Demo是之前的博文用到,看一下如何从现有的ansible项目中抽取变量来实现剧本的可复用,可维护
这是原本的结构目录
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 ┌──[root@vms81.liruilongs.github.io]-[~/ansible/inventory-variables] └─$tree  . ├── ansible.cfg ├── deploy_apache.yml ├── deploy_haproxy.yml ├── deploy_webapp.yml ├── inventory.yml ├── roles │   ├── apache │   │   ├── meta │   │   │   └── main.yml │   │   ├── tasks │   │   │   └── main.yml │   │   └── tests │   │       ├── inventory │   │       └── test.yml │   ├── firewall │   │   ├── defaults │   │   │   └── main.yml │   │   ├── handlers │   │   │   └── main.yml │   │   ├── meta │   │   │   └── main.yml │   │   ├── tasks │   │   │   └── main.yml │   │   └── tests │   │       ├── inventory │   │       └── test.yml │   ├── haproxy │   │   ├── defaults │   │   │   └── main.yml │   │   ├── handlers │   │   │   └── main.yml │   │   ├── meta │   │   │   └── main.yml │   │   ├── tasks │   │   │   └── main.yml │   │   ├── templates │   │   │   └── haproxy.cfg.j2 │   │   └── tests │   │       ├── inventory │   │       └── test.yml │   └── webapp │       ├── defaults │       │   └── main.yml │       ├── meta │       │   └── main.yml │       ├── tasks │       │   └── main.yml │       └── tests │           ├── inventory │           └── test.yml └── site.yml 30 directories, 34 files ┌──[root@vms81.liruilongs.github.io]-[~/ansible/inventory-variables] └─$ 
 
这是我们重新编写过的,会发现多了一个group_vars目录
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 ┌──[root@vms81.liruilongs.github.io]-[~/ansible/inventory-variables] └─$tree  . ├── ansible.cfg ├── deploy_apache.yml ├── deploy_haproxy.yml ├── deploy_webapp.yml ├── group_vars │   ├── lb_servers │   │   ├── firewall.yml │   │   └── haproxy.yml │   └── web_servers ├── inventory.yml ├── roles │   ├── apache │   │   ├── meta │   │   │   └── main.yml │   │   ├── tasks │   │   │   └── main.yml │   │   └── tests │   │       ├── inventory │   │       └── test.yml │   ├── firewall │   │   ├── defaults │   │   │   └── main.yml │   │   ├── handlers │   │   │   └── main.yml │   │   ├── meta │   │   │   └── main.yml │   │   ├── tasks │   │   │   └── main.yml │   │   └── tests │   │       ├── inventory │   │       └── test.yml │   ├── haproxy │   │   ├── defaults │   │   │   └── main.yml │   │   ├── handlers │   │   │   └── main.yml │   │   ├── meta │   │   │   └── main.yml │   │   ├── tasks │   │   │   └── main.yml │   │   ├── templates │   │   │   └── haproxy.cfg.j2 │   │   └── tests │   │       ├── inventory │   │       └── test.yml │   ├── org_common │   │   ├── meta │   │   │   └── main.yml │   │   ├── tasks │   │   │   └── main.yml │   │   └── tests │   │       ├── inventory │   │       └── test.yml │   └── webapp │       ├── defaults │       │   └── main.yml │       ├── meta │       │   └── main.yml │       ├── tasks │       │   └── main.yml │       └── tests │           ├── inventory │           └── test.yml └── site.yml 30 directories, 34 files 
 
下面来看一个这个Demo, 关于剧本干了什么,小伙伴可以看看我之前的ansible博文
在项目根目新建一个group_vars ,在该目录下为每个主机组创建子目录
1 2 ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$mkdir  group_vars 
 
创建 lb_servers ⽬录,以存放 lb_servers 组中主机的变量
1 2 ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$mkdir  group_vars/lb_servers 
 
创建 web_servers ⽬录,以存放 web_servers 组的变量
1 2 ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$ mkdir group_vars/web_servers 
 
在每个主机组中为涉及到的角色定义变量文件
1 2 3 4 5 6 ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$touch  group_vars/lb_servers/firewall.yml ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$touch  group_vars/lb_servers/haproxy.yml ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$ls  
 
在执行deploy_haproxy剧本的时候,调用haproxy,会涉及到角色相关的变量加载。firewall_rules,haproxy_appservers这两个角色变量。firewall 角色通过角色依赖的方式执行,而haproxy通过剧本直接执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$cat  deploy_haproxy.yml - name: Ensure HAProxy is deployed   hosts: lb_servers   force_handlers: True   roles:               - role: haproxy       firewall_rules:                  - port: 80/tcp       haproxy_appservers:       - name: serverb.lab.example.com         ip: 172.25.250.11         backend_port: 80       - name: serverc.lab.example.com         ip: 172.25.250.12         backend_port: 80 
 
在group_vars/lb_servers/firewall.yml定义主机组lb_servers中涉及firewall角色的变量
1 2 3 4 5 6 7 8 9 10 11 ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$tee  group_vars/lb_servers/firewall.yml <<- EOF  > firewall_rules: >    # Allow 80/tcp connections >    - port: 80/tcp > EOF firewall_rules:        - port: 80/tcp ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$ 
 
同时将剧本中的变量删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$cat  deploy_haproxy.yml - name: Ensure HAProxy is deployed   hosts: lb_servers   force_handlers: True   roles:               - role: haproxy       haproxy_appservers:       - name: serverb.lab.example.com         ip: 172.25.250.11         backend_port: 80       - name: serverc.lab.example.com         ip: 172.25.250.12         backend_port: 80 
 
同样的在lb_servers主机组目录下haproxy角色变量文件中定义haproxy角色涉及的变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$tee   group_vars/lb_servers/haproxy.yml <<- EOF  > haproxy_appservers: >    - name: serverb.lab.example.com >      ip: 172.25.250.11 >      backend_port: 80 >    - name: serverc.lab.example.com >      ip: 172.25.250.12 >      backend_port: 80 > EOF haproxy_appservers:    - name: serverb.lab.example.com      ip: 172.25.250.11      backend_port: 80    - name: serverc.lab.example.com      ip: 172.25.250.12      backend_port: 80 ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$ 
 
1 2 3 4 5 6 7 8 9 10 ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$cat  deploy_haproxy.yml - name: Ensure HAProxy is deployed   hosts: lb_servers   force_handlers: True   roles:               - role: haproxy 
 
通过上面的改造,我们把变量从执行角色的剧本中解耦出来,类似代码中将静态可变的数据抽离出来的通过加载配置文件的方式。如果调用角色的剧本很复杂的话,那通过把变量抽离,每次需要维护或者移植直接修改变量文件就可以啦。
同样的deploy_apache剧本的变量我们以同样的方式替换一下。
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 29 30 ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$ cat deploy_apache.yml - name: Ensure Apache is deployed   hosts: web_servers   force_handlers: True   roles:               - role: apache       firewall_rules:                  - zone: internal           service: http           source : "172.25.250.10"  ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$tee  group_vars/web_servers/firewall.yml <<- EOF  > firewall_rules: >    # Allow http requests from the load_balancer. >    - zone: internal >      service: http >      source: "172.25.250.10" > EOF firewall_rules:        - zone: internal      service: http      source : "172.25.250.10"  ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables] └─$ 
 
1 2 3 4 5 6 7 8 -  name:  Ensure  Apache  is  deployed   hosts:  web_servers    force_handlers:  True    roles:                -  role:  apache  
 
改造后的目录多出来的
1 2 3 4 5 6 7 8 9 10 ┌──[root@workstation.lab.example.com]-[/home/student/git-repos/inventory-variables/group_vars] └─$tree  . ├── lb_servers │   ├── firewall.yml │   └── haproxy.yml └── web_servers     └── firewall.yml 2 directories, 3 files 
 
同时我们对主机清单文件进行改写
该 playbook 将清单主机 load_balancer 作为负载平衡器来部署,并将组 web_servers 中的主机作为后端 Web 服务器来部署。 编辑 inventory.yml 静态清单⽂件,以便 playbook 中引⽤ load_balancer 主机时使Ansible 连接到 servera.lab.example.com。 清单主机 serverb.lab.example.com和 serverc.lab.example.com 应当位于组 web_servers 中。
1 2 3 4 5 6 7 lb_servers:   hosts:      servera.lab.example.com:  web_servers:   hosts:      server[b:c].lab.example.com:  
 
1 2 3 4 5 6 7 8 lb_servers:   hosts:      load_balancer:        ansible_host:  servera.lab.example.com  web_servers:   hosts:      server[b:c].lab.example.com:  
 
上面的为原来的清单文件,下面为我们改写过的清单文件,这里通过ansible_host清单变量指定了执行时的机器,并且定义了一个别名load_balancer,也就是说,在主机清单为lb_servers所在组执行剧本时,在连接受管主机时,使用当前定义的别名。通过DNS的方式来映射到对应的机器,而不使来用自清单文件(inventory_hostname)  中的名称。
整理参考书籍 《RED HAT 447 Advanced Automation:Ansible Best Practices Edition》