> 文章列表 > 《Linux运维实战:ansible中的变量定义及以及变量的优先级》

《Linux运维实战:ansible中的变量定义及以及变量的优先级》

《Linux运维实战:ansible中的变量定义及以及变量的优先级》

一、配置文件优先级

Ansible配置以ini格式存储配置数据,在Ansible中⼏乎所有配置都可以通过Ansible的Playbook或环境变量来重新赋值。在运⾏Ansible命令时,命令将会按照以下顺序查找配置⽂件。

# ⾸先,Ansible命令会检查环境变量,及这个环境变量指向的配置⽂件。 例如:export ANSIBLE_CONFIG=/PATH/ansible.cfg
# 其次,将会检查当前⽬录下的ansible.cfg配置⽂件
# 再次,将会检查当前⽤户home⽬录下的ansible.cfg配置⽂件
# 最后,将会检查在⽤软件包管理⼯具安装Ansible时⾃动产⽣的配置⽂件

二、变量命名

变量的名称必须以字母开头,并且只能包含字母、数字和下划线。


三、变量优先级

* extra vars (-e in the command line) always win
* then comes connection variables defined in inventory (ansible_ssh_user, etc)
* then comes "most everything else" (command line switches, vars in play, included vars, role vars, etc)
* then comes the rest of the variables defined in inventory
* then comes facts discovered about a system
* then "role defaults", which are the most "defaulty" and lose in priority to everything.* extra vars (在命令行中使用 -e)优先级最高
* 然后是在inventory中定义的连接变量(比如ansible_ssh_user)
* 接着是大多数的其它变量(命令行转换,play中的变量,included的变量,role中的变量等)
* 然后是在inventory定义的其它变量
* 然后是由系统发现的facts
* 然后是 "role默认变量", 这个是最默认的值,很容易丧失优先权

四、变量分类

可以在Ansible项目中的多个位置定义变量。不过,这些变量可简化为三个范围级别:

# 全局范围:从命令行或Ansible的配置文件设置的变量
# Play范围:在play和相关结构中设置的变量
# 主机范围:由清单、事实收集或注册的任务,在主机组和个别主机上设置的变量

4.1、playbook中的变量

可以在playbook剧本任务中定义变量,主要有两种方式。一种是在将变量放在playbook开头的vars块中,另外一种是在外部文件中定义playbook变量。

示例一:在playbook开头的vars块中定义变量,如下所示:

- hosts: - allremote_user: rootroles:- allinone1vars:role: masterservice: mysql

示例二:在外部文件中定义playbook变量,如下所示:

- hosts: allremote_user: rootvars:favcolor: bluevars_files:- /opt/external_vars.yml

说明:声明了变量后,可以在任务中使用这些变量。若要引用变量,可以将变量名放在双大括号内。在任务执行时,Ansible会将变量替换为其值。切记- name中定义任务的名称,不能以变量开头,即{{ }}开头。
《Linux运维实战:ansible中的变量定义及以及变量的优先级》


4.2、主机变量和组变量

应用于主机的清单文件分为两种,一种是主机变量,应用于特定主机,另外一种是主机组变量,应用于一个主机组或一组主机组中的所有主机。主机变量优先于组变量, 但playbook中定义的变量的优先级比这两者更高。定义主机变量和组变量有两种方式,一种是直接在主机清单hosts文件中定义,一种是创建host_vars和group_vars目录。

1、在主机清单hosts文件中定义变量

示例一:主机变量
《Linux运维实战:ansible中的变量定义及以及变量的优先级》

示例二:主机组变量
《Linux运维实战:ansible中的变量定义及以及变量的优先级》

2、在host_vars和group_vars目录中创建定义变量文件

注意:主机和主机组的目录名必须是host_vars和group_vars,且与清单文件所在目录相同。hosts_vars和group_vars对应的变量文件名称必须于清单文件中定义的主机和主机组必须保持一致。

《Linux运维实战:ansible中的变量定义及以及变量的优先级》


4.3、从命令行覆盖变量

从命令行中传递变量有两种方式,一种为直接定义变量,一种为指定一个变量文件。

示例一:命令行中直接定义变量,如下所示:

# 示例一:
# ansible-playbook -i hosts -e "package=apache2" -t buid mysql-cluster.yml

示例二:命令行中指定变量文件,如下所示:

# 示例二
# ansible-playbook -i hosts -e @config.yml  -t check mysql-cluster.yml

4.4、使用迭代数组定义变量

除了将同一元素相关的配置数据(软件包列表、服务列表和用户列表等)分配到多个变量外,也可以使用数组。这种做法的一个好处在于,数组是可以浏览的。

例如,假设有如下代码片段:

《Linux运维实战:ansible中的变量定义及以及变量的优先级》

可以改写成mysql的数组
《Linux运维实战:ansible中的变量定义及以及变量的优先级》

可以使用以下变量来访问用户数据

mysql.work_dir
mysql.data_dir
mysql.root_password
mysql.master.host
mysql.master.port

由于变量被定义为Python字典,因此可以使用替代语法,使用中括号表示法有助于避免冲突和错误:

mysql.['master'].['host']
mysql.['master'].['port']

注意:以上两种语法都有效,但为了方便故障排除,建议在任何给定Ansible项目的所有文件中一致地采用一种语法,不要混用。


4.5、使用register注册变量

可以使用register语句捕获命令输出。输出保存在一个临时变量中,然后在playbook中可用于调试用途或者达成其他目的。
《Linux运维实战:ansible中的变量定义及以及变量的优先级》

总结:当我们给被管理节点安装了某个服务,不晓得有没有安装正确的情况下,可以使用register变量注册的方法,来返回被管理节点的服务信息。

- hosts: dbservertasks:- name: install httpd serveryum: name=httpd state=present- name: service httpd serverservice: name=httpd state=started- name: check httpd servershell: ps aux | grep httpdregister: check_httpd- name: output variablesdebug: msg="{{ check_httpd }}"

如下图所示:
《Linux运维实战:ansible中的变量定义及以及变量的优先级》


4.6、facts事实变量

《Ansible变量篇:ansible中事实变量facts》


4.6、魔法变量

《Ansible变量篇:ansible中魔法变量》


总结:整理不易,如果对你有帮助,可否点赞关注一下?

更多详细内容请参考:《Linux运维篇:Linux系统运维指南》