DO447管理清单–管理清单变量
RHCSA专栏:戏说 RHCSA 认证
RHCE专栏:戏说 RHCE 认证
此文章(第二章 管理清单–管理清单变量 )收录在RHCA专栏:RHCA 回忆录
文章目录
📜2.1 描述变量基本原理
变量允许您编写可重用和灵活的任务、角色和剧本。它们允许您指定不同系统之间配置的差异。在许多不同的地方设置变量,包括:
-
在角色的defaults和vars目录中。
-
在清单文件中,可以作为主机变量或组变量。
-
在playbook或inventory的group_vars或host_vars子目录下的变量文件中。
-
在play, role, task中
在一个项目中定义和管理变量时,遵循以下原则:
📑保持简单
尽管Ansible变量可以用许多不同的方式定义,但请尝试使用两种不同的方法在少数地方定义变量
📑不要重复自己
如果一组系统具有公共配置,则将它们组织到一个组中,并在group_vars目录下的文件中为它们设置清单变量。这样,就不必在每台主机上定义相同的设置,并且当您必须修改那组系统的变量时,可以通过更新变量文件来实现。
📑在小的、可读的文件中组织变量
如果有一个带有许多主机组和变量的大型项目,请将变量定义拆分为多个文件。为了更容易找到特定的变量,可以将相关的变量分组到一个文件中,并给该文件一个有意义的名称。
也可以使用子目录而不是host_vars和group_vars中的文件。因此,例如,对于组webserver,您可以有一个目录组vars/webserver,该目录可以包含一个名为firewall.yml,其中只包含与防火墙配置相关的变量。该目录还可以包含与服务器配置的其他部分相关的其他组变量文件。
📜2.2 引入变量合并和优先级
当你用多种方式定义同一个变量时。Ansible使用优先级规则为变量选择一个值。在处理完所有的变量定义后,Ansible在每个任务开始时为每个主机生成一组合并的变量。
当Ansible合并变量时,如果同一个变量在不同的位置有两个定义,它将使用优先级最高的位置的值。
📑命令行选项
除了用于额外变量的-e之外,可以在命令行上传递给ansible-playbook的选项具有最低的优先级。例如,您可以使用-u选项设置远程用户来覆盖配置文件,但是可以通过设置ansible_user以更高的优先级来覆盖它。
📑默认角色
在rolename/defaults/文件中由角色设置的默认值具有非常低的优先级,因此它们很容易被覆盖。使用这些默认值是为了让角色的变量定义为一些合理的值,但也可以配置为其他值,因此角色默认值通常用于角色的用户配置。
📑主机和组变量
可以在许多地方设置特定于主机和特定于组的变量。可以根据你的清单位置来设置它们。您可以根据剧本的位置设置它们。最后,您可以通过收集主机事实(或从缓存中读取事实)来设置它们。
这些变量的精确优先级列表从低到高:
-
直接设置在清单文件或动态清单脚本中的组变量。
-
在清单的group_vars/all文件或子目录中设置所有变量组。
-
对剧本的group_vars/all文件或子目录中的所有设置的变量进行分组。
-
为清单的group_vars子目录中设置的其他组的变量分组。
-
为剧本的group_vars子目录中设置的其他组的变量分组。
-
主机变量直接设置在清单文件或由一个动态清单脚本。
-
主机变量设置在清单的host_vars子目录中。
-
在playbook的host_vars子目录中设置主机变量。
-
宿主事实和缓存事实。
这里最大的困惑在于group_vars和host_vars子目录相对于清单和相对于playbook之间的区别。这样做的一个原因是,如果在使用剧本的同一目录中使用静态清单文件,那么这并没有区别。
如果group_vars和host_vars子目录与playbook在同一个目录中,那么这些组和主机变量将被自动包含。
如果在某个目录中使用的是一个平面清单文件,而不是playbook所在的目录,那么清单文件目录中的group_vars和host_vars目录也将被自动包含。但是,**如果存在冲突,剧本目录中包含的变量将覆盖它们。**例如,如果你使用/etc/ansible/hosts作为清单目录,然后/etc/ansible/group_vars将被用作另一个组变量目录。
如果正在使用包含多个清单文件的清单目录,那么将包括清单目录的group_vars和host_vars子目录
例如,思考下面的树形结构:
playbook.yml文件就是playbook。ansible.cfg文件将清单目录配置为inventory, phoenix-dc和singapore-dc是两个基于ini的静态清单文件。
文件inventory/group_vars/all根据inventory的配置为group all加载组变量。
文件group_vars/all根据剧本的位置为group all加载组变量。在发生冲突的情况下,这些设置覆盖inventory/group_vars/all。
**注意:**这种区别的值是,可以为与清单文件捆绑在一起的变量设置默认值,这些文件是所有剧本共享的。但是仍然可以在单独的playbook目录中覆盖这些清单变量的设置。
虽然您可以在清单文件中直接设置主机或组变量(就像前面的例子中的phoenix-dc),但这通常不是一个好做法。如果将应用于主机或组的所有变量设置分组在一个或多个仅包含该主机或组设置的文件中,那么查找应用于该主机或组的所有变量设置就容易得多。如果还必须检查清单文件,这可能会花费更多的时间,而且容易出错,特别是对于大型清单。
📑剧本变量
下一类变量是剧本中设置的作为剧本、任务、角色参数的一部分的变量,或者包括或导入的变量。它们的优先级高于主机或组变量、角色默认值和命令行选项(除了-e)。
这些变量的优先级从低到高依次为:
-
剧本的vars部分设定的。
-
通过在剧本中使用vars_prompt部分提示用户来设置。
-
通过剧本的vars_files部分从外部文件列表中设置。
-
通过角色的rolename/vars/子目录中的文件设置。
-
为当前块设置一个vars部分。
-
设置当前任务的vars部分。
-
用include_vars模块动态加载。
-
通过使用set_fact模块或使用register来记录任务在主机上执行的结果来为特定的主机设置。
-
在剧本中的角色部分或使用include_role模块加载时为剧本中的角色设置的参数。
-
由include_tasks模块中包含的任务的vars部分设置。
注意到剧本中正常的vars部分在这个类别中优先级最低,这一点很重要。如果需要,有很多方法可以覆盖这些设置。这里设置的变量通常会覆盖特定于主机和特定于组的设置。
使用vars_prompt可能不是最佳实践。它需要在运行Ansible -playbook时进行交互,并且与红帽Ansible Tower不兼容。
vars_files指令对于通过函数将非主机或组特定的大型变量列表组织到单独的文件中非常有用。它还可以帮助您将敏感变量从不敏感和不需要加密的变量中分离到一个由Ansible Vault加密的单独文件。
可以设置仅适用于特定块或任务的变量。这些值覆盖了剧本变量和清单变量。应该很少使用它们,因为它们会使剧本变得更复杂。
注意,include_vars加载的变量具有较高的优先级,可以覆盖为角色和特定块和任务设置的变量。在许多情况下,如果不希望用外部变量文件覆盖这些值,则可能希望使用vars_files代替。
set_fact模块和register指令都设置了特定于主机的信息,要么是一个事实,要么是任务在该主机上执行的结果。注意,set_fact为运行剧本的其余部分设置了一个非常高的变量优先级值,但是如果您缓存了该事实,它将以正常的事实优先级(低于play变量)存储在事实缓存中。
📑Extra变量
使用ansible-playbook命令的-e选项设置的额外变量总是具有最高的优先级。这很有用,这样就可以从命令行覆盖剧本中变量的全局设置,而无需编辑任何Ansible项目的文件。
📜课外:笼统概括与查看官网的详细排序
##### ansibl变量的优先级 #####
- extra vars变量(在命令行中使用 -e);优先级最高
- 在inventory中定义的连接变量(比如ansible_ssh_user);优先级第二
- 大多数的其他变量(命令行转换,play中的变量,include的变量,role的变量等);优先级第三
- 在inventory定义的其他变量;优先级第四
- 有系统发现的facts;优先级第五
- “role默认变量”,这个是最默认的值,很容易丧失优先权。优先级最小。
##### inventory清单列表里定义变量:单个主机定义的变量优先级高于主机组定义的变量#####
ansible使用inventory定义变量的优先级顺序从高到低为:
- host_vars下定义变量
- inventory中单个主机定义变量
- group_vars下定义变量
- inventory中组定义变量
其实,此时,我们应该查看官网,官网有更详细的排序:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#id15
1. command line values (for example, -u my_user, these are not variables)
2. role defaults (defined in role/defaults/main.yml)
3. inventory file or script group vars
4. inventory group_vars/all
5. playbook group_vars/all
6. inventory group_vars/*
7. playbook group_vars/*
8. inventory file or script host vars
9. inventory host_vars/*
10. playbook host_vars/*
11. host facts / cached set_facts
12. play vars
13. play vars_prompt
14. play vars_files
15. role vars (defined in role/vars/main.yml)
16. block vars (only for tasks in block)
17. task vars (only for the task)
18. include_vars
19. set_facts / registered vars
20. role (and include_role) params
21. include params
22. extra vars (for example, -e "user=my_user")(always win precedence)
📜2.3 从清单中分离变量
清单源定义了Ansible使用的主机和主机组,无论它们是静态文件还是动态清单脚本。如果以静态文件的形式管理清单,则可以在清单文件中定义变量,这些文件与定义主机和主机组列表的文件相同。然而,这并不是最佳实践。随着环境的大小和种类的增加,清单文件会变得很大且难以读取。
此外,可能希望迁移到动态清单源,而不是静态清单文件,以便更容易地管理清单。但是可能仍然希望能够静态地管理清单变量,与动态清单脚本的输出分开或附加在一起。
更好的方法是将变量定义从清单文件移动到单独的变量文件中,每个主机组一个变量文件。每个变量文件以主机组命名,包含主机组的变量定义:
这种结构使查找任何主机组的配置变量(db_servers、lb_servers或web_servers)变得更容易。只要每个主机组包含少量的变量定义,上述组织结构就足够了。但正如剧本,复杂性增加了,甚至这些文件也可能变得很长,难以理解。
对于大型、多样的环境,一种更好的方法是在group_vars目录下为每个主机组创建子目录。Ansible解析这些子目录中的任何YAML,并根据父目录将变量与主机组关联:
在前面的例子中,myvars.yml中的变量文件与主机组db_servers相关联,因为该文件包含在group_vars/db_servers子目录中。然而,这个例子中的文件名使我们很难知道在哪里找到一个特定的变量。
如果选择对变量使用这种组织结构,请将具有公共主题的变量分组到同一个文件中,并使用文件名表示该公共主题。当剧本使用角色时,通常的惯例是创建以剧本中的每个角色命名的变量文件。
项目的这种组织结构允许快速查看为每个主机组定义的变量类型。
在group_vars目录下的文件中的所有变量都与其他变量合并在一起。将变量划分为按功能分组的文件可以使整个剧本项目更容易理解和维护。
📜2.4 特殊清单变量
有许多变量可以用来改变Ansible如何连接到清单中列出的主机。其中一些作为特定于主机的变量最有用。但其他主机可能与组或清单中的所有主机相关。
📑ansible_connection
用于访问托管主机的连接插件。缺省情况下,除了使用local的localhost,所有主机都使用ssh。
📑ansible_host
连接到托管主机时要使用的实际IP地址或完全限定域名,而不是使用清单文件中的名称(inventory_hostname)。默认情况下,这个变量的值与清单主机名相同。
📑ansible_port
Ansible用于连接被管理主机。对于(默认的)SSH连接插件,值默认为22。
📑ansible_user
Ansible以这个用户连接到被管理的主机。Ansible的默认行为是使用与在控制节点上运行Ansible Playbook的用户相同的用户名连接到托管主机。
📑ansible_become_user
一旦Ansible连接到托管主机,它将使用ansible_become_method(默认为sudo)切换到该用户。您可能需要以某种方式提供身份验证凭据。
📑ansible_python_interpreter
Ansible应该在托管主机上使用的Python可执行文件的路径。在Ansible2.8及以后版本,默认为auto,它会自动选择Python解释器管理清单运行playbook的主机取决于它运行的是什么操作系统,所以与旧版本的Ansible相比,使用这个设置是不太必要的。
📜2.5 使用变量识别当前主机
当一个剧本正在运行时,有许多变量和事实可以用来识别当前执行任务的托管主机的名称:
📑inventory_hostname
当前正在处理的托管主机的名称,从清单中获取。
📑ansible_host
如前所述,用于连接受管理主机的实际IP地址或主机名。
📑ansible_facts[‘hostname’]
作为事实从托管主机收集的短主机名。
📑ansible_facts[‘fqdn’]
作为事实从托管主机收集的完全合格域名(FQDN)。
最后一个有用的变量是ansible_play_hosts,它是当前运行期间尚未失败的所有主机的列表(因此将用于运行中剩余的任务)。
📜2.6 课本练习
[student@workstation ~]$ lab inventory-variables start
📑拉取项目代码文件
[student@workstation ~]$ mkdir -p /home/student/git-repos/
[student@workstation ~]$ cd /home/student/git-repos
[student@workstation git-repos]$ git clone http://git.lab.example.com:8081/git/inventory-variables.git
Cloning into 'inventory-variables'...
remote: Enumerating objects: 53, done.
remote: Counting objects: 100% (53/53), done.
remote: Compressing objects: 100% (37/37), done.
remote: Total 53 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (53/53), done.
📑创建主机组变量并修改运行剧本
[student@workstation git-repos]$ cd inventory-variables
[student@workstation inventory-variables]$ mkdir group_vars
[student@workstation inventory-variables]$ mkdir group_vars/lb_servers
[student@workstation inventory-variables]$ mkdir group_vars/web_servers
[student@workstation inventory-variables]$ vim group_vars/lb_servers/firewall.yml
firewall_rules:
# Allow 80/tcp connections
- port: 80/tcp
[student@workstation inventory-variables]$ vim group_vars/lb_servers/haproxy.yml
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
[student@workstation inventory-variables]$ vim deploy_haproxy.yml # 删除后面的定义
- name: Ensure HAProxy is deployed
hosts: lb_servers
force_handlers: True
roles:
# The "haproxy" role has a dependency on the "firewall" role.
# The "firewall" role requires a "firewall_rules" variable be defined.
- role: haproxy
[student@workstation inventory-variables]$ vim group_vars/web_servers/firewall.yml
firewall_rules:
# Allow http requests from any internal zone source.
- zone: internal
service: http
source: "172.25.250.10"
[student@workstation inventory-variables]$ vim deploy_apache.yml
- name: Ensure Apache is deployed
hosts: web_servers
force_handlers: True
roles:
# The "apache" role has a dependency on the "firewall" role.
# The "firewall" role requires a "firewall_rules" variable be defined.
- role: apache
📑修改主机清单
[student@workstation inventory-variables]$ vim inventory.yml
lb_servers:
hosts:
load_balancer:
ansible_host: servera.lab.example.com
web_servers:
hosts:
server[b:c].lab.example.com:
📑运行剧本
[student@workstation inventory-variables]$ ansible-playbook site.yml --syntax-check
playbook: site.yml
[student@workstation inventory-variables]$ ansible-playbook site.yml
📑可自我进行验证
[student@workstation inventory-variables]$ curl http://servera
This is serverb. (version v1.0)
[student@workstation inventory-variables]$ curl http://servera
This is serverc. (version v1.0)
📑提交代码
[student@workstation inventory-variables]$ git add .
[student@workstation inventory-variables]$ git commit -m "Use group_vars"
[master ad29a6d] Use group_vars
6 files changed, 17 insertions(+), 19 deletions(-)
create mode 100644 group_vars/lb_servers/firewall.yml
create mode 100644 group_vars/lb_servers/haproxy.yml
create mode 100644 group_vars/web_servers/firewall.yml
[student@workstation inventory-variables]$ git push
Enumerating objects: 15, done.
Counting objects: 100% (15/15), done.
Delta compression using up to 4 threads.
Compressing objects: 100% (10/10), done.
Writing objects: 100% (11/11), 1.08 KiB | 1.08 MiB/s, done.
Total 11 (delta 3), reused 0 (delta 0)
To http://git.lab.example.com:8081/git/inventory-variables.git
436eb56..ad29a6d master -> master
📑清除实验
[student@workstation inventory-variables]$ lab inventory-variables finish
💡总结
RHCA认证需要经历5门的学习与考试,还是需要花不少时间去学习与备考的,好好加油,可以噶🤪。
以上就是【金鱼哥】对 第二章 管理清单–管理清单变量 的简述和讲解。希望能对看到此文章的小伙伴有所帮助。
如果这篇【文章】有帮助到你,希望可以给【金鱼哥】点个赞👍,创作不易,相比官方的陈述,我更喜欢用【通俗易懂】的文笔去讲解每一个知识点,如果有对【运维技术】感兴趣,也欢迎关注❤️❤️❤️ 【金鱼哥】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💕💕!