ansible系列(20)--ansible的变量详解
1. Ansible Variables
变量提供了便捷的方式来管理 ansible
项目中的动态值。 比如 nginx-1.12
,可能后期会反复的使用到这个版本的值,那么如果将此值设置为变量,后续使用和修改都将变得非常方便。这样可以简化项目的创建和维护。
变量名:仅能由字母、数字和下划线组成,且只能以字母开头。
1.1 变量定义的方式
在 Ansible
中定义变量分为如下三种方式:
-
- 通过
ansible-playbook
命令行传递变量参数定义;
- 通过
-
- 在
play
文件中进行定义变量;
- 2.1) 通过
vars
定义变量; - 2.2) 通过
vars_files
定义变量;
- 在
-
- 通过
inventory
在主机组或单个主机中设置变量;
- 3.1) 通过
host_vars
对主机进行定义; - 3.2) 通过
group_vars
对主机组进行定义; - 3.3) 通过inventory-hosts主机清单文件中定义变量;
- 通过
1.2 在playbook中定义变量
1.2.1 使用vars方式定义变量
在 playbook
的文件中开头通过 vars
关键字进行变量定义,格式如下:
vars:
- var1: value1
- var2: value2
使用示例如下,定义变量,使用debug
模块打印变量:
[root@xuzhichao ansible_var]# cat test1.yml
---
- hosts: 192.168.20.23
remote_user: root
vars:
- web_packages: httpd
- ftp_packages: vsftpd
tasks:
- name: Print Vaiables
debug:
msg:
- "{{ web_packages }}"
- "{{ ftp_packages }}"
执行结果,打印变量的值:
[root@xuzhichao ansible_var]# ansible-playbook test1.yml
PLAY [192.168.20.23] *****************************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************************************
ok: [192.168.20.23]
TASK [Print Vaiables] ****************************************************************************************************************************************
ok: [192.168.20.23] => {
"msg": [
"httpd", <==变量的内容
"vsftpd" <==变量的内容
]
}
PLAY RECAP ***************************************************************************************************************************************************
192.168.20.23 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
1.2.2 使用vars_file方式定义变量
在 playbook
中使用 vars_files
指定文件作为变量文件,好处就是其他的playbook
也可以调用。
使用示例如下:
-
编写一个
vars_files
文件,专门用于存放变量:[root@xuzhichao ansible_var]# cat vars.yml web_packages: httpd ftp_packages: vsftpd
-
编写
playbook
文件,调用变量文件:[root@xuzhichao ansible_var]# cat test2.yml --- - hosts: 192.168.20.23 remote_user: root vars_files: ./vars.yml tasks: - name: Print Vaiables debug: msg: - "{{ web_packages }}" - "{{ ftp_packages }}"
-
执行结果,打印变量的值:
[root@xuzhichao ansible_var]# ansible-playbook test2.yml PLAY [192.168.20.23] ***************************************************************************************************************************************** TASK [Gathering Facts] *************************************************************************************************************************************** ok: [192.168.20.23] TASK [Print Vaiables] **************************************************************************************************************************************** ok: [192.168.20.23] => { "msg": [ "httpd", "vsftpd" ] } PLAY RECAP *************************************************************************************************************************************************** 192.168.20.23 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
1.3 针对每个主机定义变量
1.3.1 Inventory文件中定义变量
示例一:分别为每个主机设置不同的主机名:
-
在
Inventory
文件中为每个主机定义变量:[root@xuzhichao ansible_var]# cat /etc/ansible/hosts [NginxWebs] 192.168.20.22 hostname=nginx02 192.168.20.23 hostname=nginx03
-
编写
playbook
,修改主机名:[root@xuzhichao ansible_var]# cat test3.yml --- - hosts: NginxWebs remote_user: root tasks: - name: Set Hostname hostname: name: "{{ hostname }}" [root@xuzhichao ansible_var]# ansible-playbook test3.yml
示例二:设置组公共变量:
-
编写
hosts
文件中的变量:[root@xuzhichao ansible_var]# cat /etc/ansible/hosts [NginxWebs] 192.168.20.22 myid=1 state=master 192.168.20.23 myid=2 state=slave [NginxWebs:vars] port=80
-
编写
playbook
文件:[root@xuzhichao ansible_var]# cat test4.yml --- - hosts: NginxWebs remote_user: root tasks: - name: Print Vaiables debug: msg: - "{{ myid }}-{{ state }}-{{ port }}"
-
运行
playbook
文件:[root@xuzhichao ansible_var]# ansible-playbook test4.yml PLAY [NginxWebs] ********************************************************************************************************************************************* TASK [Gathering Facts] *************************************************************************************************************************************** ok: [192.168.20.22] ok: [192.168.20.23] TASK [Print Vaiables] **************************************************************************************************************************************** ok: [192.168.20.22] => { "msg": [ "1-master-80" <==显示的内容 ] } ok: [192.168.20.23] => { "msg": [ "2-slave-80" <==显示的内容 ] } PLAY RECAP *************************************************************************************************************************************************** 192.168.20.22 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.20.23 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
1.3.2 使用host_vars定义变量
注意:在host_vars
目录中定义的变量,只能给对应的主机使用,没有定义变量的主机不能使用此处的变量。
-
在项目目录中创建
host_vars
目录,然后在创建一个文件,文件的文件名称要与inventory
清单中的主机名称要保持完全一致,如果是ip
地址,则创建相同ip
地址的文件即可:[root@xuzhichao ansible_var]# cat /etc/ansible/hosts [NginxWebs] 192.168.20.22 192.168.20.23 [root@xuzhichao ansible_var]# mkdir host_vars [root@xuzhichao ansible_var]# cd host_vars/ [root@xuzhichao host_vars]# cat 192.168.20.22 web_packages: httpd ftp_packages: vsftpd [root@xuzhichao host_vars]# cat 192.168.20.23 web_packages: nginx ftp_packages: tftp
-
编写
palybook
文件:[root@xuzhichao host_vars]# cat ../test5.yml --- - hosts: NginxWebs remote_user: root tasks: - name: Print Vaiables debug: msg: - "{{ web_packages }}" - "{{ ftp_packages }}"
-
运行
playbook
文件:[root@xuzhichao ansible_var]# ansible-playbook test5.yml PLAY [NginxWebs] ********************************************************************************************************************************************* TASK [Gathering Facts] *************************************************************************************************************************************** ok: [192.168.20.23] ok: [192.168.20.22] TASK [Print Vaiables] **************************************************************************************************************************************** ok: [192.168.20.22] => { "msg": [ "httpd", "vsftpd" ] } ok: [192.168.20.23] => { "msg": [ "nginx", "tftp" ] } PLAY RECAP *************************************************************************************************************************************************** 192.168.20.22 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.20.23 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
1.3.3 使用group_vars定义变量
-
在项目目录中创建
group_vars
目录,然后在创建一个文件,文件的文件名称要与inventory
清单中的组名称保持完全一致;[root@xuzhichao ansible_var]# cat /etc/ansible/hosts [NginxWebs] 192.168.20.22 192.168.20.23 [root@xuzhichao ansible_var]# mkdir group_vars [root@xuzhichao ansible_var]# cd group_vars [root@xuzhichao group_vars]# cat NginxWebs port: 80
-
编写
palybook
文件:[root@xuzhichao ansible_var]# cat test6.yml --- - hosts: NginxWebs remote_user: root tasks: - name: Print Vaiables debug: msg: - "{{ port }}"
-
运行
playbook
文件:[root@xuzhichao ansible_var]# ansible-playbook test6.yml PLAY [NginxWebs] ********************************************************************************************************************************************* TASK [Gathering Facts] *************************************************************************************************************************************** ok: [192.168.20.23] ok: [192.168.20.22] TASK [Print Vaiables] **************************************************************************************************************************************** ok: [192.168.20.22] => { "msg": [ 80 ] } ok: [192.168.20.23] => { "msg": [ 80 ] } PLAY RECAP *************************************************************************************************************************************************** 192.168.20.22 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.20.23 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
注意:在group_vars
目录中定义的组文件,只能改组中的主机使用,不是该组的主机无法使用此处定义的变量。
在系统中提供了一个特殊的 all
组,也就说在 group_vars
目录下创建一个 all
文件,定义变量对所有的主机组都生效;
[root@xuzhichao ansible_var]# cd group_vars/
[root@xuzhichao group_vars]# cat all
port: 80
1.4 通过执行Playbook传递变量
在执行Playbook
时,可以通过命令行 --extra-vars
或 -e
外置传参设定变量;
-
playbook
文件如下:[root@xuzhichao ansible_var]# cat test5.yml --- - hosts: NginxWebs remote_user: root tasks: - name: Print Vaiables debug: msg: - "{{ web_packages }}" - "{{ ftp_packages }}"
-
执行 playbook 时进行变量的传递:
[root@xuzhichao ansible_var]# ansible-playbook -e "web_packages=tomcat" -e "ftp_packages=sftp" test5.yml PLAY [NginxWebs] ********************************************************************************************************************************************* TASK [Gathering Facts] *************************************************************************************************************************************** ok: [192.168.20.23] ok: [192.168.20.22] TASK [Print Vaiables] **************************************************************************************************************************************** ok: [192.168.20.22] => { "msg": [ "tomcat", "sftp" ] } ok: [192.168.20.23] => { "msg": [ "tomcat", "sftp" ] } PLAY RECAP *************************************************************************************************************************************************** 192.168.20.22 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.20.23 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
1.5 变量定义的优先级
1.5.1 编写测试环境
定义相同的变量不同的值,来测试变量的优先级。操作步骤如下:
-
在
plabook
中定义vars
变量:[root@xuzhichao ansible_var]# cat test.yml --- - hosts: 192.168.20.23 remote_user: root vars: - test_var: "playbook var" vars_files: ./vars.yml tasks: - name: Print Vaiables debug: msg: - "{{ test_var }}"
-
在
playbook
中定义vars_files
变量:[root@xuzhichao ansible_var]# cat vars.yml test_var: vars_files
-
在
host_vars
中定义变量:[root@xuzhichao ansible_var]# cat host_vars/192.168.20.23 test_var: host_vars
-
在
group_vars
中定义变量:[root@xuzhichao ansible_var]# cat group_vars/NginxWebs test_var: groups_vars
-
在
group_vars
目录中的all文件中定义变量:[root@xuzhichao ansible_var]# cat group_vars/all test_var: all_file_var
-
在
inventory
中定义主机变量和主机组变量:[root@xuzhichao ansible_var]# cat /etc/ansible/hosts [NginxWebs] 192.168.20.22 test_var=inventory_host_var 192.168.20.23 test_var=inventory_host_var [NginxWebs:vars] test_var=inventory_group_var
-
通过执行命令传递变量:
ansible-playbook -e "test_var=ansible-playbook_var" test.yml
1.5.2 测试变量的优先级
测试思路:运行playbook
文件,当前显示的就是优先级最高的,然后把优先级最高的变量删除,再依次向下测试。
-
最优先的为命令行传递的参数:
[root@xuzhichao ansible_var]# ansible-playbook -e "test_var=ansible-playbook_var" test.yml TASK [Print Vaiables] ************************************************************************************************************************** ok: [192.168.20.23] => { "msg": [ "ansible-playbook_var" ] }
-
然后是在
playbook
中定义的vars_files
变量:[root@xuzhichao ansible_var]# ansible-playbook test.yml TASK [Print Vaiables] ************************************************************************************************************************** ok: [192.168.20.23] => { "msg": [ "vars_files" ] }
-
然后是在
plabook
中定义的vars
变量:#删除playbook中的vars_files: ./vars.yml行再进行测试: [root@xuzhichao ansible_var]# ansible-playbook test.yml TASK [Print Vaiables] ************************************************************************************************************************** ok: [192.168.20.23] => { "msg": [ "playbook var" ] }
-
然后是在
host_vars
中定义的变量#删除playbook中的vars:行再进行测试: [root@xuzhichao ansible_var]# ansible-playbook test.yml TASK [Print Vaiables] ************************************************************************************************************************* ok: [192.168.20.23] => { "msg": [ "host_vars" ] }
-
然后是在
inventory
中定义的主机变量:#删除host_vars/192.168.20.23文件,再进行测试: root@xuzhichao ansible_var]# ansible-playbook test.yml TASK [Print Vaiables] ************************************************************************************************************************* ok: [192.168.20.23] => { "msg": [ "inventory_host_var" ] }
-
然后是在
group_vars
中定义的组变量:#删除/etc/ansible/hosts中192.168.20.23的主机变量,再进行测试: [root@xuzhichao ansible_var]# ansible-playbook test.yml TASK [Print Vaiables] ************************************************************************************************************************* ok: [192.168.20.23] => { "msg": [ "groups_vars" ] }
-
然后是在
group_vars
中定义的all文件中的变量:#删除group_vars/NginxWebs文件,再进行测试: [root@xuzhichao ansible_var]# ansible-playbook test.yml TASK [Print Vaiables] ************************************************************************************************************************* ok: [192.168.20.23] => { "msg": [ "all_file_var" ] }
-
然后是在
inventory
中定义的主机组变量:#删除group_vars/all文件,再进行测试: [root@xuzhichao ansible_var]# ansible-playbook test.yml TASK [Print Vaiables] ************************************************************************************************************************* ok: [192.168.20.23] => { "msg": [ "inventory_group_var" ] }
1.5.3 变量优先级总结
变量的优先级从高到低依次为:
- 命令行传递的变量;
playbook
中定义的vars_files
;playbook
中定义的vars
;- 在
host_vars
中定义的变量; - 在
inventory
中定义的主机变量; - 在
group_vars
中定义的组变量:group_vars/group_name
; - 在
group_vars
中定义的all文件中的变量:group_vars/all
; - 在
inventory
中定义的主机组变量;