ぼっちエンジニアのリーンなブログ

リーン・スタートアップ、プログラミングなどについてまとめます

秘密情報をchefで扱う

概要

Chefで秘密情報を扱うときは、data_bagというものを利用する。
秘密情報は、BAGとITEMで表され、Projectは複数のBAGを持ち、BAGは複数のITEMを持つ
ITEMはjsonで表現され、Chefのコードからアクセス可能である

 セットアップ

knife-solo_data_bagのインストール

gem install knife-solo_data_bag --no-ri --no-rdoc # knife-soloのdata bag用プラグイン

暗号化に利用する鍵を用意する

cd project-directory
openssl rand -base64 512 > .chef/encrypted_data_bag_secret

.chef/knife.rbを変更

cookbook_path    ["cookbooks", "site-cookbooks"]
node_path        "nodes"
role_path        "roles"
environment_path "environments"
data_bag_path    "data_bags"
encrypted_data_bag_secret ".chef/encrypted_data_bag_secret" # ← ここを変更

knife[:berkshelf_path] = "cookbooks"
Chef::Config[:ssl_verify_mode] = :verify_peer if defined? ::Chef

data bag用のエディターを設定する

# .bash_profileに書くと良いかも。vimを色々いじっているとエラーが発生するのでemacsとかにすると良いかも
export EDITOR=vi # or emacs, notepad

暗号化データを作成する

BAGとITEMの作成

# BAGだけでは作成できないので必ずITEMも必要
knife solo data bag create <BAG> <ITEM>

ITEMの編集

knife solo data bag edit <BAG> <ITEM>

作成されるもの 上記の編集コマンドだと復号化された状態が見れるが、作成されるファイルは暗号化されている。
例:data_bags/certificates/ssl.json

{
  "id": "ssl",
  "test": {
    "encrypted_data": "Ht6iZta7RqJN7Xc+tF7p1vIp/n0p2Jz33VRB35vbwqo=\n",
    "iv": "dJMOFLGm3NtW1Z0YYMTbgw==\n",
    "version": 1,
    "cipher": "aes-256-cbc"
  }
}

ファイルを扱う

証明書などをアップロードしたいときとかあると思います
ファイルだと持てないのでJSONで扱う必要があります
なので下記コマンドでファイルを文字列にする

cat <filename> | sed s/$/\\\\n/ | tr -d '\n'
-OR-
/usr/bin/env ruby -e 'p ARGF.read' <filename>
-OR-
perl -pe 's!(\x0d)?\x0a!\\n!g' <filename>

復元するときは、下記のようにやる

data_bag = Chef::EncryptedDataBagItem.load('certificates','ssl')

execute "create_key" do
  command "echo \"#{data_bag['file_name']}\" > /path/to/file ; chmod 600 /path/to/file"
  user "root"
  group "root"
  action :run
end

Utils

バッグリストの取得

knife solo data bag list

バッグの中のアイテムリストの取得

knife solo data bag show <BAG NAME>