参考: http://ed.victavision.co.uk/blog/post/4-8-2012-chef-solo-encrypted-data-bags
鍵を作る
Chef リポジトリのルートに data_bag_key という名前で鍵をつくる。
openssl rand -base64 512 | tr -d '\r\n' > data_bag_key
Git リポジトリに入れてしまうとせっかく暗号化する意味が無いので .gitignore に追加しておく。
/data_bag_key
knife solo cook
を使う場合、Chef Solo を実行するサーバには rsync でコピーされるので Git リポジトリに入ってなくとも問題ない。
そのかわり、この鍵は紛失しないよう注意。
暗号化データバッグ (Encrypted data bag) 作成
Chef Server なら下記コマンドでいいんだけど、Chef Solo ではうまくいかない。
knife data bag create --secret-file data_bag_key [data-bag-name] [entry-name]
下記のように Chef のライブラリを使って作成する。
require 'chef/encrypted_data_bag_item'
require "fileutils"
data = {"id" => "foo", "password" => "foobar"}
secret = Chef::EncryptedDataBagItem.load_secret('data_bag_key')
encrypted_data = Chef::EncryptedDataBagItem.encrypt_data_bag_item(data, secret)
FileUtils.mkdir_p('data_bags/passwords')
File.open('data_bags/passwords/mysql.json', 'w') do |f|
f.print encrypted_data.to_json
end
私はこれをもとに JSON または YAML からデータバッグを作成するスクリプトを作成して使っている。
このへんをうまくやってくれそうなツールもある (試してない)。
https://github.com/thbishop/knife-solo_data_bag
使いかた
レシピ内で Chef::EncryptedDataBagItem.load
を使う。data_bags(データバッグ名)
で entry name の配列が取得できるのは通常の data bag と同じ。
Chef::EncryptedDataBagItem.load("passwords", "mysql")
追記 (2013-11-18)
いつからかは詳しく見てないけど、新しく Chef リポジトリ作って上記手順を実行したら knife solo cook
時に下記のようなエラーが出た。
Errno::ENOENT
-------------
No such file or directory - file not found '/home/chef/chef-solo/data_bag_key'
最新の knife-solo の README.rdoc をみると、.chef/knife.rb
で鍵のパスを示せとの記述が。みてみるとコメントアウトされてる。
# .chef/knife.rb
cookbook_path ["cookbooks", "site-cookbooks"]
node_path "nodes"
role_path "roles"
data_bag_path "data_bags"
#encrypted_data_bag_secret "data_bag_key"
knife[:berkshelf_path] = "cookbooks"
このコメントを外したら、data_bag_key がアップロードされ、問題なく動作するようになった。