[chef] data bag活用法

data_bagを使う

chefにはdata_bagというものがあります。
attributeとは何が違うのかなーと思っていましたが、良い使い方を見つけましたのでご紹介させていただきます。

ユーザアカウントは全てdata_bagで管理

ユーザアカウント系は全てdata_bagで管理すると楽かも!と思ってやってみました。
例えばログインアカウント。
サーバの機能や場所ごとにroleを作りますが、そのroleの中でログインアカウントを管理するrecipeを入れるとします。
data_bagを使わないとrecpieもしくはroleのattributeにユーザ情報を格納して、recipeのuser resourceでユーザを作成することになると思います。
僕の管理している環境では鍵認証が基本なので公開鍵の情報も管理をしたいです。公開鍵はユーザに紐づいていてどのサーバでも同じ鍵で入れると便利ですよね。
そこで、data_bagを活用。
data_bagはdata_bagそのものと、data_bag_itemという2階層構造になっているようです。
まず、data_bag['users']というdata_bagを作成します。  
そしてその中にdata_bag_item['login_account']というdata_bag_itemを作ります。
data_bag_item[‘login_account’]は配列でユーザ情報が格納されています。
例えばこんな感じ。

{
  "users":[
    {
      "system": [
        "role1",
        "role2"
      ],
      "key": "ssh-rsa xxx",
      "name": "user01",
      "active": true,
      "uid": 10001
    },
    {
      "system": [
        "role1",
        "role2"
      ],
      "key": "ssh-rsa xxx",
      "name": "user02",
      "active": true,
      "uid": 10002
    }
  ],
  "id": "login_account"
}

ユーザ情報は

  • uid
  • account名
  • 公開鍵
  • ユーザを作るシステム
  • 有効フラグ

という情報からなっています。

ユーザ作成のrecipeはこんな感じ。

# User add or delete
for u in data_bag_item('users','login_account')['users']
act = false

  # 適用システムかどうかを確認する
  for role in node["roles"]
    for system in  u["system"]
      if role == system
        act = true
        break
      end
    end
    if act
      break
    end
  end

  if ! act
    next
  end

 # activeがfalseなら削除
 user_act = u["active"] ? "create":"remove"

 # ホームディレクトリの文字列作成
 home_dir = "/home/" + u["name"]

 # useradd
 user u["name"] do
  uid u["uid"]
  gid u["uid"]
  shell "/bin/bash"
  home home_dir
  action user_act
 end

 # .ssh directory
 ssh_dir = home_dir + "/.ssh"
 # authorized_keys
 authorized_keys = ssh_dir + "/authorized_keys"

 # .ssh directory作成
 if u["active"]
  directory ssh_dir do
   owner u["name"]
   group "ssh_users"
   mode  0700
  end
  
  # authorized_keyの作成
  if u["key"]
   file authorized_keys do
    owner u["name"]
    mode  0600
    content u["key"] + " " + u["name"]
   end
  end
 end
end

こんな感じで、各サーバのユーザアカウントを管理しています。
もう少し大規模になればディレクトリサービスとかを使うのですが、そこまででもない規模はこれでいいかなーと。

これをやっていてchefの残念なところを発見。

 # activeがfalseなら削除
 user_act = u["active"] ? "create":"remove"

この部分はactiveを見て、trueならcreate,falseならremoveというactionのパラメータを指定しています。
理想はrecipeからユーザが消えたら自動で削除してくれるのが良いのですが、どうもそうではないようなので、不要になったユーザはactiveをfalseにして、明示的に削除処理をするようにしています。

login_accountの説明でだいぶ長くなってしまいましたが、このdata_bag["users"]はユーザ管理data_bagとして、login_accountの他に、例えばdata_bag_item['mysql']とかdata_bag_item['basic']とかを登録して、ここを見ればユーザ管理が出来るというように使いたいと思っています。

おしまい。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です