[chef] attributeの理解

今回はattributeの話。
お約束ですが、この記事の内容は私が一人で分かったつもりになって書いていることなので、誤認やウソが書いてありましたらご指摘してくださると助かります。

attributeとは

Recipeではできるだけ汎用的に書いた方がいいという雰囲気がありますが、それはその通りだと思います。
その汎用性を持たせる機能を担っているのが、providerとこのattributeでは無いでしょうか。
providerはOSなどの環境を吸収してくれて、attributeは変数として使うことができます。

分からなかったのはあちこちでattributeが設定できること

CookbookやRecipeを調べてたり、ドキュメントを読んでいたりすると、あちこちでdefault_attributesやらoverride_attributesを見かけます。
いったいどこでattributeを設定するのが正しいの?と混乱してしまっていました。

その混乱を鎮めたのがドキュメント以下の記述。

Chef > Home > Chef Essentials > Attributes > Precedence

これを見ると設定箇所によってプライオリティがあり、どこで設定するのが適切かということが分かった気がします。

イメージとしては、CookbookのCOOKBOOK/attribute/default.rbではデフォルト値を設定。
roleのdefault_attributesではそのRoleに適した値を設定。
という感じでしょうか。

具体例

具体例を挙げてみます。
シナリオはいつもの通りAWS EC2でchefを使うという想定です。
複数のAWSアカウントを持っていて、横断的にchefを使いたい。
例としてAWSアカウントの各種認証情報をサーバに保管するRecipeを作ります。

template "/path/to/credencial" do
 source "credencial.erb"
 owner "root"
 group "root"
 mode 0644
 variables(
  :cert      => node["ec2"]["cert"],
  :pk        => node["ec2"]["cert"],
  :awsid     => node["ec2"]["awsid"],
  :accesskey => node["s3"]["access_key_id"],
  :secretkey => node["s3"]["secret_key"],
  :region    => node["ec2"]["region"]
 )
end

これは/path/to/credencialというファイルにAPIの証明書やらaccesskey_idなどの情報を記載したファイルのResourceです。
もちろんCOOKBOOK/templates/default/credencial.erbというテンプレートファイルも用意します。
そして、COOKBOOK/attribute/default.rbに以下のように上記resourceで使っているattributeのデフォルト値を設定します。

# s3 key 
default["s3"]["access_key_id"] = ""
default["s3"]["secret_key"] = ""

# ec2 credencial
default["ec2"]["key_location"] = ""
default["ec2"]["cert"] = ""
default["ec2"]["pk"] = ""
default["ec2"]["awsid"] = ""
default["ec2"]["region"] = "ap-northeast-1"

デフォルト値と言ってもそれぞれ、適切な値を入れないと意味がないので、適当に空に設定してみました。

次にRoleを作ります。
account_aというAWS Accountに紐づいたRole[account_a]というroleを作ります。

name "account_a"
description "AWS account_a account servers"
run_list("recipe[Ec2Init]")
default_attributes({
  "s3" => {
    "access_key_id" => "xxxxxxxxxxxxxxxx",
    "secret_key" =>  "xxxxxxxxxxxxxxxxxxx"
  },
  "ec2" => {
    "key_location" => "hoge",
    "cert" => "cert-xxxx.pem",
    "pk" => "pk-xxxx.pem",
    "awsid" => "xxxx"
  }
})

こんな感じで、attributeを便利に使うことができました。

まとめ

attributeが使えるようになって、汎用性がぐっと広がりました。
やってみて分かったんですが、attributeは最終的にnodeに付与されて、node['hoge']['piyo']という感じで指定するんですね。

次回はなにかな?

コメントを残す

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