先说说怎样定义变量,变量名应该由字母、数字、下划线组成,变量名需要以字母开头,ansible内置的关键字不能作为变量名。
由于之前的几篇文章都是在通过剧本举例,所以我们先聊聊怎样在playbook中使用变量。
当我们需要使用testvar1的变量值时,则需要引用这个变量,使用"{{变量名}}"可以引用对应的变量
如果我们想要在某个play中定义变量,可以借助vars关键字,示例如下
---
- hosts: test3
name: testvar
vars:
var1: qwer.txt
tasks:
- name: touchtest
file:
path: /tmp/{{ var1 }}
state: touch
#也可以定义多个变量
vars:
testvar1: testfile
testvar2: testfile2
在定义变量时,还能够以类似"属性"的方式定义变量,示例如下
---
- hosts: test3
name: testvar
vars:
var1:
test1: qwer.txt
test2: qqqq.txt
tasks:
- name: touchtest
file:
path: /tmp/{{ var1.test2 }}
state: touch
#有两种引用语法
语法一
"{{nginx.conf80}}"
语法二
"{{nginx['conf8080']}}"
变量分离
除了能够在playbook中直接定义变量,我们还可以在某个文件中定义变量,然后再在playbook中引入对应的文件,引入文件后,playbook
即可使用文件中定义的变量,你可能会问,为什么要多此一举呢?这是因为在某些工作场景中这样做很有用,比如,你想要让别人阅读你的playbook,却不想让别人看到某些值,可以使用这种办法,因为别人在阅读playbook时,只能看到引入的变量名,但是看不到变量对应的值,这种将变量分离到某个文件中的做法叫做"变量文件分离","变量文件分离"除了能够隐藏某些值,还能够让你将不同类的信息放在不同的文件中,并且让这些信息与剧本主体分开。
先来看看"变量文件分离"的一些小例子
你可以选择你觉得较为舒适的语法定义变量,如下所示,直接在var.yml文件中定义变量即可
vartxt:
txt1: 1.txt
txt2: 2.txt
在nginx_vars.yml中定义完相关变量后,即可在playbook中引入文件中的变量,在playbook中引入包含变量的文件时,需要使用"vars_files"关键字,被引入的文件需要以"- "开头,以YAML中块序列的语法引入,示例如下
---
- hosts: test3
name: testvar
vars_files:
- /etc/ansible/roles/var.yaml
tasks:
- name: touchtest1
file:
path: /tmp/{{ vartxt.txt1 }}
state: touch
- name: touchtest2
file:
path: /tmp/{{ vartxt.txt2 }}
state: touch
"vars"关键字和"vars_files"关键字可以同时使用
Gathering Facts
当我们运行一个playbook时,默认都会运行一个名为"[Gathering Facts]"的任务,前文中已经大致的介绍过这个默认的任务,ansible通过"[Gathering Facts]"这个默认任务收集远程主机的相关信息(例如远程主机的IP地址,主机名,系统版本,硬件配置等信息),其实,这些被收集到的远程主机信息会保存在对应的变量中,当我们想要使用这些信息时,我们可以获取对应的变量,从而使用这些信息
如果想要查看"[Gathering Facts]"任务收集的信息内容,我们可以借助一个模块:setup模块
当执行playbook时,playbook其实就是自动调用了setup模块从而执行了"[Gathering Facts]"任务,所以我们可以通过手动执行setup模块查看"[Gathering Facts]"任务收集到的信息,示例如下
ansible test3 -m setup
#筛选一些信息
ansbile test3 -m setup -a 'filter=ansible_memory_mb'
#使用通配符
ansible test3 -m setup -a "filter=*mb*"
其实,setup模块返回的这些信息都存在了对应的变量中,我们可以通过引用变量从而使用对应的信息,但是别急,我们先来了解一下另外一个模块,这个模块叫"debug模块
见名知义,debug模块的作用就是帮助我们进行调试的,debug模块可以帮助我们把信息输出到ansible控制台上,以便我们能够定位问题。
那么我们先来看一个debug模块的playbook小示例,如下
---
- hosts: test3
name: debugtest
vars:
debug1: value of test variable
tasks:
- name: testdebug
debug:
var: debug1
注册变量
ansible的模块在运行之后,其实都会返回一些"返回值",只是默认情况下,这些"返回值"并不会显示而已,我们可以把这些返回值写入到某个变量中,这样我们就能够通过引用对应的变量从而获取到这些返回值了,这种将模块的返回值写入到变量中的方法被称为"注册变量",那么怎样将返回值注册到变量中呢?我们来看一个playbook示例
---
- hosts: test3
name: shelltest
tasks:
- name: mk a file
shell: "echo test > /tmp/op.txt"
register: testvar
- name: bugtext
debug:
var: testvar
提示用户输入信息并写入变量
在运行某些脚本时,有时候脚本会提示用户输入一些信息,脚本需要根据用户输入的信息决定下一步的动作,这种"交互"有时候是必须的,那么,在playbook中该怎样实现这种交互呢?我们可以这样做,提示用户输入信息,然后将用户输入的信息存入到指定的变量中,当我们需要使用这些"输入的信息"时,只要引用对应的变量即可。
我们来看一个小示例,如下
---
- hosts: test3
name: nametest
vars_prompt:
- name: "you_name"
prompt: "what is you name"
- name: "you_age"
prompt: "what is you age"
tasks:
- name: output vars
debug:
msg: you name is {{ you_name}},you age is {{ you_age }}
如你所见,当你使用这种方式提示用户时,默认情况下不会显示用户输入的信息,这种方式比较适合用户输入密码时的场景,如果你想要显示用户输入的信息,可以使用如下示例中的方法。
vars_prompt:
- name: "your_name"
prompt: "What is your name"
private: no
- name: "your_age"
prompt: "How old are you"
private: no
如上例所示,我们在定义" vars_prompt"中的变量时,使用private关键字,将变量的private属性设置为no即可, "private: no"表示变量值为非私有的,可见的,默认情况下 private值为yes,表示不可见。
我们还能为提示信息设置默认值,即如果用户不输入任何信息,则将默认值赋予变量,示例playbook如下。
---
- hosts: test70
remote_user: root
vars_prompt:
- name: "solution"
prompt: "Choose the solution you want \n
A: solutionA\n
B: solutionB\n
C: solutionC\n"
private: no
default: A
tasks:
- name: output vars
debug:
msg: The final solution is {{solution}}.
如上例所示,我们使用了default关键字设置了"solution"变量的默认值,如果用户没有输入任何值(直接回车),则将"solution"变量的值设置为A,如果用户输入了值,则"solution"变量值为用户输入的值。
之前的示例中,我们提到可以利用提示信息让用户设置密码,有了这项功能,我们就可以编写出一个playbook,这个playbook可以让用户手动输入用户名和密码,然后根据用户输入的信息去创建系统用户了,聪明如你一定想到了,创建系统用户可以使用user模块,前文已经总结过user模块,此处不再赘述,那么我们来尝试编写一个可交互创建系统用户的playbook吧,经过思考,我编写了如下playbook,你可以帮我看看如下playbook中存在什么问题
尝试编写一个可交互创建系统用户的playbook
---
- hosts: test3
name: usertest
vars_prompt:
- name: "hash_name"
prompt: "input u username"
private: no
- name: "pass_wd"
prompt: "input u passwd"
encrypt: "sha512_crypt"
tasks:
- name: output vars
user:
name: "{{ hash_name }}"
password: "{{ pass_wd }}"
#private 不显示输出 默认为yes,no=显示输出,encrypt: "sha512_crypt" 指定用户的哈希码
除了能够使用"encrypt"关键字对字符串进行哈希加密,还能够使用"confirm"关键字实现类似确认密码的功能,我们在为用户设置密码时,通常需要输入两次完全相同的密码,才能够设置成功,通过"confirm"关键字就能实现类似的效果,示例playbook如下
---
- hosts: test3
name: usertest
vars_prompt:
- name: "hash_name"
prompt: "input u username"
private: no
- name: "pass_wd"
prompt: "input u passwd"
encrypt: "sha512_crypt"
confirm: yes
tasks:
- name: output vars
user:
name: "{{ hash_name }}"
password: "{{ pass_wd }}"
#加入了confirm:yes 进行验证,需输2次密码