管理变量
Ansible变量
Ansible支持利用变量来存储值,并在Ansible项目的所有文件中重复使用这些值。这可以简化项目的创建和维护,并减少错误的数量。
通过变量,可以轻松地在Ansible项目中管理给定环境的动态值。例如,变量可能包含下面这些值:
要创建的用户
要安装的软件包
要重新启动的服务
要删除的文件
要从互联网检索到存档
命名变量
命名变量
变量的名称必须以字母开头,并且只能包含字母、数字和下划线。
无效和有效的Ansible变量名称示例
无效的变量名称 | 有效的变量名称 |
---|---|
web server | web_server |
remote.file | remote_file |
1st file | file_1(回车)file1 |
remoteserver$1 | remote_server_1(回车)remote_server1 |
定义变量
可以在Ansible项目中的多个位置定义变量。不过,这些变量大致可简化为三个范围级别:
全局范围:从命令行或Ansible配置设置的变量
Play范围:在play和相关结构中设置的变量
主机范围:由清单、事实收集或注册的任务,在主机组和个别主机上设置的变量
如果在多个xeklh定义了相同名称的变量,则采用优先级别最高的变量。窄范围优先于更广泛的范围:由清单定义的变量将被playbook定义的变量覆盖,后者将被命令行中定义的变量覆盖。
Playbook中的变量
变量在Ansible Playbook中发挥着重要作用,因为它们可以简化playbook中变量数据的管理。
在Playbook中定义变量
编写playbook时,可以定义自己的变量,然后在任务中调用这些值。例如,名为web_package的变量可以使用值httpd来定义。然后,任务可以使用yum模块调用该变量来安装httpd软件包。
Playbook变量可以通过多种方式定义。一种常见的方式是将变量放在playbook开头的vars块中:
- hosts: all
vars:
user: mokf
home: /home/mokf
也可以在外部文件中定义playbook变量。此时不使用playbook中的vars块,可以改为使用vars_files指令,后面跟上相对于playbook位置的外部变量文件名称列表:
- hosts: all
vars_files:
- vars/user.yml
而后,可以使用YAML格式在这一/这些文件中定义playbook变量:
user: mokf
home: /home/mokf
在Playbook中使用变量
声明了变量后,可以在任务中使用这些变量。若要引用变量,可以将变量名放在双大括号内。在任务执行时,Ansible会将变量替换为其值。
vars:
user: mokf
tasks:
- name: create a user
user:
name: "{{ user }}"
注意:当变量用作开始一个值的第一元素时,必须使用引号。这可以防止Ansible将变量引用视为YAML字典的开头。
主机变量和组变量
直接应用于主机的清单变量分为两在类:
主机变量,应用于特定主机
组管理,应用于一个主机组或一组主机组中的所有主机
主机变量优先于组变量,但playbook中定义的变量的优先级比这两者更高。
若要定义主机变量和组变量,一种方法是直接在清单文件中定义。这是较旧的做法,不建议采用,但你可能会在未来的工作当中遇到。
定义192.168.126.136的ansible_user主机变量
[Users]
192.168.126.136 ansible_user=zichen
定义servers主机组的user组变量:
[Users]
192.168.126.144
192.168.126.148
[Users:vars]
user=mokf
定义servers组的user组变量,该组由两个主机组成,每个主机组有两个服务器:
[Users1] //定义两个组
node1.example.com
node2.example.com
[Users2]
node3.example.com
node4.example.com
[Users:children] //给组定义变量
Users1
Users2
[Users:vars] //变量的值
user=mokf
此做法存在一些缺点,它使得清单文件更难以处理,在同一文件中混合提供了主机和变量信息,而且采用的也是过时的语法。
使用目录填充变量
定义主机和主机组的变量的首选做法是在与清单文件或目录相同的工作目录中,创建group_vars和host_vars两个目录。这两个目录分别包含用于定义组变量和主机变量的文件。
建议的做法是使用host_vars和group_vars目录定义清单变量,而不直接在清单文件中定义它们。
从命令行覆盖变量
清单变量可被playbook中设置的变量覆盖,这两种变量又可通过在命令行中传递参数到ansible或ansible-playbook命令来覆盖。在命令行上设置的变量称为额外变量。
使用数组作为变量
除了将同一元素相关的配置数据(软件包列表、服务列表和用户列表等)分配到多个变量外,也可以使用数组。这种做法的一个好处在于,数组是可以浏览的。
如果键名与python方法或属性的名称(如discard、copy和add)相同,点表示法可能会造成问题。使用中括号表示法有助于避免冲突和错误。
但要声明的是,上面介绍的两种语法都有效,但为了方便故障排除,建议在任何给定Ansible项目的所有文件中一致地采用一种语法,不要混用。
使用已注册变量捕获命令输出
可以使用register语句捕获命令输出。输出保存在一个临时变量中,然后在playbook中可用于调试用途或者达成其他目的,例如基于命令输出的特定配置。
以下playbook演示了如何为调试用途捕获命令输出:
---
[root@ansible ~]# vim playbook.yml
[root@ansible ~]# cat playbook.yml
- name: Do a test
hosts: all
tasks:
- name: install the package
yum:
name: httpd
state: installed
register: install_result
- debug: var=install_result
运行该playbook时,debug模块用于将install_result注册变量的值转储到终端。
[root@ansible ~]# ansible-playbook playbook.yml
PLAY [Do a test] *************************************
TASK [Gathering Facts] **************************************************************
ok: [192.168.126.136]
TASK [Install the package] **********************************************************
ok: [192.168.126.136]
TASK [debug] ************************************************************************
ok: [192.168.126.136] => {
"install_result": {
"changed": false,
"failed": false,
"msg": "",
"rc": 0,
"results": [
"httpd-2.4.6-93.el7.centos.x86_64 providing httpd is already installed"
]
}
}
PLAY RECAP **************************************************************************
192.168.126.136 : ok=3 changed=0 unreachable=0 failed=0