ansible笔记(9)之传入变量到playbook

ansible笔记(9)之传入变量到playbook

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

本来打算自己写一波 ansible 系列的,后来发现一老哥写的太好了,「点击此处直达」,我这里也就边看边对该系列文章做下笔记,方便以后查阅,ansible 入门的话墙裂建议阅读前方链接博文~~~

交互式传入

在运行某些脚本时,有时候脚本会提示用户输入一些信息,脚本需要根据用户输入的信息决定下一步的动作,这种交互有时候是必须的,那么,在 playbook 中该怎样实现这种交互呢?我们可以这样做,提示用户输入信息,然后将用户输入的信息存入到指定的变量中,当我们需要使用这些输入的信息时,只要引用对应的变量即可。

我们来看一个小示例,如下:

---
- hosts: B
  vars_prompt:
    - name: "your_name"
      prompt: "What is your name"
    - name: "your_age"
      prompt: "How old are you"
  tasks:
   - name: output vars
     debug:
      msg: Your name is {{your_name}},You are {{your_age}} years old.

如上例所示,我们使用 vars_prompt 关键字创建了两个变量,这两个变量的名称分别为 your_nameyour_age,当运行上例 playbook 时,会出现 What is your name 的提示信息,然后用户输入的信息会存入到 your_name 变量中,之后,会出现 How old are you 的提示信息,用户输入的信息会存入到 your_age 变量中,上例中的 output vars 任务会输出一句话,这句话中包含了上述两个变量的值,我们来看一下上例的执行效果。

$ ansible-playbook test.yml 
What is your name: 
How old are you: 

PLAY [B] ************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************
ok: [B]

TASK [output vars] **************************************************************************************************************************
ok: [B] => {
    "msg": "Your name is zze,You are 22 years old."
}

PLAY RECAP **********************************************************************************************************************************
B                          : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

如上,运行 playbook 时会提示输入你的名字,输入你的年龄,你输入的内容并不会显示在屏幕上,在完成提示输入的内容后,在 output vars 任务的输出中可以看到用户输入的名字和年龄。

如你所见,当你使用这种方式提示用户时,默认情况下不会显示用户输入的信息,这种方式比较适合用户输入密码时的场景,如果你想要显示用户输入的信息,可以使用如下示例中的方法。

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: B
  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 模块的 password 参数虽然可以指定用户的密码,但是 password 参数对应的值必须是一个明文密码加密过后的字符串。

没错,我们需要对用户输入的密码字符串进行哈希,然后将哈希过后的字符串传入 user 模块的 password 参数中,ansible 已经为我们考虑到了这一点,我们可以使用 encrypt 关键字,对用户输入的字符串进行哈希,用户输入的信息被哈希以后会存入对应的变量中,示例如下:

---
- hosts: B
  vars_prompt:
    - name: "hash_string"
      prompt: "Enter something"
      private: no
      encrypt: "sha512_crypt"
  tasks:
   - name: Output the string after hash
     debug:
      msg: "{{hash_string}}"

encrypt 关键字表示对用户输入的信息进行加密,encrypt: "sha512_crypt" 表示使用 sha512 算法对用户输入的信息进行加密,加密后的字符串会存入到上例中的 hash_string 变量中。

ansible 需要依赖 passlib 库(一个用于加密的 python 库)完成加密操作,通过 pip 进行安装即可,如下:

$ pip install passlib

确认

使用 confirm 关键字实现类似确认密码的功能,我们在为用户设置密码时,通常需要输入两次完全相同的密码,才能够设置成功,通过 confirm 关键字就能实现类似的效果,示例 playbook 如下:

---
- hosts: B
  vars_prompt:
    - name: "user_name"
      prompt: "Enter user name"
      private: no
    - name: "user_password"
      prompt: "Enter user password"
      encrypt: "sha512_crypt"
      confirm: yes
  tasks:
   - name: create user
     user:
      name: "{{user_name}}"
      password: "{{user_password}}"

执行效果如下:

$ ansible-playbook test.yml 
Enter user name: zze
Enter user password: 
confirm Enter user password: 

PLAY [B] ************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************
ok: [B]

TASK [create user] **************************************************************************************************************************
changed: [B]

PLAY RECAP **********************************************************************************************************************************
B                          : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

命令行传入

我们能够在执行 playbook 时直接传入需要使用的变量,我们来看一小示例,如下:

---
- hosts: B
  tasks:
  - name: "Passing Variables On The Command Line"
    debug:
      msg: "{{pass_var}}"

上例中的 playbook 中,并没有定义 pass_var 变量,而是直接引用了 pass_var 变量,我们可以在调用上述 playbook 时直接从命令行传入 pass_var 变量,如下:

$ ansible-playbook test.yml -e "pass_var='cmdline pass var'"

也可以一次性传入多个变量,变量之间用空格隔开,如下:

$ ansible-playbook test.yml -e 'pass_var="test" pass_var1="test1"'

还可以通过 json 格式传入变量:

ansible-playbook test.yml -e '{"testvar":"test","testvar1":"test1"}'

上例中的 playbook 中并没有定义 pass_var 变量,如果在调用 playbook 时也没有传入 pass_var 变量,则会报错,其实,我们也可以先在 playbook 中定义好变量,然后在执行 playbook 时,再次传入相同名称的变量,最终还是以传入的变量值为准。

传入变量文件

命令行不仅能够传入变量,还能传入变量文件,变量文件中的变量都会一并被传入,变量文件可以是 json 格式的,也可以是 YAML 格式的,此处使用 YAML 格式的变量文件进行示例,示例文件内容如下:

$ cat testvar.yml
testvar: testvarinfile
countlist:
- one
- two
- three
- four

测试用的 playbook 如下:

---
- hosts: B
  tasks:
  - name: "Passing Variables On The Command Line"
    debug:
      msg: "{{testvar}} {{countlist[0]}}"

playbook 中引用了变量文件中定义的两个变量,我们只需要这样从命令行中将变量文件中的变量传入 playbook:

$ ansible-playbook test.yml -e "@testvar.yml"

如上述命令所示,使用 @ 符号加上变量文件的路径,即可在命令行中传入对应的变量文件,变量文件中的所有变量都可以在 playbook 中引用。

playbook 中引入

通过 vars_files 可以将文件中的变量引入 playbook,以便在 task 中使用,那么,我们先来看一个示例变量文件,示例变量文件 testfile 中的内容如下:

testvar1: aaa
testvar2: bbb

注:变量文件位于 ansible 控制节点中,与目标主机无关。

如上所示,其中一共定义了两个变量,如果我们使用 vars_files 导入这两个变量,可以编写如下 playbook:

---
- hosts: A
  remote_user: root
  gather_facts: no
  vars_files:
  - /testdir/ansible/testfile
  tasks:
  - debug:
      msg: "{{testvar1}}"

上例中,我们调用了变量文件中的 testvar1 变量,输出的值为 aaa,没有任何问题。

注意哦,使用 vars_files 引入的变量文件一经引入后不可修改,即便修改也是不会被载入生效的,如果需要动态载入变量文件,可参考「include_vars模块」。

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/ansible9.html

Buy me a cup of coffee ☕.