公司已经由 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