ページ ツリー

比較バージョン

キー

  • この行は追加されました。
  • この行は削除されました。
  • 書式設定が変更されました。

お題: Jenkins の Cookbook をつくる

Jenkins とは

 

手動でインストールするときの手順

 

Cookbook のひな形をつくる

ひな形の生成

ChefDK 内包の chef コマンドで Cookbook のひな形を生成します。

目次

 

基本的な用語

Chef でのプロビジョニングを行うには、まず Resource、Recipe、Cookbook という単語をおさえておきましょう。
これは、Chef を使うにあたって最低限作らなければいけないものです。 

Section
Column

Resource

Resource はプロビジョニング先の "ある部分" の "あるべき状態" を宣言的に記述する DSL です。
Chef でのプロビジョニングは、Resource があるべき状態に収束されることを意味します。

Recipe

Recipe は Resource を記述するためのファイルです。
Ruby のコードをそのまま使って Resource を定義できます。 

プロビジョニングを実行すると、Recipe がコンパイルされ、Recipe に定義した Resource が Resource Collection に登録されます。 
Resource の収束は、基本的には Resource Collection に登録された順で行われます。

Cookbook

Cookbook は Recipe を意味のある単位で取りまとめたものです。
Cookbook は複数の環境で使いまわすことができ、たいていの場合はインストールするアプリケーションやサービス単位で作成されます。 

Column

Drawio
diagramNamechef 用語.drawio
revision1

 

Cookbook をつくる

Cookbook のひな形の生成

まずは Cookbook を作成しましょう。 

ChefDK の chef generate cookbook コマンドを使えば簡単に Cookbook のひな形を生成できます。

コード ブロック
$ cd workspace
$ chef generate cookbook <Cookbook 名>
情報

Cookbook

...

のディレクトリ構成

...

パス

コマンドを実行すると、以下のファイルが作成されます。

...

概要
recipes/

Recipe を置きます。 

attributes/Attribute を使う場合、ここにデフォルト値を定義するファイルを置きます。
templates/Template を使う場合、ここに eRuby ファイルを置きます。
files/File を使う場合、ここにファイルを置きます。
resources/LWRP を使う場合、ここに lightweight resource を置きます。
providers/LWRP を使う場合、ここに lightweight provider を置きます。
metadata.rbCookbook

...

の名前やバージョン、依存関係などの情報を記述します。

...

 

Eclipse プロジェクトに変換

.project 生成スクリプトを実行

BerksfileBerkshelf の設定ファイルです。
Kitchen でテストをするときに依存する Cookbook を定義します。
README.mdCookbook の README を記述します。
.kitchen.ymlKitchen の設定ファイルです。
Cookbook のテスト環境を定義します。

 

Cookbook を Eclipse で編集しよう

Eclipse のプロジェクトファイル ".project" をつくっておけば、Cookbook を Eclipse プロジェクトとして開けます。
ツリービューとタブエディタ(だけ)は便利なので、 他によいエディタがない場合は、次の手順で Eclipse プロジェクトをインポートしましょう。

.project を生成

スクリプトを実行し .project を生成します。

コード ブロック
$ cd <Cookbook 名>
$ gen-eclipse

...

注意

"gen-eclipse" は開発環境の ~/bin/gen-eclipse に置いてある .project

...

生成用のスクリプトです。

...

 

プロジェクトをインポート

 Eclipse を起動し、プロジェクトをインポートします。

123

Image Added

File ->

...

Import...

Image Added

General -> Existing Projects into Workspace

...

 Next

Image Added

/home/vagrant/workspace/<Cookbook

...

名>」を追加

...

Finish 

 

Package Explorer に隠しファイルも表示させる

標準では .kitchen.yml が見えないので、次の手順で隠しファイルを表示します。

12

Image Added

Package Explorer の ▽ を選択 -> Filters…

...

Image Added

 「.*resources」のチェックを外す
OK



Recipe を書く

default Recipe

...

Chef では、インスタンスのあるべき状態を Recipe(ソースコード)として記述します。
Recipe は「ファイルのダウンロード」や「コマンドの実行」など、さまざまな機能をもつ Resource で構成されています。

たとえば、 以下の Recipe は 「bash により “/tmp” ディレクトリで “tar zxf archive.tar.gz” というスクリプトを実行する “extract tar file” という名前の Resource」 を定義したものです。

コード ブロック
 bash “extract tar file” do
  cwd “/tmp”
  code “tar zxf archive.tar.gz”
  action :run
end

