サーバー設定ツール「Chef」をより便利に使うためのテクニック 4ページ
Data Bagを使ったRecipeを作成する
続いて、RecipeからData Bagに格納したデータにアクセスする方法を説明しよう。今回は「setup-user」というCookbookを作成し、そこから先ほどのData Bagにアクセスしてユーザーやグループを作成することにする。
$ cd chef-repo/cookbooks/ $ knife cookbook create setup-user -o . ** Creating cookbook setup-user ** Creating README for cookbook: setup-user ** Creating CHANGELOG for cookbook: setup-user ** Creating metadata for cookbook: setup-user $ vi setup-user/recipes/default.rbRecipe(default.rb)の内容は、以下のようになる。
accounts = data_bag('initial_accounts') accounts.each do |id| item = data_bag_item('initial_accounts', id) item['groups'].each do |g| group g['name'] do gid g['gid'] action :create end end item['users'].each do |u| user u['name'] do home u['home'] password u['password'] shell u['shell'] uid u['uid'] gid u['gid'] supports :manage_home => true action :create end end end
Recipe内からData Bagのデータを取得するには、data_bag関数を使用する。引数には対象のData Bag名を文字列で指定する。たとえば「initial_accounts」というData Bagを取得するには、以下のようになる。
accounts = data_bag('initial_accounts')
data_bag関数の戻り値は、data_bagに含まれるデータの「id」を格納した配列となる。続いて、Data Bag名とidを引数に与えてdata_bag_item関数を実行することで、データをハッシュとして取得できる。今回の例では、以下のように配列のeachメソッドを使ってidを順番に取り出し、それを引数としてdata_bag_item関数を呼び出すことでデータを取り出している。
accounts.each do |id| item = data_bag_item('initial_accounts', id)
data_bag_item関数の戻り値は、JSONで指定したものと同じデータ構造を持つハッシュとなっており、以下のように[‘キー名’]という書式で各項目を取得可能だ。
item['groups'].each do |g| group g['name'] do gid g['gid'] action :create end end
作成したCookbookは前回解説したとおり「knife cookbook upload」コマンドでアップロードできる。
$ knife cookbook upload setup-user
このCookbookをクライアント側で実行すると、以下のようにユーザーおよびグループが作成される。
# chef-client -o setup-user Starting Chef Client, version 11.6.2 [2013-10-24T19:58:40+09:00] WARN: Run List override has been provided. [2013-10-24T19:58:40+09:00] WARN: Original Run List: [] [2013-10-24T19:58:40+09:00] WARN: Overridden Run List: [recipe[setup-user]] resolving cookbooks for run list: ["setup-user"] Synchronizing Cookbooks: - setup-user Compiling Cookbooks... Converging 2 resources Recipe: setup-user::default * group[taro] action create (up to date) * user[taro] action create - alter user user[taro] Chef Client finished, 1 resources updated
このように作成されたCookbookでは、Cookbook側を変更することなく、Data Bagのみを変更することで作成するユーザーを追加したり、その情報を変更することが可能だ。たとえば、新たに「jiro」というユーザーを追加したい場合、JSONファイルを以下のように修正すれば良い。
{ "id": "default", "groups": [ { "name": "hylom", "gid": 1000 }, { "name": "jiro", "gid": 1001 } ], "users": [ { "name": "hylom", "home": "/home/hylom", "password": "$6$OmC3KootOURrqOaP$63rwQ2bSE8op8wXa.ZWzgxm/iGvePTzEL5lOntmkPyYh5Qwh4lWs2DtyoEHcvsbYV5Q6a2ezzrZueb2ydrkhz0", "shell": "/bin/bash", "uid": 1000, "gid": "hylom" }, { "name": "jiro", "home": "/home/jiro", "password": "$6$OmC3KootOURrqOaP$63rwQ2bSE8op8wXa.ZWzgxm/iGvePTzEL5lOntmkPyYh5Qwh4lWs2DtyoEHcvsbYV5Q6a2ezzrZueb2ydrkhz0", "shell": "/bin/bash", "uid": 1001, "gid": "jiro" } ] }
このJSONデータをData Bagに格納し、再度Cookbookを実行すると新たにユーザー「jiro」が作成される。
$ knife data bag from_file initial_accounts default.json
# chef-client -o setup-user Starting Chef Client, version 11.6.2 [2013-10-24T20:08:31+09:00] WARN: Run List override has been provided. [2013-10-24T20:08:31+09:00] WARN: Original Run List: [recipe[setup-user]] [2013-10-24T20:08:31+09:00] WARN: Overridden Run List: [recipe[setup-user]] resolving cookbooks for run list: ["setup-user"] Synchronizing Cookbooks: - setup-user Compiling Cookbooks... Converging 4 resources Recipe: setup-user::default * group[taro] action create (up to date) * group[jiro] action create - create group[jiro] * user[taro] action create (up to date) * user[jiro] action create - create user user[jiro] Chef Client finished, 2 resources updated