目录
一、ansible Variables
1、变量定义的方式
2、变量常用关键字
3、引用变量
4、在playbook中定义变量
1、使用vars方式定义变量
2、示例:提示用户输入信息并写入变量
3、使用vars_file方式定义变量
5、针对每个主机定义变量
1、Inventory文件中定义变量
2、使用host_vars定义变量
3、使用group_vars定义变量
6、通过执行playbook传递变量
7、变量定义的优先级
1、编写测试环境
2、变量的优先级
3、变量优先级总结
二、ansible的变量注册Register
三、层级定义变量
四、facts内置变量
1、常用变量信息
2、在playbook中直接调用facts变量
3、通过set_fact模块定义变量
变量提供了便捷的方式来管理 ansible 项目中的动态值。
变量名:仅能由字母、数字、下划线组成,且只能以字母开头。
1、通过ansible-playbook命令行传递变量参数定义;
2、在play文件中定义;
通过vars定义变量;
通过vars_files定义变量;
3、通过 inventory在主机组或单个主机中设置变量;
通过host_vars对主机进行定义
通过group_vars对主机进行定义
通过inventory-hosts主机清单文件中定义变量;
1、vars_prompt 关键字 :#创建变量,并提示输入信息
vars_prompt.prompt:表示 提示信息
2、encrypt 关键字 :#表示对用户输入的信息进行哈希
#示例:encrypt: “sha512_crypt”表示使用sha512算法对用户输入的信息进行哈希
3、default 关键字 :#设置变量的默认值
示例:如下4.b
4、private 关键字:#表示变量值为非私有的,可见的,默认情况下 private值为yes,表示不可见。
5、confirm 关键字:#实现类似确认密码的功能,
# 我们在为用户设置密码时,通常需要输入两次完全相同的密码,才能够设置成功,通过”confirm”关键字就能实现类似的效果
当我们需要引用变量时,有两种语法
1、语法1
"{{httpd.conf80}}"
2、语法2
"{{nginx['conf8080']}}"
在playbook的文件中开通通过 vars 关键字进行定义变量,格式如下:
vars:
- var1: value1
- var2: value2
#使用变量如下:
---
- hosts: web
remote_user: root
vars:
- var1: test1
- var2: test2
- name: test vars
debug:
msg:
- "{{ var1 }}"
- "{{ var2 }}"
[root@k8s-master-1 test]# ansible-playbook test.yaml
PLAY [web] ********************************************
TASK [Gathering Facts] ********************************
ok: [192.168.134.138]
TASK [Test connectivity] *******************************
ok: [192.168.134.138]
TASK [test vars] ***************************************
ok: [192.168.134.138] => {
"msg": [
"test1",
"test2"
]
}
PLAY RECAP ********************************************
192.168.134.138 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
使用 vars_prompt 关键字
[root@k8s-master-1 variables]# vim test.yaml
---
- hosts: web
remote_user: root
vars_prompt:
- name: "your_name"
prompt: "What is your name"
private: no #设置了此参数,表示在下方输入名字,年龄时候 会显示,就是非私有的、可见的。
- name: "your_age"
prompt: "How old are you"
private: no
tasks:
- name: output vars
debug:
msg: Your name is {{ your_name }},You are {{ your_age }} years old.
[root@k8s-master-1 variables]# ansible-playbook test.yaml
What is your name: 再此输入的信息不回显示,如果添加了private: no 就会显示
How old are you:
ok: [192.168.134.138] => {
"msg": "Your name is wuzhaobo,You are 22 years old."
}
PLAY RECAP ********************************************************
192.168.134.138 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2、我们也可以为提示信息设置默认值,即用户不输入任何信息,则将默认值赋予变量,示例如下:
---
- hosts: web
remote_user: root
vars_prompt:
- name: "your_name"
prompt: "What is your name"
- name: "your_age"
prompt: "How old are you \n
A: 22\n
B: 23\n
C: 24\n"
default: A
private: no
tasks:
- name: output vars
debug:
msg: Your name is {{ your_name }},You are {{ your_age }} years old.
[root@k8s-master-1 variables]# ansible-playbook -C test.yaml
What is your name:
How old are you
A: 22
B: 23
C: 24
[A]: B
ok: [192.168.134.138] => {
"msg": "Your name is we,You are B years old."
}
PLAY RECAP ***************************************************************************
3、编写playbook,使用户输入用户名,密码,根据用户输入的信息创建系统账户。
---
- hosts: web
remote_user: root
vars_prompt:
- name: "user_name"
prompt: "Enter user name"
private: no
- name: "user_password"
prompt: "Enter user password"
private: no
encrypt: "sha512_crypt"
confirm: yes #通常情况下密码需要输入两遍确认,就是设置此关键字
tasks:
- name: create user
user:
name: "{{user_name}}"
password: "{{user_password}}"
tasks:
- name: test password
debug:
msg: Your name is {{ user_name }},You are password is {{ user_password }}.
但是以上信息,用户输入的密码,没有被哈希转换,用户在输入密码时候登陆不上去的,需要做哈希加密处理,使用 encrypt 参数
我们使用debug 来测试密码否加密
[root@k8s-master-1 variables]# ansible-playbook -C test.yaml
Enter user name: wu
Enter user password: 123456
confirm Enter user password: 123456
TASK [test password] *************************************************************************
ok: [192.168.134.138] => {
"msg": "Your name is wu password is $6$L.THtt8pzWP4bAtL$1mAP/nQ75cMdHYpNFrt2G2pi/R35MynlNCCKRtLoE3kfIsuByZDjIRZUO/7EyHE5kIE2MLmEjY0g8q1HZmvnh0."
}
PLAY RECAP *********************************************************************************
192.168.134.138 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
在playbook中使用vars_files指定文件作为变量文件,好处就是其他的playbook也可以调用。
示例:
1、编写一个vars_files文件,专门用来存放变量
[root@k8s-master-1 test]# vim vars.yaml
name: wuzhaobo
name2: kangkexin
name3: xxx
2、编写playbook
[root@k8s-master-1 test]# cat test.yaml
---
- hosts: web
remote_user: root
vars_files: /etc/ansible/test/vars.yaml
tasks:
- name: test vars
debug:
msg:
- "{{ name }}"
- "{{ name2 }}"
[root@k8s-master-1 test]# ansible-playbook test.yaml
[WARNING]: Found variable using reserved name: name
PLAY [web] *****************************************************
TASK [Gathering Facts] **********************************************
ok: [192.168.134.138]
TASK [test vars] *********************************************
ok: [192.168.134.138] => {
"msg": [
"wuzhaobo",
"kangkexin"
]
}
PLAY RECAP ******************************************************
192.168.134.138 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
示例:
分别为每个主机设置变量,和设置组的公共的变量
1、先在hosts 文件中定义
[web] #组名
192.168.134.138 myid=1 state=master #定义变量 myid=1 state=master
[web:vars] #定义web这个组的 共同的端口为80
port=80
2、打印测试
---
- hosts: web
remote_user: root
tasks:
- name: test vars
debug:
msg:
- "{{ myid }}-{{ state }}-{{ port }}"
[root@k8s-master-1 test]# ansible-playbook test.yaml
ok: [192.168.134.138] => {
"msg": [
"1-master-80"
]
}
注意:在host_vars目录中定义的变量,只能给对应的主机使用,没有定义变量的主机不能使用此处的变量
在项目目录中创建,host_vars目录,然后在创建一个文件夹,文件的文件名称要与inventory清单中的主机名称要保持完全一致,如果是IP地址,则创建相同IP地址的文件即可:
1、先创建host_vars目录
[root@k8s-master-1 ansible]# mkdir host_vars
[root@k8s-master-1 ansible]# cd host_vars/
2、创建与主机清单文件中主机名称一致的文件
[root@k8s-master-1 hosr_vars]# vim 192.168.134.138
name: wuzhaobo
name2: kangkexin
[root@k8s-master-1 test]# vim test.yaml
- hosts: web
remote_user: root
tasks:
- name: test vars
debug:
msg:
- "{{ name }}"
- "{{ name2 }}"
[root@k8s-master-1 test]# ansible-playbook test.yaml
ok: [192.168.134.138] => {
"msg": [
"kangkexin",
"wuzhaobo"
]
}
在项目目录中创建group_vars目录,然后在创建一个文件,文件的文件名称要与清单文件中定义的组名保持完全一致。
示例:
1、在项目目录下创建一个group_vars文件夹
然后,在文件夹中创建与清单文件中相同组名的文件
[root@k8s-master-1 ansible]# mkdir group_vars
[root@k8s-master-1 group_vars]# vim web
name: wuzhaobo
name2: wuzhaobo2
记得把上一个测试的文件名称改下,因为host_vars的优先级比group_vars的优先级高
[root@k8s-master-1 test]# ansible-playbook test.yaml
ok: [192.168.134.138] => {
"msg": [
"wuzhaobo2",
"wuzhaobo"
]
}
在执行playbook时,可以通过命令行 --extra-vars 或者 -e 外置参数设定变量
示例:
---
- hosts: web
remote_user: root
tasks:
- name: test vars
debug:
msg:
- "{{ name2 }}"
- "{{ name }}"
[root@k8s-master-1 test]# ansible-playbook -e "name=wuzhaobo" -e "name2=xxxxxx" test.yaml
ok: [192.168.134.138] => {
"msg": [
"xxxxxx",
"wuzhaobo"
]
}
定义相同的变量,不同的值,测试变量的优先级
1、在playbook中定义vars变量
---
- hosts: web
remote_user: root
vars:
- test_var: "playbook var"
vars_files: ./vars.yml
- name: test vars
debug:
msg:
- "{{ test_var }}"
2、在playbook中定义vars_files变量
[root@k8s-master-1 test]# vim vars.yaml
test_var: vars_files
3、在host_vars中定义变量
[root@k8s-master-1 ansible]# cat host_vars/192.168.134.138
test_var: host_vars
4、在group_vars中定义变量:
[root@k8s-master-1 ansible]# cat group_vars/web
test_var: group_vars
5、在清单文件中定义主机变量和主机组
[root@k8s-master-1 ansible]# vim hosts
[web]
192.168.134.138 test_var=inventory_host_var
[web:vars]
test_var=inventory_group_var
6、通过命令行 使用 -e 参数传递变量
[root@k8s-master-1 test]# ansible-playbook -e "test_var=ansible-playbook_var"test.yaml
思路:运行playbook文件,当前显示的就是优先级最高的,然后把最高的变量删除,再依次测试
1、最优先的为命令行传递变量的方式
[root@k8s-master-1 test]# ansible-playbook -e "test_var=ansible-playbook_var" test.yaml
ok: [192.168.134.138] => {
"msg": [
"ansible-playbook_var"
]
}
2、然后是在playbook中定义的 vars_files 变量
[root@k8s-master-1 test]# ansible-playbook test.yaml
ok: [192.168.134.138] => {
"msg": [
"vars_files"
]
}
3、然后是在playbook中定义的 vars 变量
[root@k8s-master-1 test]# ansible-playbook test.yaml
ok: [192.168.134.138] => {
"msg": [
"playbook vars"
]
}
4、然后是在host_vars中定义的变量
[root@k8s-master-1 test]# ansible-playbook test.yaml
ok: [192.168.134.138] => {
"msg": [
"host_vars"
]
}
5、然后是在inventory中定义的主机变量
[root@k8s-master-1 test]# ansible-playbook test.yaml
ok: [192.168.134.138] => {
"msg": [
"inventory_host_var"
]
}
6、然后是在group_vars中定义的组变量
[root@k8s-master-1 test]# ansible-playbook test.yaml
ok: [192.168.134.138] => {
"msg": [
"group_vars"
]
}
7、然后是在inventory中定义的主机组变量
[root@k8s-master-1 test]# ansible-playbook test.yaml
ok: [192.168.134.138] => {
"msg": [
"inventory_group_var"
]
}
变量的优先级从高到低依次为:
Ansible模块运行时,都会返回一些result结果,类似于执行脚本,我们需要获取这些结果,判断上一步是否执行成功,默认情况下,ansible的result并不会显示出来,所以,我们可以把这些返回值存储到变量之中,通过调用对应的变量名,获取这些result。这种将模块的返回值写入到变量的方法叫做变量注册。
示例:
1、创建一个yaml
[root@k8s-master-1 test]# cat test.yaml
---
- hosts: web
remote_user: root
tasks:
- name: Register test
shell: df -h
当我们执行这个命令时,并不会给我们返回结果,只会返回changed是否改变,这时我们使用变量注册
[root@k8s-master-1 test]# ansible-playbook test.yaml
PLAY [web] ***************************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [192.168.134.138]
TASK [Register test] *******************************************************************************
changed: [192.168.134.138]
PLAY RECAP ***********************************************************************
192.168.134.138 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@k8s-master-1 test]#
[root@k8s-master-1 test]# vim test.yaml
---
- hosts: web
remote_user: root
tasks:
- name: Register test
shell: df -h
register: df
- name: return result
debug:
msg: "{{ df.stdout_lines }}"
[root@k8s-master-1 test]# ansible-playbook test.yaml 内容有很多,不在展示,我们可以让他输出想要的内容,在变量处添加
PLAY [web] *************************************************************************
TASK [Gathering Facts] *****************************************************************************
ok: [192.168.134.138]
TASK [Register test] ************************************************************************
changed: [192.168.134.138]
TASK [return result] **************************************************************************
ok: [192.168.134.138] => {
"msg": [
"文件系统 容量 已用 可用 已用% 挂载点",
"/dev/mapper/centos-root 36G 8.2G 27G 24% /",
"devtmpfs 1.9G 0 1.9G 0% /dev",
"tmpfs 1.9G 0 1.9G 0% /dev/shm",
"tmpfs 1.9G 9.5M 1.9G 1% /run",
"tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup",
"/dev/sda1 1014M 179M 836M 18% /boot",
"tmpfs 378M 12K 378M 1% /run/user/42",
"tmpfs 378M 0 378M 0% /run/user/0",
]
}
PLAY RECAP ************************************************************************************************
192.168.134.138 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
示例:
1、编辑变量文件
[root@k8s-master-1 test]# vim vars.yaml
information:
name: wuzhaobo
age: 30
gender: male
information2:
name: kangkexin
age: 28
gender: female
2、编辑剧本
[root@k8s-master-1 test]# vim test.yaml
---
- hosts: web
remote_user: root
vars_files: /etc/ansible/test/vars.yaml
tasks:
- name: debug information
debug:
msg: "{{ information.name }}"
- name: debug information
debug:
msg: "{{ information.age }}"
- name: debug information
debug:
msg: "{{ information.gender }}"
- name: debug information
debug:
msg: "{{ information2.name }}"
- name: debug information
debug:
msg: "{{ information2.age }}"
- name: debug information
debug:
msg: "{{ information2.gender }}"
[root@k8s-master-1 test]# ansible-playbook test.yaml
PLAY [web] ***********************************************************************************
TASK [Gathering Facts] *********************************************************************
ok: [192.168.134.138]
TASK [debug information] ***************************************************************
ok: [192.168.134.138] => {
"msg": "wuzhaobo"
}
TASK [debug information] ******************************************************
ok: [192.168.134.138] => {
"msg": "30"
}
TASK [debug information] *****************************************************************
ok: [192.168.134.138] => {
"msg": "male"
}
TASK [debug information] *****************************************************************
ok: [192.168.134.138] => {
"msg": "kangkexin"
}
TASK [debug information] ********************************************************************
ok: [192.168.134.138] => {
"msg": "28"
}
TASK [debug information] ************************************************************
ok: [192.168.134.138] => {
"msg": "female"
}
PLAY RECAP *********************************************************************
192.168.134.138 : ok=7 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansible facts是在客户端主机通过ansible自动采集发现的变量,facts包含每台特定主机的信息,如被控端的主机名、IP地址、系统版本、CPU数量、内存状态、磁盘状态。
facts的获取方法:
被控制端的主机是通过ansible的setup模块来获取信息,使用filter 参数可以过滤指定的Facts变量。
可以使用 命令行参数 查看下被控端变量信息
由于信息太多 我们直接把内容输出到文件中
[root@k8s-master-1 variables]# ansible web -m setup > ./a.txt
facts中的变量可以直接引用,不用获取。
示例:
使用变量的setup模块
1、ansible_distribution :获取到主机的发行版本
[root@k8s-master-1 variables]# ansible web -m setup -a 'filter=ansible_distribution'
192.168.134.138 | SUCCESS => {
"ansible_facts": {
"ansible_distribution": "CentOS",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
2、ansible_fqdn 获取主机名、或者 ansible_hostname
[root@k8s-master-1 variables]# ansible web -m setup -a 'filter=ansible_fqdn'
192.168.134.138 | SUCCESS => {
"ansible_facts": {
"ansible_fqdn": "k8s-node-2",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
3、ansible_distribution_version 获取系统版本
[root@k8s-master-1 variables]# ansible web -m setup -a 'filter=ansible_distribution_version'
192.168.134.138 | SUCCESS => {
"ansible_facts": {
"ansible_distribution_version": "7.4",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
4、ansible_default_ipv4:获取IP地址,网关、等网络信息
[root@k8s-master-1 variables]# ansible web -m setup -a 'filter=ansible_default_ipv4'
192.168.134.138 | SUCCESS => {
"ansible_facts": {
"ansible_default_ipv4": {
"address": "192.168.134.138",
"alias": "ens33",
"broadcast": "192.168.134.255",
"gateway": "192.168.134.2",
"interface": "ens33",
"macaddress": "00:0c:29:af:17:61",
"mtu": 1500,
"netmask": "255.255.255.0",
"network": "192.168.134.0",
"type": "ether"
},
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
5、ansible_date_time :获取时间相关信息
[root@k8s-master-1 variables]# ansible web -m setup -a 'filter=ansible_date_time'
192.168.134.138 | SUCCESS => {
"ansible_facts": {
"ansible_date_time": {
"date": "2023-07-24",
"day": "24",
"epoch": "1690184612",
"hour": "15",
"iso8601": "2023-07-24T07:43:32Z",
"iso8601_basic": "20230724T154332548470",
"iso8601_basic_short": "20230724T154332",
"iso8601_micro": "2023-07-24T07:43:32.548470Z",
"minute": "43",
"month": "07",
"second": "32",
"time": "15:43:32",
"tz": "CST",
"tz_offset": "+0800",
"weekday": "星期一",
"weekday_number": "1",
"weeknumber": "30",
"year": "2023"
},
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
6、查看系统版本信息
[root@k8s-master-1 variables]# ansible web -m setup -a 'filter=*version'
192.168.134.138 | SUCCESS => {
"ansible_facts": {
"ansible_bios_version": "6.00",
"ansible_distribution_major_version": "7", <==centos主版本
"ansible_distribution_version": "7.4", <==centos版本
"ansible_kernel_version": "#1 SMP Tue Aug 22 21:09:27 UTC 2017",
"ansible_product_version": "None",
"ansible_python_version": "2.7.5",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
[root@k8s-master-1 variables]# vim test.yaml
---
- hosts: web
remote_user: root
tasks:
- name: Output ansible variables facts
debug:
msg: hostname "{{ ansible_fqdn }}" and IP "{{ ansible_default_ipv4.address }}"
[root@k8s-master-1 variables]# ansible-playbook test.yaml
PLAY [web] **************************************************************************
TASK [Gathering Facts] ************************************************************
ok: [192.168.134.138]
TASK [Output ansible variables facts] *****************************************************
ok: [192.168.134.138] => {
"msg": "hostname \"k8s-node-2\" and IP \"192.168.134.138\""
}
PLAY RECAP ****************************************************************
192.168.134.138 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@k8s-master-1 variables]#
set_fact是一个模块,我们可以使用set_fact模块在tasks中定义变量;
示例:
---
- hosts: web
remote_user: root
tasks:
- name: test set_fact
set_fact:
test: "wuzhaobo"
- name: debug test
debug:
msg: "{{ test }}"
[root@k8s-master-1 variables]# ansible-playbook -C test2.yaml
TASK [debug test] **************************************************
ok: [192.168.134.138] => {
"msg": "wuzhaobo"
}
PLAY RECAP ***********************************************
192.168.134.138 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
也可以通过set_fact将一个变量的值赋值给另一个变量
---
- hosts: web
remote_user: root
vars:
testvar1: test1_string
tasks:
- shell: 'echo "123456"'
register: shellreturn
- set_fact:
testsf1: "{{ testvar1 }}"
testsf2: "{{ shellreturn.stdout }}"
- debug:
msg: "{{testsf1}} {{ testsf2 }}"
# var: shellreturn
[root@k8s-master-1 variables]# ansible-playbook test2.yaml
TASK [debug] ***************************************************************************************
ok: [192.168.134.138] => {
"msg": "test1_string 123456"
}
PLAY RECAP ************************************************************************************
192.168.134.138 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
以上我们用vars定义了一个变量testvar1,又使用register 将shell 模块的返回值注册到了变量shellreturn 中
之后 使用set_fact模块将testvar1变量的值赋予了变量testsf1,将shellreturn变量中的stdout信息赋值给了testsf2变量
通过set_fact模块创建的变量还有一个特殊性,通过set_fact创建的变量就像主机上的facts信息一样,可以在之后的play中被引用。
示例:
---
- hosts: web
remote_user: root
vars:
test1: tv1
tasks:
- name: test_fact
set_fact:
test2: tv2
- name: debug
debug:
msg: "{{ test1 }} ------ {{ test2 }}"
- hosts: web
remote_user: root
tasks:
- name: test play1 test1
debug:
msg: "{{ test2 }}"
- name: test play test2
debug:
msg: "{{ test1 }}"
[root@k8s-master-1 variables]# ansible-playbook -C test3.yaml
TASK [debug] *************************************************************************************
ok: [192.168.134.138] => {
"msg": "tv1 ------ tv2"
}
TASK [test play1 test1] *****************************************
ok: [192.168.134.138] => {
"msg": "tv2"
}
TASK [test play test2] **************************************************************************
报错
PLAY RECAP ****************************************************************************************
192.168.134.138 : ok=5 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
可以发现,这两个变量在第一个play中都可以正常的输出。但是在第二个play中,testvar2可以被正常输出了,testvar1却不能被正常输出,会出现未定义testvar1的错误,因为在第一个play中针对testB主机进行操作时,testvar1是通过vars关键字创建的,而testvar2是通过set_fact创建的,所以testvar2就好像testB的facts信息一样,可以在第二个play中引用到,而创建testvar1变量的方式则不能达到这种效果,虽然testvar2就像facts信息一样能被之后的play引用,但是在facts信息中并不能找到testvar2,只是”效果上”与facts信息相同罢了。