【Ansible】让你掌握关键要点的贴心提示 第二篇
使用Ansible时,我个人遇到了一些问题并进行了研究,现在我想将它们作为小贴士总结起来。当积累到一定数量的小贴士后,我会发布第三篇!
本次介绍的小贴士
-
- OS用户的密码无需事先进行哈希处理!
-
- 将role内的变量设为仅在role内使用的私有变量
-
- 在Ansible模块中使用*(星号)
-
- 想要安装RPM包
-
- 想要在使用become时自动输入sudo密码
-
- 想要在使用ansible-vault时通过环境变量传递密码
-
- 将需要重复写入的参数进行整合!
- 当变量中包含变量时,在Ansible中使用eval进行处理
OS用户的密码无需提前进行哈希化!
使用password_hash
以前提到过的技巧是在事前进行加密的步骤,但是仔细查看参考资料后发现有一种可以进行加密的写法。
我們可以滿足以下需求。
-
- sha256
- sha512
使用方法
- name: ユーザー作成
user:
name: test
#SHA256の時はこちら
password: "{{ 'password' |password_hash('sha256', 'mysecretsalt') }}"
#SHA512の時はこちら
password: "{{ 'password' |password_hash('sha512', 'mysecretsalt') }}"
home: /home/test
然而需要注意的是,如果按照以下方式将变量列成列表并进行循环,执行结果中的密码将会以明文形式传递。
vars:
test:
- name: test1
password: password
home: /home/test1
- name: test2
password: password
home: /home/test2
tasks:
- user:
name: "{{ item.name }}"
password: "{{ item.password |password_hash('sha256', 'mysecretsalt') }}"
home: "{{ item.home }}"
with_items:
- "{{ test }}"
密码以明文形式可见!
PLAY ***************************************************************************
TASK [user] ********************************************************************
changed: [rhel6_d] => (item={u'home': u'/home/test1', u'password': u'password', u'name': u'test1'})
changed: [rhel6_d] => (item={u'home': u'/home/test2', u'password': u'password', u'name': u'test2'})
因此,如果要将其列入列表,我们需要添加no_log:True,以便不输出。
vars:
test:
- name: test1
password: password
home: /home/test1
- name: test2
password: password
home: /home/test2
tasks:
- user:
name: "{{ item.name }}"
password: "{{ item.password |password_hash('sha256', 'mysecretsalt') }}"
home: "{{ item.home }}"
with_items:
- "{{ test }}"
no_log: True
这样会发生。
TASK [user] ********************************************************************
changed: [rhel6_d] => (item=(censored due to no_log))
changed: [rhel6_d] => (item=(censored due to no_log))
将角色内的变量转换为仅在角色内部使用的私有变量。
使用private_role_vars = yes
被role调用或定义的变量,即使在处理转移到另一个role中,也会被继承。这也是Ansible变量命名规则中要求在开头加上role名称的原因。
然而,如果无法这样做,就需要在角色中封闭变量,在ansible.cfg文件中添加以下内容。
private_role_vars = yes
在Ansible模块中使用*(星号)
使用 with_fileglob
- copy:
src: {{ item }}
dest: /path
with_fileglob:
- "/etcsysconfig/network-scripts/ifcfg-*"
顺便一提,在使用 fetch 模块中,虽然使用 with_fileglob 会显示输出结果正常,但有可能无法获取文件的情况。这是因为 with_fileglob 的解析是在本地主机上进行的,而 fetch 则在目标机器(受配置管理的服务器)上执行。
因此,如果要指定特定情况,可以使用shell模块进行find搜索并将注册的值放入with_items。
如果有其他更好的方法,请告诉我。
我想要安装RPM软件包。
使用yum模块
通过使用yum模块,在name属性中可以完整地指定路径,从而可以通过指定本地上的RPM文件进行安装。
yum:
name: xxxxx.rpm
state: present
使用参考:Ansible 可处理 RPM 包。
在使用become时,希望能自动输入sudo密码。
使用ansible_become_pass
自动输入无效!对于那些已经将sudo密码设置为NOPASSWD的人来说,这是个好消息。
在过去,我们有sudo_password之类的设置,但从推荐使用become之后,在ansible.cfg中无法再指定它了。那么该怎么办呢?答案是,现在有ansible_become_pass可供使用。
这个东西有两种用法.
-
- インベントリファイルで指定
- 変数ファイルで指定(変数として作成する)
[target]
hostname1 ansible_become_pass=xxxx
ansible_become_pass: xxxx
发展案例(通过环境变量传递)
ansible_become_pass: "{{ lookup('env','SUDO_PASSWD') }}"
希望在使用ansible-vault时可以通过环境变量传递密码。
当使用类似Jenkins的CI工具或者不想保存Vault密码文件时,可以使用的技巧。
— 我们将使用“vault-password-file”来解锁。
–vault-password-file可以接受不仅仅是文件作为参数,还可以接受具有执行权限的脚本,并将其标准输出用作密码。
即通过解析脚本中的环境变量并将其输出到标准输出,就不再需要将vault密码保存在本地了。这是一种类似于动态清单的用法。
#!/bin/bash
echo $VAULT_PASS
export VAULT_PASS=xxx
ansible-playbook site.yml --vault-password-file vault.sh
记录
如果你希望使用过程替换的方式來完成,甚至连创建shell都不需要!那么在Mac系统中,只需要利用过程替换,就可以实现以下功能。(在CentOS系统上无法实现)
ansible-playbook site.yml --vault-password-file <(echo $VAULT_PASS)
在Centos系的Linux中,对于进程替换时的临时文件,使用pipe:[xxxxxxxx]进行管理。
[server ]# ll <(date)
lr-x------ 1 root root 64 4月 8 11:01 /dev/fd/63 -> pipe:[24349835]
在执行ansible-vault命令时,以下文件中包含了os.path.realpath(引用实际文件路径)并且写有pipe:[xxxxxxxx],这导致了它无法正常工作。(当删除realpath时,就可以正常运行了)
this_path = os.path.realpath(to_bytes(os.path.expanduser(vault_password_file), errors='strict'))
if not os.path.exists(to_bytes(this_path, errors='strict')):
raise AnsibleFileNotFound("The vault password file %s was not found" % this_path)
在Mac上,由于Centos的进程管理机制(proc周边)有所不同,使用进程替换的方式似乎可以解决这个问题。
整理需要多次写的参数!
使用YAML的合并语法。
参考:你可以在ansible-playbook中使用YAML的合并语法!
- file:
path: /tmp/a
<< : &DEF
owner: ansible
group: ansible
mode: 0755
state: directory
- file:
path: /tmp/b
<< : *DEF
我将owner/group/mode/state的设置放入DEF变量,并且将其重复使用。这将使得之后的权限设置更加简洁。(变量名称可以是任意的<< : &和<< : *非常重要)
这个看起来好像可以用在很多方面!
如果在Ansible中的eval变量中有变量的情况
{{ somvar_{{other_var}} }}
要做这样的事情时,可以按以下步骤进行。
{{['somevar_' + other_var] }}
host_varsを使ってる時はこっちらしい
{{ hostvars[inventory_hostname]['somevar_' + other_var] }}