たとえばtwitterのconsumer_keyなど,外部サービスを利用するためのkeyとかtokenとかpassword等々
こういう第三者には秘密にしておきたい,githubの公開リポジトリに置いておきたくない類のものを管理する方法
ここでは,Chef(knife-solo)のData Bagという仕組みを試してみることにします.
Data Bagとは
入門Chef Soloには,グローバルなドメインモデル的なデータを扱うためにつかうといいもの,といったようなことが書いてあります.
複数台のノードを扱う場合に,それらのノード全てに複数のユーザを追加したいといったケースでは,それらのユーザのデータがData Bagが扱う対象とすべきデータ,だそうです.
あまり深く考えずに,とりあえず手を動かしてみることにします.
knife-solo インストール
一応インストールから.
knife-soloの他に,knife-solo_data_bagが要ります.
$ gem install knife-solo
$ gem install knife-solo_data_bag
$ knife solo init chef-repo
$ cd chef-repo
鍵の作成
鍵を作って,レシピのカレントディレクトリ下に配置します.
(.gitignoreしておくことをオススメします)
$ openssl rand -base64 512 > data_bag_key
knife.rbの編集
.chef/knife.rbのencrypted_data_bag_secretでdata_bag_keyのパスを指定します.
今回は,L6でコメントアウトしてあるものをそのまま使えばOKです.
cookbook_path ["cookbooks", "site-cookbooks"]
node_path "nodes"
role_path "roles"
environment_path "environments"
data_bag_path "data_bags"
encrypted_data_bag_secret "data_bag_key"
knife[:berkshelf_path] = "cookbooks"
data_bagの作成
ここでようやくデータの設定作業です.
hogeという外部サービスが発行したapi_keyとapi_secretを扱いたいという設定で作ってみます.
$ export EDITOR=vim
$ knife solo data bag create app hoge
data_bags下にapp/hoge.jsonというファイルができます.
環境変数EDITORに設定したエディタで立ち上がるので編集します.
{
"id": "hoge",
"api_key": "xxxxxx",
"api_secret": "zzzzzz"
}
再度編集したくなった場合
$ knife solo data bag edit app hoge
knife solo data bag editを使わずに,直接hoge.jsonを覗いてみると,api_key & api_secretが暗号化されているのがわかるかと思います.
暗号&複号には先ほど作った鍵が使われています.
{
"id": "hoge",
"api_key": {
"encrypted_data": "WAxqaxShdfnww36d4sLFW+35VIbxi4zHNfs56VTrse0=\n",
"iv": "imayJwTu00tSccCWfDVPUQ==\n",
"version": 1,
"cipher": "aes-256-cbc"
},
"api_secret": {
"encrypted_data": "yoYzF9FHmh/jHXYqA80ZVeYvWE92EGPvI3MtAhetJ5Y=\n",
"iv": "dfnlC0Ub5tky5tuvSrzjgQ==\n",
"version": 1,
"cipher": "aes-256-cbc"
}
}
レシピの記述
data_bagで設定した値は,レシピ内でChef::EncryptedDataBagItemによって読むことができます.
ここまで来たら,あとは煮るなり焼くなりお好きなようにって感じですが,今回は環境変数に設定してみることにします.
レシピの作成
$ knife cookbook create sample -o site-cookbooks
templateを使って.profileを配置します.
variablesを使うことで,テンプレートに値を指定できます.
(user名などは適当に読み替えてください)
app = Chef::EncryptedDataBagItem.load("app", 'hoge')
template "/home/vagrant/.profile" do
source "profile.erb"
user "vagrant"
mode 0644
variables({
:api_key => app["api_key"],
:api_secret => app["api_secret"],
})
end
テンプレートの中身
# <関係ない所は省略>
export API_KEY=<%= @api_key %>
export API_SECRET=<%= @api_secret %>
アプリケーション
アプリケーション側では,先ほど設定した環境変数から値を読み込むようにします.
おわり
data_bagで,api_keyを暗号化した状態で管理することができるようになった.
data_bagの勉強にはなったが,ただ単にapi_keyを安全に管理したいだけならば,少々大げさな気がする,やること多いし.多分普通にprivateリポジトリとか使った方がいい.
既にChefを使ってるのであれば使えると思う.
参考資料
アルパカchef日記3日目 data bagについて / またはユーザ管理クックブックなど - アルパカDiary
http://d.hatena.ne.jp/toritori0318/20130516/1368722444
chefに関してはこの本が詳しいです.
今回,Chefの説明多々すっ飛ばしてますが,その辺はこれを読んでおけば多分補間できるはず
入門Chef Solo - Infrastructure as Code
http://www.amazon.co.jp/dp/B00BSPH158