1.ansible Variables
变量提供了便捷的方式来管理ansible项目中的动态值
变量名:仅能由字母、数字、下划线组成,且只能以字母开头
1.变量定义的方式
(1)通过ansible-playbook命令行传递变量参数定义
(2)在play文件中定义
通过vars定义变量
通过vars_file定义变量
(3)通过inventory在主机或单个主机中设置变量
通过host_vars对主机进行定义
通过group_vars对主机进行定义
通过inventory-hosts主机清单文件中定义变量
2.变量常用关键字
1、vars_prompt 关键字 :#创建变量,并提示输入信息 vars_prompt.prompt:表示 提示信息
2、encrypt 关键字 :#表示对用户输入的信息进行哈希
#示例:encrypt: “sha512_crypt”表示使用sha512算法对用户输入的信息进行哈希
3、default 关键字 :#设置变量的默认值
示例:如下4.b
4、private 关键字:#表示变量值为非私有的,可见的,默认情况下 private值为yes,表示不可见。
5、confirm 关键字:#实现类似确认密码的功能,
# 我们在为用户设置密码时,通常需要输入两次完全相同的密码,才能够设置成功,通过“confirm”关键字就能实现类似的效果
3.引用变量
当我们引用变量时,有两种语法
1、语法1
"{{httpd.conf80}}"
2、语法2
"{{nginx['conf8080']}}"
4.在playbook中定义变量
1.使用vars方式定义变量
在playbook的文件中开通通过vars关键字进行定义变量,格式如下:
vars:
- var1: value1
- var2: value2
#使用变量如下
---
- hosts: webservers
remote_user: root
vars:
- var1: test1
- var2: test2
- name: test vars
debug:
msg:
- "{{ var1 }}"
- "{{ var2 }}"
2.示例:提示用户输入信息并写入变量
使用vars_prompt关键字
---
- hosts: webservers
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.
我们也可以为提示信息设置默认值,即用户不输入任何信息,将默认值赋予变量,示例如下
---
- hosts: webservers
remote_user: root
vars_prompt:
- name: "your_name"
prompt: "What is your name"
- name: "your_age"
prompt: "How old are you\n"
A: 17\n
B: 18\n
C: 19\n
private: no
tasks:
- name: output vars
debug:
msg: Your name is {{ your_name }},You are {{ your_age }} years old.
编写playbook,使用户输入用户名,密码,根据用户输入的信息创建系统账户
---
- hosts: webservers
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 }}.
3.使用vars_file方式定义变量
在playbook中使用vars_file指定文件作为变量文件,好处就是其他的playbook也可以调用
示例:
1、编写一个var_files文件,专门用来存放变量
[root@ansible-server ~]# vi vars.yaml
name: lingqianhui
name2: lingyizhe
name3: xxx
2、编写playbook
---
- hosts: webservers
remote_user: root
vars_files: /etc/ansible/test/vars.yaml
tasks:
- name: test vars
debug:
msg:
- "{{ name }}"
- "{{ name2 }}"
5.针对每个主机定义变量
1.Inventory文件中定义变量
示例:
分别为每个主机设置变量,和设置组的公共的变量
1、先在hosts 文件中定义
[webservers] #组名
192.168.134.138 myid=1 state=master #定义变量 myid=1 state=master
[webservers:vars] #定义webservers这个组的 共同的端口为80
port=80
2、打印测试
---
- hosts: webservers
remote_user: root
tasks:
- name: test vars
debug:
msg:
- "{{ myid }}-{{ state }}-{{ port }}"
2.使用host_vars定义变量
注意:在host_vars目录中定义的变量,只能给对应的主机使用,没有定义变量的主机不能使用此处的变量
在项目目录中创建,host_vars目录,然后在创建一个文件夹,文件的文件名称要与inventory清单中的主机名称要保持完全一致,如果是IP地址,则创建相同IP地址的文件即可:
1.先创建host_vars目录
[root@ansible-server ~]# mkdir host_vars
[root@ansible-server ~]# cd host_vars/
2.创建与主机清单文件中主机名称一致的文件
[root@ansible-server host_vars]# vi 192.168.100.20
name: lingqianhui
name2: lingyizhe
[root@ansible-server ~]# vi test.yaml
- hosts: webservers
remote_user: root
tasks:
- name: test vars
debug:
msg:
- "{{ name }}"
- "{{ name2 }}"
3.使用group_vars定义变量
在项目目录中创建group_vars目录,然后再创建一个文件,文件的文件名称要与清单文件中定义的组名保持完全一致。
示例:
[root@ansible-server ~]# mkdir group_vars
[root@ansible-server ~]# cd group_vars
[root@ansible-server group_vars]# vi webservers
name: lingqianhui
name2: lingqianhui2
3.使用group_vars定义变量
在项目目录中创建group_vars目录
6.通过执行playbook传递变量
在执行playbook时,可以通过命令行 --extra-vars 或者 -e 外置参数设定变量
示例:
---
- hosts: webservers
remote_user: root
tasks:
- name: test vars
debug:
msg:
- "{{ name2 }}"
- "{{ name }}"
7.变量定义的优先级
(1)命令行传递的变量;
(2)playbook中定义的vars_files;
(3)playbook中定义的vars;
(4)在host_vars中定义的变量;
(5)在inventory中定义的主机变量;
(6)在group_vars中定义的组变量:group_vars/group_name;
(7)在group_vars中定义的all文件中的变量:group_vars/all;
(8)在inventory中定义的主机组变量
2.ansible的变量注册Register
Ansible模块运行时,都会返回一些result结果,类似于执行脚本,我们需要获取这些结果,判断上一步是否执行成功,默认情况下,ansible的result并不会显示出来,所以,我们可以把这些返回值存储到变量之中,通过调用对应的变量名,获取这些result。这种将模块的返回值写入到变量的方法叫做变量注册。
示例:
---
- hosts: webservers
remote_user: root
tasks:
- name: Register test
shell: df -h
当执行这个命令时,并不会返回结果,只会返回changed时候改变,这时使用变量注册
---
- hosts: webservers
remote_user: root
tasks:
- name: Register test
shell: df -h
register: df
- name: return result
debug:
msg: "{{ df.stdout_lines }}"
3.层级定义变量
示例:
1.编辑变量文件
[root@ansible-server test]# vi vars.yaml
information:
name: lingqianhui
age: 10
gender: female
information2:
name: lingyizhe
age: 11
gender: male
2.编辑剧本
[root@ansible-server test]# vi test.yaml
---
- hosts: webservers
remote_user: root
vars_files: 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 }}"
4.facts内置变量
ansible facts是在客户端主机通过ansible自动采集发现的变量,facts包含每台特定主机的信息,如被控端的主机名、IP地址、系统版本、CPU数量、内存状态、磁盘状态。
facts的获取方法:
被控制端的主机是通过ansible的setup模块来获取信息,使用filter 参数可以过滤指定的Facts变量。
可以使用 命令行参数 查看下被控端变量信息
由于信息太多 我们直接把内容输出到文件中
ansible web -m setup > ./a.txt
facts中的变量可以直接引用,不用获取
1.常用变量信息
使用变量的setup模块
ansible_distribution:获取到主机的发行版本
ansible webservers -m setup -a 'filter=ansible_distribution'
ansible_fqdn 获取主机名、或者 ansible_hostname
ansible webservers -m setup -a 'filter=ansible_fqdn'
ansible_distribution_version 获取系统版本
ansible webservers -m setup -a 'filter=ansible_distribution_version'
ansible_default_ipv4:获取IP地址,网关、等网络信息
ansible webservers -m setup -a 'filter=ansible_default_ipv4'
ansible_date_time :获取时间相关信息
ansible webservers -m setup -a 'filter=ansible_date_time'
查看系统版本信息
ansible webservers -m setup -a 'filter=*version'
2.在playbook中直接调用facts变量
[root@ansible-server variables]# vi test.yaml
---
- hosts: webservers
remote_user: root
tasks:
- name: Output ansible variables facts
debug:
msg: hostname "{{ ansible_fqdn }}" and IP "{{ ansible_default_ipv4.address }}"
3.通过set_fact模块定义变量
set_fact是一个模块,我们可以使用set_fact模块在tasks中定义变量;
---
- hosts: webservers
remote_user: root
tasks:
- name: test set_fact
set_fact:
test: "lingqianhui"
- name: debug test
debug:
msg: "{{ test }}"
也可以通过set_fact将一个变量赋值给另一个变量
---
- hosts: webservers
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
用vars定义了一个变量testvar1,又使用register 将shell 模块的返回值注册到了变量shellreturn 中,之后 使用set_fact模块将testvar1变量的值赋予了变量testsf1,将shellreturn变量中的stdout信息赋值给了testsf2变量
通过set_fact模块创建的变量还有一个特殊性,通过set_fact创建的变量就像主机上的facts信息一样,可以在之后的play中被引用。
示例:
---
- hosts: webservers
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 }}"
可以发现,这两个变量在第一个play中都可以正常的输出。但是在第二个play中,testvar2可以被正常输出了,testvar1却不能被正常输出,会出现未定义testvar1的错误,因为在第一个play中针对testB主机进行操作时,testvar1是通过vars关键字创建的,而testvar2是通过set_fact创建的,所以testvar2就好像testB的facts信息一样,可以在第二个play中引用到,而创建testvar1变量的方式则不能达到这种效果,虽然testvar2就像facts信息一样能被之后的play引用,但是在facts信息中并不能找到testvar2,只是”效果上”与facts信息相同