● ansible支持利用变量储存整个ansible项目文件中可重复使用的值
● 变量的名称由字符串组成,必须以字母开头,并且只能包含字母,数字,下划线
● ansible中变量可以分为三个范围
● Global范围:从命令行或ansible配置设置的变量
● Play范围:在play和相关结构中设置的变量
● Host范围:由inventory、facts或注册的任务,在主机组和个别主机上设置的变量
● 三个范围的变量优先级一次升高,如果变量重复定义,则以优先级高的为准
● 在编写playbook时,管理员可以定义变量并在任务中调用他们
● playbook变量可以通过多种方式定义,最简单方式就是将他放在playbook开头的vars块中
- hosts: all
vars:
user: joe
home: /home/joe
● 也可以在外部文件中定义playbook变量。此时不使用vars,使用vars_files指令,而后以YAML格式在文件中定义playbook
- hosts: all
vars_files:
- vars/users.yml
user: joe
home: /home/joe
● 定义了变量后,管理员可以在任务中使用这些变量。若要引用,可将变量名称放在双花括号内
name: {{ user }}
● 强烈建议变量使用引号,这可防止ansible将变量视为YAML字典的开头。
name: "{{ name }}"
● 直接应用到主机的变量清单可以归为两类:
● 主机变量应用到主机
● 组变量应用到组内所有主机
● 主机变量优先于组变量,但playbook中定义的变量高于这两者
● 建议在与清单文件或目录相同的工作目录中,创建两个目录group_vars和host_vars,分别包含用于组变量和主机变量的特定文件
● 不要直接在一个或多个清单文件中定义主机变量和组变量
● 为了定义用于组servers的组变量,需要创建名为group_var/servers的YAML文件,使用与playbook相同的语法为变量赋值
● 为了定义于特定主机的主机变量,需要在hosts_vars中创建名称与主机匹配的文件,来存放主机变量
inventory变量可被playbook中设置的变量覆盖,这两种变量又可通过在命令行中传递参数到ansible或ansible-playbook命令来覆盖
如果运行playbook时需要针对单个主机变量进行覆盖,可以
$ ansible-playbook demo2.example.com main.yml -e "package=apache"
● 除了将统一元素相关的一组配置数据(软件包列表、服务列表和用户列表等)分配到多个变量外,管理员也可以使用数组。这种做法的好处在于,数组可读性更好
users:
bjones:
first_name: Bob
last_name: Jones
home_dir: /users/acook
调用方法:
users.bjones.first_name
因为变量以python dictionary方式定义,另一种调用方法:
users['bjones']['first_name']
● 管理员可以使用register语句捕获命令输出
● 输出保存在一个变量中,可用于调试用途或其他目的,例如输出命令结果
.........
yum:
name: httpd
state: installed
register: install_result
- debug : var=install_result
● 在该playbook运行时,debug模块将install_result注册变量的值转储到终端
● Ansible事实是Ansible从受管主机自动探查到的变量
● 事实由setup模块调取,其中包含的信息储存到可重复使用的变量中
● ansible事实可以成为playbook的一部分
● 可以根据当前内核版本来重新启动服务器
● 可以根据可用的内存来定义MySQL配置文件
● 可以根据主机名来创建用户
● 对ansible事实的利用几乎不存在任何的限制
● 借助ansible事实,可以方便的检索受管节点的状态,并根据其状态决定要执行的操作
● 事实提供如下相关信息:主机名称,内核版本,网络接口,IP,操作系统版本,各种环境变量,CPU数量,提供或可用的内存,可用的磁盘空间
$ ansible demo1.example.com -m setup
● 输出以JSON格式返回,每个值都存在一个Python字典中。管理员而后可以浏览字典来检索特定值
● 事实:
1. 主机名:{{ ansible_hostname }}
2. IPv4: {{ ansible_default_ipv4.address }}
3. 主磁盘第一分区大小:{{ ansible_device.vda.partitions.vda1.size }}
4. DNS: {{ ansible_dns.nameservers }}
5. 内核版本: {{ ansible_kernel }}
● 在playbook中使用事实,ansible将事实变量名替换相对性的值
● ansible事实包含于系统相关的广泛信息,管理员可以使用ansible过滤器收集facts时限制的结果
● 仅检索与网卡相关的信息
● 仅检索与磁盘相关的信息
● 仅检索与用户相关的信息
● 若要使用过滤器,则利用 (-a ‘filter=EXPRESSION’)将表达式作为选项来传递
● 例如要仅返回eth0的信息,可对ansible_eth0元素应用过滤器
$ ansible demo1.example.com -m setup -a 'filter=ansible_eth0'
● 管理员可以自行创建事实,将他们推送到受管节点
● 创建后,自定义事实可用于
● 基本自定义脚本定义系统特定值
● 基于程序执行定义值
● 如果自定义事实文件保存在/etc/ansible/facts.d目录中,ansible可以找到该事实
● 文件的扩展名必须为.fact ,采用INI或JSON格式的纯文本文件
● 在INI事实文件中,首先是定义事实的顶级分类:[packages],后跟预定义事实的键值对
[packages]
web_package = httpd
db_package = mariadb-server
[users]
user1 = joe
user2 = jane
如果JSON格式
{
"packages": {
"web_package": "httpd",
"db_package" : "mariadb-server"
},
"users": {
"user1": "joe",
"user2": "jean"
}
}
● 对于这两种格式,ansible返回结果相同,且都放入ansible_local级别中。然后,可以利用过滤器确保成功安装并检索了自定义事实
● 在处理复杂的playbook时,可使用单独的文件将任务和变量列表划分成较小的片段,从而简化管理
● 将多个外部文件用于任务和变量,可以将主playbook进行模块化构建,并实现跨多个playbook重复利用ansible元素
● 可以通过多种方式将任务变量包含到playbook中
● 可以通过include将外部文件中的任务(task)包含到playbook中
tasks:
- name: Include tasks to install the database server
include: tasks/db_server.yml
include_vars模块可以包含JSON或YAML文件中的定义变量,覆盖已定义的主机变量和playbook变量
● 一下情境中将一组任务作为与playbook的独立文件来管理会有所帮助
● 如果全新的服务器需要全面配置、管理员可以创建不同的任务集合,分别用于创建用户,安装软件包,配置服务,配置特权,设置共享文件系统,强化服务器,安装安全更新,安装监控代理。每一集合可通过单独的任务文件进行管理
● 如果服务器由开发人员,系统管理员,和数据库管理员统一管理,没人可以编写自己的一组任务,再由系统经理审核集成
● 如果服务器需要特定配置,他可以整合按照某一条件来执行的一组任务
● 如果一组服务器需要运行某一项任务,他们可以在属于特定主机组的服务器上运行
● include指令允许管理员将任务文件插到playbook中某个点上
● 在playbook中使用include指令来指定将什么任务包含在playbook中的哪一个点上
● 管理员可以创建专门用于任务的文件目录,并将所有任务文件保存在该目录,然后,playbook只需要将来自该目录的任务和文件包含在playbook中,这便能够构建复杂的playbook,同时简化管理
● 注意:对于复杂的项目,角色可以提供一种强大的途径来组织包含的任务文件和playbook
● 任务可以包含在playbook中,外部定义的变量也可以包含在playbook中。实现方式多种
● 其中一些设置变量的方式包括:
● 在清单或host_vars 和group_vars 目录的文件中定义变量
● 事实的变量
● 通过vars在playbook文件中定义playbook变量,或者通过vars_files在外部文件定义
● include_vars模块是另一种方式,在playbook中设置来自外部的变量
● 此方式的特别之处在于,他是通过模块来执行的,而且会覆盖利用上述方法设定任何值
● 包含的变量文件可以采用JSON或YAML格式来定义,YAML是首选的语法
● 注意:如果任务要求来自变量文件中的变量,管理员必须在定义该任务之前将变量包含在playbook中
● 注意:再决定变量定义位置时,尽量做到简化
---
packages:
web_package: httpd
db_package: mariadb-server
---
- name: Install Web server
hosts: all
tasks:
- name: Include the variables
include_vars: variables.yml
- name: Debug the variables
debug:
msg: >
"{{ packages['web_package'] }} and {{ package.db_package }}
have been imported"