...
コード ブロック |
---|
/home/vagrant/workspace/<Cookbook 名> |
...
隠しファイルを表示する
Package Explorer の ▽ を選択 -> Filters…
「.*resources」のチェックを外す
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 ] です。
Recipe は基本的に上から順に、記述した順で Resource が実行されます。
たとえば、「ファイルをダウンロード」してから「ダウンロードしたファイルを解凍」したい場合は、次のように記述できます。
コード ブロック |
---|
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 |
...
Recipe を書くにはまず、「具体的に何をしたいのか」を明らかにし、それに対し「どの Resource を使用するか」を決めなければなりません。そうしてからようやく具体的なソースコードを記述できます。
たとえば、あるアプリケーションのコマンドにパスを通すために、/etc/profile.d/application.sh に 「export PATH=$PATH:/opt/application/bin」 という内容のファイルを配置したいとします。
これはどの 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 を書くには、
具体的に何をしたいのかを明らかにする
使えそうな Resource を探し、仕様を確認する
Recipe を記述する
という手順を繰り返していきます。
Jenkins をインストールする Recipe をつくる
...
作成した Recipe が期待したとおりに動いているか確認してみましょう。
確認には Kitchen を利用すると便利です。
Kitchen とは、任意の環境をインスタンスとして起動し、プロビジョニングを行い、その結果を検証できるツールです。インスタンスは何度でも簡単に作り直すことができるので、気軽に とは、任意の環境をインスタンスとして起動し、プロビジョニングを行い、その結果を検証できるツールです。
インスタンスは何度でも簡単に作り直すことができるので、気軽に Chef の Recipe を試すことができます。
まずは Kitchen を使用するために、設定ファイル .kitchen.yml を編集しましょう。
コード ブロック |
---|
driver: |
...
name: docker
provisioner:
...
name: docker provisioner: name: chef_solo |
...
platforms: |
...
- name: centos-6.4 |
...
driver_config: |
...
image: centos
forward: 8080
suites:
- name: default
run_list:
...
image: centos forward: 8080 suites: - name: default run_list: - recipe[tar::default] |
...
- recipe[java::default] |
...
- recipe[jenkins::default] |
...
attributes:
java:
...
attributes: java: install_flavor: |
...
oracle jdk_version: |
...
7 java_home: /usr/java/default |
...
oracle:
...
oracle: accept_oracle_download_terms: true |
ポイント
driver
軽量・高速な docker を使用します。
Kitchen から docker を利用するには kitchen-docker のインストールが必要です。
コード ブロック |
---|
$ chef gem install kitchen-docker |
※ 今回の環境には既にインストールされています。
driver_config
centos をベース image とします。
利用できる image 名は Dockerfile の FROM 句で指定できるものと同じです。
詳細は Dockerfile のリファレンスを参照してください。
[ https://docs.docker.com/reference/builder/#from ]
forward ではホストマシンにフォワーディングするポート番号を指定します。
今回は jenkins が使用する 8080 ポートに http://localhost:8080 でアクセスできるように指定しています。
詳細は kitchen-docker のドキュメントを参照してください。
[ https://github.com/portertech/kitchen-docker ]
run_list
プロビジョニング時に実行する Recipe を指定します。
Jenkins の動作には Java が必要なので、今回は Opscode Community の java Cookbook を使うことにします。また、java を使うことにします。
また、java Cookbook の動作には tar が必要なので、これも Opscode Community の tar Cookbook を使います。自作した を使います。
自作した jenkins Cookbook も忘れずに指定しましょう。
※ プロビジョニングに外部の Cookbook が必要な場合は後述する Berksfile の編集が必要です。
attributes
プロビジョニング時に Recipe にわたす Attribute を指定します。
Attribute とは Recipe に対するパラメータのようなものです。今回は に対するパラメータのようなものです。
今回は Opscode コミュニティの java Cookbook の Attribute を指定しています。詳細は を指定しています。
詳細は java Cookbook の README.md を参照してください。
[ http://community.opscode.com/cookbooks/java ]
Berksfile の編集
プロビジョニング時に必要な外部の Cookbook は、このファイルをもとに berkshelf によって解決されます。Opscode Community の Cookbook であれば、次のように名前を指定するだけでOKです。
...
コード ブロック |
---|
source "https://api.berkshelf.com" |
...
cookbook ‘tar' |
...
cookbook 'java' |
...
metadata |
※ Opscode Community 以外の依存
Git リポジトリ
git: ‘https://path/to/cookbook.git’ローカルファイルシステム
path: ‘/path/to/cookbook’
Kitchen インスタンスの起動とプロビジョニング
では、作成した Cookbook を Kitchen のインスタンスへプロビジョニングしてみましょう。
...
コード ブロック |
---|
$ kitchen setup |
プロビジョニングが成功したら、Kitchen インスタンスにログインしてみてください。
...
コード ブロック |
---|
[vagrant] $ kitchen login |
...
kitchen@localhost’s password: kitchen |
...
[kitchen] $ sudo service jenkins status |
...
jenkins (pid 17656) を実行中... |
...
[kitchen] $ exit |
ログインできたら、jenkins サービスが実行されているか確認してみましょう。
/etc/sysconfig/jenkins の内容も確認してみてください。
うまくいっていない場合は、Cookbook を修正し、次のコマンドでプロビジョニングをやり直します。
...
コード ブロック |
---|
$ kitchen converge |
以前プロビジョニング結果が原因でプロビジョニングがうまくいかない場合は、次のコマンドで Kitchen インスタンスを破棄してから、再度プロビジョニングを実行します。
...
コード ブロック |
---|
$ kitchen destroy |
...
$ kitchen setup |
※ kitchen の主なサブコマンド
コード ブロック |
---|
# インスタンスの生成 |
kitchen create |
# Chef-Solo のインストールと初回のプロビジョニング |
kitchen setup |
# プロビジョニング |
kitchen converge |
# Serverspec の実行 |
kitchen verify |
# ssh ログイン |
kitchen login |
# インスタンスの破棄 |
kitchen destroy |
Web ブラウザで Jenkins にアクセス
docker コマンドでコンテナのポートを確認します。
...
コード ブロック |
---|
$ docker ps |
...
CONTAINER |
...
ID PORTS e35e89ea252a 0.0.0.0:49153->22/tcp, 0.0.0.0:49154->8080/tcp |
コンテナの 8080 ポートがホストの 49154 にフォワーディングされていることが確認できます。
Firefox などの Web ブラウザで http://localhost:49154/ にアクセスしてみてください。
Jenkins の画面が表示されていれば成功です。
Attribute に対応させる
Attribute とは
Recipe にパラメータを与える仕組みです。
プロビジョニング時に Attribute を指定することで、Recipe の動作などを変化させることができるようになります。
Attribute を指定するには
Attribute は Key - Value 形式のデータで、指定する方法はプロビジョニングツールにより異なります。
Kitchen の場合
.kitchen.yml の attributes に、YAML形式で定義
...
コード ブロック attributes:
...
application:
...
application: version: ‘2.0.0’
Vagrant の場合
Vagrantfile の chef.json に、Hash で定義
...
コード ブロック config.vm.provision :chef_solo do |chef|
...
chef.json =
...
application: {
...
{ application: { version: ‘2.0.0’
...
}
...
} }
Knife の場合
knife node edit で Json ファイルを編集
...
コード ブロック "normal":
...
“application”: {
“version”: {}
}
}
{ “application”: { “version”: {} } }
※ 実際の運用では knife を使っていないので、間違っているかもしれません。
Attribute の値を Recipe で 使う
Recipe から Attribute の値を参照するには、node オブジェクトを利用します。
Attribute が以下のように設定されている場合、
...
コード ブロック |
---|
attributes: |
...
application: {
...
{ application: { version: ‘2.0.0’ |
...
}
} } |
Recipe では以下のように node オブジェクトを経由して、目的の Attribute の値を取得できます。
コード ブロック |
---|
application_version = node[‘application’][‘version’] |
Attribute にデフォルト値をセットする
Attribute にはプロビジョニングツールで値が指定されなかった場合のデフォルト値を指定しておくことができます。
デフォルト値は専用のファイルに記述します。ファイルは chef コマンドで生成できます。
...
コード ブロック |
---|
chef generate attribute ./ default |
./attributes/default.rb というファイルが生成されますので、以下のようにデフォルト値を定義します。
コード ブロック |
---|
default[‘application’][‘version’] = ‘1.0.0’ |
jenkins Cookbook を Attribute に対応させる
何を Attribute にするか
Cookbook の設計次第で何を Attribute にするかは変わります。
今回は次の項目を Attribute にしてみましょう。
Jenkins のバージョン
特定のバージョンの Jenkins をインストールしたくなるかもしれないJenkins の rpm ファイルの URL
将来的に、rpm ファイルの URL が変更されるかもしれないJenkins の実行ユーザー
特定のユーザーで Jenkins を実行したくなるかもしれない
ヒント
Attribute の名前
一般的には、「node[<Cookbook の名前>][<任意の Attribute 名>]」とすることが多いようです。
Recipe の中で自身の Cookbook 名を取得するには cookbook_name Method [ http://docs.opscode.com/dsl_recipe_method_cookbook_name.html ] を利用できます。
※ ./attribute/defualt.rb では利用できません。
Kitchen で確認
対応が完了したら、.kitchen.yml に作成した Attribute を追記して、Kitchen インスタンスでプロビジョニングを行い確認してみましょう。
...
コード ブロック |
---|
$ kitchen destroy |
...
$ kitchen setup |
...
$ kitchen login |
...
kitchen@localhost’s password: kitchen |
Cookbook のテスト
Foodcritic [ http://acrmp.github.io/foodcritic/ ]
Chef 専用の静的テストツールで、ChefDK に含まれています。
Cookbook のルートディレクトリでコマンドを実行すると、Chef のお作法に違反したコードなどが検出されます。
...
コード ブロック |
---|
$ foodcritic ./ |
警告のメッセージには Foodcritic のルール番号が含まれています。
Foodcritic の公式サイトには各ルールの詳細な情報と修正例が記載されていますので、参考にしてください。
Ruby の静的テストツールを利用する
Recipe は Ruby で記述されているので、Ruby の汎用的な静的テストツールを利用することもできます。
Reek [ https://github.com/troessner/reek ]
複雑なコードを検出する静的テストツール
...
コード ブロック |
---|
$ reek ./ |
Flay [ http://ruby.sadi.st/Flay.html ]
重複コードを検出する静的テストツール
コード ブロック |
---|
$ flay ./ |
これらのツールは gem でインストールできるものです。
ChefDK の gem にインストールするには、以下のようにコマンドを実行します。
コード ブロック |
---|
chef gem install <gem パッケージ名> |
※ 今回の環境では reek、flay は既にインストールされています。
...