kikumotoのメモ帳

インフラ・ミドル周りを中心に、興味をもったことを適当な感じで。twitter : @takakiku

はじめてのレシピ

Chef Server, Chef Client(Node), Knife Client と一通り環境が揃ったので、All about Chef ... — Chef Docsに従って、Recipeを書いて、Nodeに適応してみる。

Chefリポジトリの用意

cookbookを書いていくあたって、ローカルにChefリポジトリを用意する。これにはひな形が github に公開されているのでこれをもらってくる。今回は git はインストールしていないので tarball で取得し展開した。

$ wget --no-check-certificate https://github.com/opscode/chef-repo/tarball/master
$ tar xzf opscode-chef-repo-9769e69.tar.gz
$ mv opscode-chef-repo-9769e69 chef-repo

ちなみに作業しているのは knife が使える環境。

Chefの考え方としては、このリポジトリを git, bazaar, subversion などのソースコード管理に入れろということらしい。

Recipeの作成

Recipeを作成するにあたっては、knife コマンドでそのひな形を作成することができる。

$ cd chef-repo/cookbooks
$ knife cookbook create quick_start -o ./

これで、quick_start というディレクトリが作成されて、さらにその配下にいくつかディレクトリが作られる。

ChefのWikiに書かれているサンプルのRecipeでは、テキストファイルを作って、その中にAttributeで指定される値を流し込むという感じのもの。

そこで、Attributeを定義する。quick_start/attributes/default.rb を以下のように作成。

default["first_name"] = "Mickey"
normal["second_name"] = "Mouse"

後の説明ために、あえて default と normal Attribute で書いている。

このAttributeを利用して作成されるtemplate resourceをquick_start/recipes/default.rbに記述。

template "/tmp/name.txt" do
  source "name.txt.erb"
  action :create
end

そしてtemplate自体を、quick_start/templates/default/name.txt.erbとして以下のように作成。

My Name is <%= node["first_name"]%> <%= node["second_name"]%>.
This server address is <%= node[:ipaddress]%>.

これでRecipeができたので、Chef Serverに以下のコマンドでアップロードする。

$ cd chef-repo
$ knife cookbook upload quick_start -o cookbooks/

登録できていれば、以下のコマンドで登録状況を確認できる。

$ knife cookbook list
[
  "quick_start"
]

Nodeへの適用/反映

作ったRecipeをNodeに適用するためには、以下のようなコマンドを実行する。

$ knife node run_list add <NODENAME> 'recipe[quick_start]'
{
  "run_list": [
    "recipe[quick_start]"
  ]
}

これで対象となるNodeにログインして、chef-clientを実行する。

# chef-client

これで、/tmp/name.txt が作成されて以下の内容になっているはず(ここでは、このNodeのアドレスは192.168.100.11としている)。

My Name is Mickey Mouse.
This server address is 192.168.100.11.

chef-client は何度実行しても同じ状態になるというのが1つの特徴。この/tmp/name.txtを適当に修正してから、再度実行すれば元の内容に戻っていることが確認できる。

Attributeの変更(上書き)

attrributeを

default["first_name"] = "Mickey"
normal["second_name"] = "Mouse"

のように用意したけれど、これをNodeやRoleに応じて上書きしてみる。

Node Attributeでの変更

Node Attributeではnormal attributeの定義しかできないみたいなので(All about Chef ... — Chef Docs)、上書きできるのはdefault attributeの方のみのようである。これは以下のようにして、Nodeの属性を直接編集する。

$ export EDITOR=/bin/vi
$ knife node edit <NODENAME>

これで、

  "normal": {
    "tags": [

    ],
    "second_name": "Mouse"
  },

という部分を

  "normal": {
    "tags": [

    ],
    "second_name": "Mouse",
    "first_name": "Minnie"
  },

に変える。

これで、対象のNodeで再度chef-clietを実行すると、/tmp/name.txtは

My Name is Minnie Mouse.
This server address is 192.168.100.11.

となる。

Role Attributeでの変更

normal Attribute は override できるので、これを Role Attribute に記述してみる。
Role を作成するためのコマンドを実行する。

$ knife role create roletest

すると、エディタが起動するので、以下のように記述して保存して閉じる。

{
  "name": "roletest",
  "description": "",
  "json_class": "Chef::Role",
  "default_attributes": {
  },
  "override_attributes": {
    "second_name": "Riperton"
  },
  "chef_type": "role",
  "run_list": [
    "recipe[quick_start]"
  ]
}

この段階では、Nodeにはquick_startレシピが直接反映されるので、このRoleが適用されるようにする。

knife node run_list remove <NODENAME> recipe[quick_start]
knife node run_list add <NODENAME> "role[roletest]"

以上で、再度対象Nodeにてchef-clientを実行すると、/tmp/name.txtは以下のようになる。

My Name is Minnie Riperton.
This server address is 192.168.100.11.

とりあえず、こんな感じでRecipeを書いていくというイメージはつかめた気がする。
で、気になったのはChfeリポジトリのcookbooks配下の構成方法。どういう感じがいいんだろう?
これについて後日少し考えてみようと思う。