基本的な用語
Chef でのプロビジョニングを行うには、まず Resource、Recipe、Cookbook という単語をおさえておきましょう。
これは、Chef を使うにあたって最低限作らなければいけないものです。
Resource
Resource はプロビジョニング先の "ある部分" の "あるべき状態" を宣言的に定義する DSL です。
各 Resource にはユニークな名前を指定する必要があり、それがプロビジョニング先の ”どの部分か” を表しています。
そして、Resource の do ~ end ブロックに ”あるべき状態” を定義します。(ResourceType によって定義できる内容は異なります。)
Chef でのプロビジョニングは、Resource があるべき状態に収束されることを意味します。
Recipe
Recipe は Resource を記述するためのファイルです。
Ruby のコードをそのまま使って Resource を定義できます。
Recipe に定義した Resource はプロビジョニングの実行時に解釈され、収束するべき Resource がキューイングされます。
基本的に、Resource は Recipe に定義した順でキューイングされます。
Recipe に書いた Ruby コードは Resource が収束されるときでなく、キューイングされるときに実行されることに注意してください。
Cookbook
Cookbook は Recipe を意味のある単位で取りまとめたものです。
Cookbook は複数の環境で使いまわすことができ、たいていの場合はインストールするアプリケーションやサービス単位で作成されます。
Cookbook も名前で管理されるので、ユニークで、かつ内容を表す名前をつけましょう。
Cookbook をつくる
Cookbook のディレクトリ構成
パス | 概要 |
---|---|
recipes/ | Cookbook の Recipe を置きます。 |
attributes/ | Recipe で Attribute を使う場合、ここにデフォルト値を定義するファイルを置きます。 |
templates/ | Recipe で Template を使う場合、ここに置きます。 |
files | Recipe で File を使う場合、ここに置きます。 |
metadata.rb | Cookbook の名前やバージョン、依存関係などの情報を記述します。 |
Berksfile | Cookbook の依存する Cookbook を定義します。 |
README.md | Cookbook の README を記述します。 |
.kitchen.yml | Cookbook のテスト環境を定義します。 |
Cookbook のひな形の生成
まずは Cookbook を作成しましょう。
ChefDK の chef generate cookbook コマンドを使えば簡単に Cookbook のひな形を生成できます。
$ cd workspace $ chef generate cookbook <Cookbook 名>
Cookbook を Eclipse で編集しよう
Eclipse のプロジェクトファイル ".project" をつくっておけば、Cookbook を Eclipse プロジェクトとして開けます。
ツリービューとタブエディタ(だけ)は便利なので、 他によいエディタがない場合は、次の手順で Eclipse プロジェクトをインポートしましょう。
.project を生成
スクリプトを実行し .project を生成します。
$ cd <Cookbook 名> $ gen-eclipse
"gen-eclipse" は開発環境の ~/bin/gen-eclipse に置いてある .project 生成用のスクリプトです。
プロジェクトをインポート
Eclipse を起動し、プロジェクトをインポートします。
1 | 2 | 3 |
---|---|---|
File -> Import... | General -> Existing Projects into Workspace Next | 「/home/vagrant/workspace/<Cookbook 名>」を追加 Finish |
Package Explorer に隠しファイルも表示させる
標準では .kitchen.yml が見えないので、次の手順で隠しファイルを表示します。
1 | 2 |
---|---|
Package Explorer の ▽ を選択 -> Filters… | 「.*resources」のチェックを外す OK |
Recipe を書く
default Recipe
chef generate cookbook コマンドを実行すると、./recipes/default.rb というファイルができていると思います。
それが Cookbook がデフォルトで適用する Recipe です。
特別な理由がない限りは default.rb に基本となる Recipe を書いていきます。
default Recipe 以外の Recipe は chef generate recipe コマンドで追加できます。
$ chef generate recipe <Cookbook のパス> <Recipe の名前>
Resource の要素
Recipe には Resource を定義していきます。
Resource とは、プロビジョニング先の ”ある部分” の ”あるべき状態” を宣言的に定義したもので、具体的には以下の要素で構成されます。
ResourceType
Resource の型を表します。
yum パッケージの状態を定義する yum_package Resource、任意のコマンドの実行状態を定義する execute Resource などがあります。
ResourceType によって、指定できる Attribute や Action は異なります。
詳細は各 ResourceType の公式ドキュメントに記載されているので、確認するようにしてください。
Name
Resource の名前を定義します。
公式ドキュメントを見るとわかりますが、yum_package では Resource の名前がそのまま package_name Attribute になる仕様になっています。
Attribute
Resource の "あるべき状態" について、詳細に定義します。
yum_package であれば version などを指定できます。
Action
Resource の適用のされ方を定義します。
yum_package であれば、インストールされている状態(:install)、アンインストールされている状態(:remove)などを指定できます。
ResourceType についての公式ドキュメントは Chef の公式ドキュメントから辿ると非常に見つけにくいです。
Google で「Opscode <ResourceType 名>」などと検索したほうが早く見つけられたりします。
また、Mac であれば Dash に Chef のドキュメントがあるので、これを使うのもオススメです。
Resource の実行順序
Recipe は上から順に解釈され、Resource は基本的には Recipe に定義した順でキューイングされ、収束されます。
たとえば、「ファイルをダウンロード」してから「ダウンロードしたファイルを解凍」したい場合は、次のように記述できます。
remote_file '/tmp/archive.tar.gz' do source 'http://path/to/archive.tar.gz' action :create end bash 'extract tar file' do cwd '/tmp' code 'tar zxf archive.tar.gz' action :run end
notifies などを利用して、Resource の実行順序を制御することも可能です。
Recipe に書いたコードは基本的に Recipe が解釈されるときに実行されます。
Resource が実行されるタイミングでコードを実行したい場合は ruby_block や lazy を使います。
冪等性を確保する
Chef では何度 Recipe を実行しても同じ結果になることが望まれています。
これは Chef 標準の package Resource などを使用していれば Resource 側で確保してくれるのですが、
bash Resource などでは自力でがんばって確保するしかありません。
冪等性を確保するには、not_if や only_if を使用して Resource にガード条件を設定します。
例えば、特定のファイルが存在しないときだけ Resource を実行するには次のように書きます。
exexute 'install peco' command 'cp /tmp/peco_linux_amd64/peco /usr/local/bin/peco' not_if { File.exists?('/usr/local/bin/peco') } end
この例では、Resource が実行される直前に not_if ブロックの Ruby コードが実行され、結果が false のときだけ Resource が実行されます。
逆に結果が true のときだけ Resource が実行されるようにしたい場合は only_if を使います。
また、Ruby のブロックでなく、文字列を直接わたすこともできます。
exexute 'install peco' command 'cp /tmp/peco_linux_amd64/peco /usr/local/bin/peco' not_if "test -e '/usr/local/bin/peco'" end
この場合は not_if にわたした文字列がシェルスクリプトとして実行され、実行結果が 0 以外のときだけ Resource が実行されます。
さきほどと同じように、結果が 0 のときだけ Resource が実行されるようにするには only_if を使います。
Recipe を書く手順
- 具体的に何をしたいのかを明らかにする
- 使えそうな Resource をさがす
- 実際に Recipe を書く
はじめは、目的に対して適切な Resource をさがせることがいちばん大事です。
Google で検索してもいいですし、Dash を使ってもいいですし、Chef実践入門 や Chef活用ガイド のような書籍を利用するのも手です。
実際に作ってみる
ここまでの手順がなんとなくわかったら、次は実際に Cookbook を作ってみます。
次のページ に進んでください。