使用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

在评论中也有补充说明,处理程序的步骤如下:

    1. 从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 的变量读取顺序,可能会比较复杂。

bannerAds