[chef] chef solo + knife solo で、encrypted data bag を使うための 5ステップ [password]

More than 1 year has passed since last update.

こんなタイトルの記事はいくらでもあるので、今更感満載だけれども、あえて書きます。
なぜかというと「私のため」だから。

さて、chef を使っていて、パスワードを埋め込んだり変更したりと言うことはよくあるざます。
その時に、node ファイルや attributes へ直接書き込んだまま、Github に上げてしまうと、パスワードバレバレの事態になります。さすがに初心者でも気がつく当たり前の事象です。

とは言え、data bagってなんかめんどくさいし、password は環境変数 でもいっか、とか手の抜きどころを沢山考えたのですが、折角与えられた機能だから使ってみよう。使っておこう。
そういうことにして、本日はそのステップのみを記載して終わりにします。

夜遅いし、まだ仕事終わってないし。

1. 鍵を作る

君のマシンに openssl コマンドはあるか?
よし、次のコマンドを打て

openssl rand -base64 512 > data_bag_key

名前も場所も好きなところで良いけれども、~/chef_repo 配下だと何も考えずに git add して git commit して git push して泣くことになるかも知れないので、別のトコへ配置するのが推奨かも。 .gitignore にわざわざ書いてもいい。

オレは Emacsmagit-status でいちいち staging する内容確認してるから、どこでも問題なし。さすが、Emacs (関係ない)

2. .chef/knife.rb 書き換え

書き換えといっても大したことじゃないです。
最小限の作業としては、1行アンコメントするだけです。

.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 "data_bag_key"

knife[:berkshelf_path] = "cookbooks"

encrypted_data_bag_secret "data_bag_key" をアンコメントして、指定したファイルとするだけです。/etc/chef/data_bag_key へ配置したなら
encrypted_data_bag_secret "/etc/chef/data_bag_key" となることでしょう。
簡単。

3. knife solo 用の data bag ツールを準備する

たいそうなこと言ってますが、gem install knife-solo_data_bag してくださいってだけです。sudo する派もしない派もどちらでもいいですし、bundle派も自分の環境どおりに好きにしてください。私は sudo派です。ゴメンなさい。

gem
$ sudo gem install knife-solo_data_bag
Password:
Fetching: knife-solo_data_bag-1.1.0.gem (100%)
Successfully installed knife-solo_data_bag-1.1.0
Parsing documentation for knife-solo_data_bag-1.1.0
Installing ri documentation for knife-solo_data_bag-1.1.0
1 gem installed

4. 鍵を使って暗号化 json を作成する

事前に EDITOR 環境変数を指定しておきましょう。よく分からない人は次のようにして、vi でも使ってください。vi の使い方知らない人が、chef 使うことはあり得ないでしょう。

EDITOR
$ export EDITOR=vi

そして、次のコマンドです。

create_data_bag
$ knife solo data bag create password mysql --secret-file ./data_bag_key 

knife solo data bag create まで固定です。
次に指定している password mysql は、ディレクトリで示すと次のようになります

mysql
~/chef_repo/data_bags/password/mysql.json

分かりやすい。password というグループに、mysql 用の定義を準備したと理解するといいですね。はい、私はそんな風に理解しました。

--secret-file の後は、お分かりのように、1. で作成した鍵ファイルを指定します。

すると、きっと次のような画面が出てくるはずです。

default
{
  "id": "mysql"
}

ここで必要な定義を追加して、そっと閉じましょう。

default
{
  "id": "mysql",
  "password": "p@ssw0rd"
}

実際はこんな単純なパスワードは使ってませんが、例えばです。 なお、"id": "mysql" は、おまじないの中でも必須な条項です。書き換えるのはやめておきましょう。

試しに中を覗いてみるとこんな感じです。

mysql.json
$ cat data_bags/password/mysql.json 
{
  "id": "mysql",
  "password": {
    "encrypted_data": "6u167KJgpqz0MxwHW+SZ3/kxXkehCeCYZfuSqoJqYRg=\n",
    "iv": "raa292+i9HCAED4DC9eEFg==\n",
    "version": 1,
    "cipher": "aes-256-cbc"
  }
}

見事、暗号化されていますね。良かった。

5. recipe で読み出す

後は、実際にchef のレシピで呼び出すだけです。

こう。

load
data_bag = Chef::EncryptedDataBagItem.load('password','mysql')
mysql_password = data_bag['password']

これで、mysql_password 変数に一時的に復元されたパスワードが保持されました。

template resource 内で使う場合は、variables で飛ばして上げる必要があります。

template
template "foo" do
  variables ({
               :password => mysql_password
             })
end 

で、foo という tepmlate ファイル内では、こう

foo
PASSWORD = '<%= @password %>'

で定義されます。良かったネヽ(´ー`)ノ