使用Serverspec来使用ansible-vault的信息
好久不见了。自4月份开始工作以来,已经有差不多8个月没有发表过帖子了。
现在我在田町玩弄Ruby、Ansible、Jenkins等技术,同时搭建云环境。
在我还是学生的时候,我为实验室编写了hico-horiuchi/ansible-playbooks。
现在看来,它并没有按角色进行整理,也没有使用标签或变量等,可以说相当粗糙呢…。
因此,在5月的培训期间,我闲着无事,所以兼顾了Ansible 2.0的支持,尝试着编写了一份用于自己服务器的Playbook。
内容是为了搭建“ConoHa + Dokku”私有PaaS环境。
- hico-horiuchi/hiconyan-com-ansible
本文将介绍如何巧妙地利用ansible-vault加密的信息,在Serverspec中使用。通过这样做,我们可以确认”配置文件中是否包含令牌”和”是否可以使用密码登录”等情况。
Ansible Spec的介绍。
为了使用Ansible + Serverspec对测试进行,我们使用了volanja/ansible_spec。
有关ansible_spec的详细信息,请查看下面由开发人员编写的文章。
- Ansibleの設定ファイルを使ってServerspecを実行するテンプレート作成用Gem(ansible_spec)を作りました。
这次我们要修改由ansible_spec生成的spec/spec_helper.rb文件。
使用Ruby来读取ansible-vault的信息。
ansible-vault是用于加密Ansible的变量的工具。
它可以加密和解密包含密码和令牌的YAML文件。
本次我们使用tpickett66/ansible-vault-rb库来通过Ruby读取ansible-vault加密文件。
使用方法很简单,只需传递加密文件的路径和密码,就可以解密文件。
但需要注意的是,Ansible::Vault.read的返回值是字符串,因此需要使用YAML.load将其转化为哈希。
require 'ansible/vault'
require 'yaml'
contents = Ansible::Vault.read(path: '/path/to/file', password: 'foobar')
vars = YAML.load(contents)
在Serverspec中使用ansible-vault的信息。
前面的话说得有点长,但接下来才是正题。
为了在Serverspec中使用ansible-vault-rb,需要在spec/spec_helper.rb文件的末尾添加以下内容。
整个源代码请参考hico-horiuchi/hiconyan-com-ansible/spec/spec_helper.rb。
vars = AnsibleSpec.get_variables(host, group_idx, hosts)
property = AnsibleSpec.get_properties[group_idx]
ansible_cfg = File.expand_path('../ansible.cfg', File.dirname(__FILE__))
vault_password_file = ''
vault_password = ''
# ansible.cfgからvault_password_fileのパスを抽出
File.open(ansible_cfg, 'r') do |f|
vault_password_file = f.read.match(/^vault_password_file = (.+)$/)[1]
end
# vault_password_fileからパスワードを読込
File.open(File.expand_path(vault_password_file), 'r') do |f|
vault_password = f.read.chomp
end
# 必要なroles/*/vars/secret.ymlをハッシュとして読込
property['roles'].each do |role|
secret = "roles/#{role}/vars/secret.yml"
if File.exist?(secret)
vars.merge! YAML.load(Ansible::Vault.read(path: secret, password: vault_password))
end
end
set_property vars
在评论中也有补充说明,处理程序的步骤如下:
-
- 从ansible.cfg中提取vault_password_file的路径。
为了在ansible-playbook时无需输入密码,将密码写入并保存在配置文件中。
在我的情况下,将密码写入到~/.vault_password中。
请参阅“Configuration file — Ansible Documentation”以获取更多详细信息。
从vault_password_file中读取密码。
通过简单的Ruby文件操作,读取vault_password_file的内容。
通过File.expand_path获取绝对路径,以展开~等符号。
将必要的roles/*/vars/secret.yml作为哈希表进行读取。
这次我将加密文件(secret.yml)按照角色(role)分开存储在vars目录中。
通过property[‘roles’]可以知道目标主机的角色,所以如果secret.yml存在,则进行读取。
此外,使用 set_property vars,可以在Serverspec中使用property哈希表。下面是实际使用Serverspec的两个示例,请参考。
-
- hico-horiuchi/hiconyan-com-ansible/roles/mackerel/spec/config_spec.rb
- hico-horiuchi/hiconyan-com-ansible/roles/redis/spec/config_spec.rb
最后
其实,这种方法在八月中旬就已经确立了,但由于工作繁忙,文章发布的时间晚了一些…。
成为社会人后,不仅是爱好,技术上能够有闲暇娱乐的时间也变得很少,相当不容易。
我们这次将 secret.yml 配置在 roles/*/vars 中。
另一种方法是将其配置在 group_vars/*/secret.yml 中,以便按组进行分割。
要同时实现这两种方法,考虑到 Ansible 的变量读取顺序,可能会比较复杂。