ここでは Chef 標準の “bash” という Resource の :run という Action を呼び出すように定義していて、“cwd” や ”code” という Attribute によりそのときのパラメータを指定しています。
指定できる Action や Attribute は Resource ごとに異なるので、Chef のドキュメントを確認してください。bash Resource であれば [ http://docs.opscode.com/resource_bash.html ] です。

Resource の実行順序

...

chef generate cookbook コマンドを実行すると、./recipes/default.rb というファイルができていると思います。
それが Cookbook がデフォルトで適用する Recipe です。
基本的には、このファイルに Recipe を書いていきます。

ヒント

default Recipe 以外の Recipe は chef generate recipe コマンドで追加できます。

コード ブロック
$ chef generate recipe <Cookbook のパス> <Recipe の名前>


Resource の要素

Recipe には Resource を定義していきます。
Resource とは、プロビジョニング先の ”ある部分” の ”あるべき状態” を宣言する DSL で、具体的には以下の要素で構成されます。

Section
Column

ResourceType

Resource の型を表します。

yum パッケージの状態を定義する yum_package、任意のコマンドの実行状態を定義する execute などがあります。

ResourceType によって、指定できる Attribute や Action は異なります。
詳細は各 ResourceType の公式ドキュメントに記載されているので、確認するようにしてください。

Name

Resource の名前です。
ユニークな名前を指定します。

Attribute

Resource の属性です。
Resource がどのような状態であるべきか、詳細な情報を指定します。

yum_package であれば package_name や version などを指定できます。
yum_package
 では Resource の Name がそのまま package_name に指定される仕様になっています。

Action

Resource の収束のされ方です。 

yum_package であれば、インストールされている状態(:install)、アンインストールされている状態(:remove)などを指定できます。

Column

Drawio
diagramNameyum_package.drawio
revision1

ヒント

ResourceType についての公式ドキュメントは Chef の公式ドキュメントから辿ると非常に見つけにくいです。
Google で「Opscode <ResourceType 名>」などと検索したほうが早く見つけられたりします。
また、Mac であれば Dash に Chef のドキュメントがあるので、これを使うのもオススメです。


Resource の実行順序

Recipe は上から順にコンパイルされ、Resource Collection に格納されます。
基本的には Resource Collection に格納された順で Resource が収束されますので、
たとえば、「ファイルをダウンロード」してから「そのファイルを解凍」したい場合は、次のように記述できます。 

コード ブロック
remote_file '/tmp/archive.tar.gz”gz' do
  source “http'http://path/to/archive.tar.gz”gz'
  action :create
end

bash “extract'extract tar file”file' do
  cwd '/tmp”tmp'
  code “tar'tar zxf archive.tar.gz”gz'
  action :run
end

Recipe を書く手順 

Recipe を書くにはまず、「具体的に何をしたいのか」を明らかにし、それに対し「どの Resource を使用するか」を決めなければなりません。
そうしてからようやく具体的なソースコードを記述できます。

 たとえば、あるアプリケーションのコマンドにパスを通すために、/etc/profile.d/application.sh に 「export PATH=$PATH:/opt/application/bin」 という内容のファイルを配置したいとします。
これはどの Resource を使えば実現できるでしょうか。 

Chef のドキュメントを調べると、file Resource というのが見つかります。
これは、任意の内容のテキストファイルを任意のパスに配置する Resource のようです。
使えそうですね。
 

では、file Resource の詳細を確認しましょう。
Chef のドキュメント [ http://docs.opscode.com/resource_file.html ] を参照すると、次のようなシンタックスになっていることが確認できます。

コード ブロック
file <配置先のファイルパス> do
  content <配置するファイルの内容>
end

充分に理解できたら、いよいよ具体的なソースコードを実装します。

コード ブロック
file “/etc/profile.d/application.sh” do
  content “export PATH=$PATH:/opt/application/bin”
end

これで完成です。

このように Recipe を書くには、 

  1. 具体的に何をしたいのかを明らかにする

  2. 使えそうな Resource を探し、仕様を確認する

  3. Recipe を記述する

という手順を繰り返していきます。

 

Jenkins をインストールする Recipe をつくる

 

まずは、手動で Jenkins をインストールする場合の手順を確認します。

 

  1. http://pkg.jenkins-ci.org/redhat/ から rpm をダウンロード

  2. ダウンロードした rpm を yum コマンドでインストール

  3. /etc/sysconfig/jenkins を編集して、実行ユーザーを変更

  4. 利用するディレクトリのオーナーを変更

  5. サービスを登録・起動

 

これを Recipe にしてみましょう。

 

デフォルトの Recipe なので、chef generate cookbook で生成された recipes/default.rb を編集します。

 

ヒント

 

コマンドを実行する

 

execute Resource [ http://docs.opscode.com/resource_execute.html ]

 

ファイルをダウンロードする

 

remote_file Resource [ http://docs.opscode.com/resource_remote_file.html ]

 

※ ダウンロードしたファイルなどは /tmp ではなく Chef::Config[:file_cache_path] に保存する

 

パッケージをインストールする

 

package Resource [ http://docs.opscode.com/resource_package.html ]

 

テキストファイルの内容を置換する

 

ruby_block Resource [ http://docs.opscode.com/resource_ruby_block.html ]

 

Chef::Util::FIleEdit [ http://rubydoc.info/gems/chef/Chef/Util/FileEdit ]

 

※ execute Resource で sed コマンドを実行してもよい

 

※ file Resource + lazy でもできるかな?

 

ファイルやディレクトリのオーナーを変更する

 

ruby_block Resource [ http://docs.opscode.com/resource_ruby_block.html ]

 

FileUtils#chown_R [ http://docs.ruby-lang.org/ja/1.9.3/method/FileUtils/m/chown_R.html ]

 

※ execute Resource で chown コマンドを実行してもよい

 

サービスを起動する / 自動的に起動するように登録する

 

...

ヒント

notifies などを利用して、Resource の実行順序を制御することも可能です。

ヒント

Recipe に書いたコードは Recipe がコンパイルされるときに実行されます。
Resource が収束されるタイミングでコードを実行したい場合は ruby_blocklazy を使います。

 

冪等性を確保する

Chef では Resource の収束結果は何度実行しても常に同じでなければいけません。
yum_package などであれば、何も考えなくとも冪等性が確保されるのですが、
execute や bashruby_block などではサーバーにどのような変更が行われるのか Chef が判断できないので、
自力で冪等性を確保する必要があります。 

冪等性を確保するためのひとつの手段として、ガード条件 があります。
これは、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 を書く手順 

  1. 具体的に何をしたいのかを明らかにする
  2. 使えそうな Resource をさがす
  3. 実際に Recipe を書く

はじめは、目的に対して適切な Resource をさがせることがいちばん大事です。

Google で検索してもいいですし、Dash を使ってもいいですし、Chef実践入門Chef活用ガイド のような書籍を利用するのも手です。


実際に作ってみる

ここまでの手順がなんとなくわかったら、次は実際に Cookbook を作ってみます。

次のページ に進んでください。