公司已经由 saltstack 全面转向了 ansible 。

用 ansible-playbook 执行各种任务的时候,需要登录主机,就必然涉及到主机 ssh 密码的输入。

最早我们是在 inventory 里做了定义:

[deqin:vars]
ansible_ssh_common_args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
host_key_checking=False
ansible_ssh_user="peadmin"
ansible_ssh_pass="Fuck2021!"

[deqin]
192.168.1.19

太直白了,所有看到这文件内容的人都会知道密码了。完全没有安全性,这样行不通啊!

好在 ansible-vault 提供了一种方法来解决:那就是生成一个密文放进去,然后解开它必须再输入一个密码。这样看到的人也不知道实际的密码到底是什么

具体的做法如下,首先生成 key –> 加密字符串的键值对:

ansible-vault encrypt_string 'Fuck2021!' --name 'ansible_ssh_pass'

输入密码,会得到下面一串字符

ansible_ssh_pass: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          37393235646234613332646366306233346330656666623862313339313861393239646261366237
          6663343263363161643634653266343466356634656539650a393834663938636165336431656433
          66333761643538623434363334316661653035313166333137373562363436613636366162353239
          3661623733323933350a373164626131646235616361356638653733646534616163393362373135
          6139

这个就是密文了,必须用输入的密码才能解开。

注意:这里的键值 name 不可改变,如果你想把字符串拷贝下来,改掉 ansible_ssh_pass 的名字,改成别的,想改名引用,是不行的。

这一大长串密文有以下两种用法:

一、ini格式的inventory引用

最原始的 inventory.ini 内容如下:

[deqin:vars]
ansible_ssh_common_args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
host_key_checking=False
ansible_ssh_user="peadmin"

[deqin]
192.168.1.19

我们定义 playbook 文件 shenji.yml:

- hosts: deqin
  become: yes
  vars_files:
    - pass.yml
  vars:
    ansible_ssh_pass: '{{ ansible_ssh_pass }}'

  tasks:
    - name: mkdirs
      file: path="{{ item }}" state=directory
      with_items:
        - "OS.05"
        - "OS.06"

把密文放进 pass.yml 文件

cat << EOF >> pass.yml
ansible_ssh_pass: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          37393235646234613332646366306233346330656666623862313339313861393239646261366237
          6663343263363161643634653266343466356634656539650a393834663938636165336431656433
          66333761643538623434363334316661653035313166333137373562363436613636366162353239
          3661623733323933350a373164626131646235616361356638653733646534616163393362373135
          6139
EOF

运行 playbook:

ansible-playbook --ask-vault-pass -i inventory.ini shenji.yml -vvv

为什么这样呢?因为 ansible-vault 加密过的字符串是 yaml 格式的,在 ini 里无法直接引用。

所以在 playbook 的 yaml 文件中引入它,然后再跟从 inventory.ini 中获取的变量合作一起。

二、yaml格式的inventory引用

上面我们看到了必须间接引用才可以,为了避免掉 pass.yml 文件,那么干脆把 inventroy 用 yaml 格式来写,那不就可以了么

如下即可:

cat << EOF >> inventory.yml
---
all:
  hosts:
    deqin:
      ansible_host: 192.168.1.19
    vars:
      host_key_checking: "False"
      ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
      ansible_ssh_pass: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          37393235646234613332646366306233346330656666623862313339313861393239646261366237
          6663343263363161643634653266343466356634656539650a393834663938636165336431656433
          66333761643538623434363334316661653035313166333137373562363436613636366162353239
          3661623733323933350a373164626131646235616361356638653733646534616163393362373135
          6139
EOF

然后运行就可以了:

ansible-playbook --ask-vault-pass -i inventory.yml shenji.yml -vvv