1. 管理变量
1.1 Ansible变量简介
Ansible支持利用变量来存储值,并在Ansible项目的所有文件中重复使用这些值。这可以简化项目的创建和维护,并减少错误的数量。
通过变量,可以轻松地在Ansible项目中管理给定环境的动态值。例如,变量可能包含下面这些值:
- 要创建的用户
- 要安装的软件包
- 要重新启动的服务
- 要删除的文件
- 要从互联网检索的存档
1.1.1 命名变量
变量的名称必须以字母开头,并且只能包含字母、数字和下划线。
无效和有效的Ansible变量名称示例
无效的变量名称 |
有效的变量名称 |
web server |
web_server |
remote.file |
remote_file |
1st file |
file_1 |
remoteserver$1 |
remote_server_1 |
1.1.2 定义变量
可以在Ansible项目中的多个位置定义变量。不过,这些变量大致可简化为三个范围级别:
- 全局范围:从命令行或Ansible配置设置的变量
- Play范围:在play和相关结构中设置的变量
- 主机范围:由清单、事实收集或注册的任务,在主机组和个别主机上设置的变量
如果在多个xeklh定义了相同名称的变量,则采用优先级别最高的变量。窄范围优先于更广泛的范围:由清单定义的变量将被playbook定义的变量覆盖,后者将被命令行中定义的变量覆盖。
1.2 playbook中的变量
变量在Ansible Playbook中发挥着重要作用,因为它们可以简化playbook中变量数据的管理。
1.2.1 在Playbook中定义变量
编写playbook时,可以定义自己的变量,然后在任务中调用这些值。例如,名为web_package的变量可以使用值httpd来定义。然后,任务可以使用yum模块调用该变量来安装httpd软件包。
Playbook变量可以通过多种方式定义。一种常见的方式是将变量放在playbook开头的vars块中:
[root@master project]# ansible all -m ping
web2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
web1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
[root@master project]#
[root@master ~]# cd /opt/project/
[root@master project]# ls
ansible.cfg inventory playbooks
[root@master project]# cd playbooks/
[root@master playbooks]# ls
[root@master playbooks]# vim test.yml
[root@master playbooks]# cat test.yml
---
- hosts: web1
vars:
web: httpd
tasks:
- name: install {
{ web }}
yum:
name: "{
{ web }}"
state: present
[root@master playbooks]#
#语法检查没有问题
[root@master project]# ansible-playbook --syntax-check playbooks/test.yml
playbook: playbooks/test.yml
[root@master project]#
#检查是否能安装
[root@master project]# ansible-playbook -C playbooks/test.yml
PLAY [web1] ********************************************************************************************
TASK [Gathering Facts] *********************************************************************************
ok: [web1]
TASK [install httpd] ***********************************************************************************
ok: [web1]
PLAY RECAP *********************************************************************************************
web1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@master project]#
#成功没有问题
也可以在外部文件中定义playbook变量,也就是同时编译多个变量。此时不使用playbook中的vars块,可以改为使用vars_files指令,后面跟上相对于playbook位置的外部变量文件名称列表:
[root@master project]# cd playbooks/
[root@master playbooks]# ls
test.yml
[root@master playbooks]# mkdir vars
[root@master playbooks]# cd vars
[root@master vars]#
[root@master vars]# vim web.yml
[root@master vars]# cat web.yml
pkg: httpd
port: 82
install_dir: /usr/local/apache
[root@master vars]#
[root@master project]# vim playbooks/test.yml
[root@master project]# cat playbooks/test.yml
---
- hosts: web1
vars_files:
- vars/web.yml
tasks:
- name: install {
{ pkg }}
yum:
name: "{
{ pkg }}"
state: present
[root@master project]#
[root@master project]# ansible-playbook --syntax-check playbooks/test.yml
playbook: playbooks/test.yml
[root@master project]# ansible-playbook -C playbooks/test.yml
[WARNING]: Found variable using reserved name: port
PLAY [web1] ********************************************************************************************
TASK [Gathering Facts] *********************************************************************************
ok: [web1]
TASK [install httpd] ***********************************************************************************
ok: [web1]
PLAY RECAP *********************************************************************************************
web1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@master project]#
1.2.2 在Playbook中使用变量
声明了变量后,可以在任务中使用这些变量。若要引用变量,可以将变量名放在双大括号内。在任务执行时,Ansible会将变量替换为其值。
vars:
user: joe
tasks:
# This line will read: Creates the user joe
- name: Creates the user {
{ user }}
user:
# This line will create the user named joe
name: "{
{ user }}"
注意:当变量用作开始一个值的第一元素时,必须使用引号。这可以防止Ansible将变量引用视为YAML字典的开头。
也就是说,当变量前面有值时就不使用引号;前面有空格是需要加上引号
1.3 主机变量和组变量
直接应用于主机的清单变量分为两在类:
- 主机变量,应用于特定主机
- 组管理,应用于一个主机组或一组主机组中的所有主机
主机变量优先于组变量,但playbook中定义的变量的优先级比这两者更高。
若要定义主机变量和组变量,一种方法是直接在清单文件中定义。这是较旧的做法,不建议采用,但你可能会在未来的工作当中遇到。
定义172.16.103.129的ansible_user主机变量:
[servers]
172.16.103.129 ansible_user=joe
定义servers主机组的user组变量:
[servers]
172.16.103.129
172.16.103.130
[servers:vars]
user=joe
定义servers组的user组变量,该组由两个主机组成,每个主机组有两个服务器:
[servers1]
node1.example.com
node2.example.com
[servers2]
node3.example.com
node4.example.com
[servers:children]
servers1
servers2
[servers:vars]
user=joe
1.3.1 使用目录填充主机和组变量
定义主机和主机组的变量的首选做法是在与清单文件或目录相同的工作目录中,创建group_vars和host_vars两个目录。这两个目录分别包含用于定义组变量和主机变量的文件。
建议的做法是使用host_vars和group_vars目录定义清单变量,而不直接在清单文件中定义它们。
为了定义用于servers组的组变量,需要创建名为group_vars/servers的YAML文件,然后该文件的内容将使用与playbook相同的语法将变量设置为值:
[root@master project]# mv playbooks/* .
[root@master project]# ls
ansible.cfg group_vars host_vars inventory playbooks test.yml vars
[root@master project]# rm -rf playbooks/
[root@master project]# mv test.ym