レシピの書き方


# リソース別の記載方法
Chefでは管理対象のパッケージやユーザー、グループ等々のことをリソースと呼ぶ。

リソースごとにメソッドがあり、引数に管理対象を取り、続いてブロック内に管理対象のあるべき状態を記載するようになっている。

cookを実行した際は定義されたリソースがあるべき状態になるように変更が行われる（変更がなければ何も行われない）。

レシピ自体は通常のRubyファイルなので、分岐やループ処理など通常のシンタックスを記述して処理を分岐したり、簡略化することができる。

## packageリソース
パッケージリソースを使用すると、内部的にOSに合わせたパッケージ管理システム（yumやapt）でパッケージの管理を行ってくれる。
基本的にはそういったOS依存の部分はChefが自動的に判断して実行コマンドを判別する。

### パッケージのインストール
引数に対象のパッケージ名を記述する。

```ruby:recipes/default.rb
package "git" do
  action :install
end
```

#### ブロック内で使用するメソッド
##### action
:install - パッケージのインストールする。
:upgrade - パッケージのインストールに加え、最新バージョンへのアップグレードも行う（インストール済みの場合はアップグレードのみ）。
:remove - パッケージを削除する。
##### options
アクションを実行する際に、コマンドに渡すオプション（"-f --force-yes"など）を文字列で指定する。
複数指定する場合も、１つの文字列でスペース区切りで複数記載すればよい。
##### version
文字列でパッケージのバージョンを指定する。
##### source
rpmファイルなど、パッケージファイル指定でインストールしたい場合に、パッケージファイルのパスを文字列で指定する。
#### notifies
パッケージのアクションをトリガーとして、別リソースのアクションを実行することができる。
記述形式は以下の通り。

```ruby:recipes/default.rb
  notifies :action "resource_type[resource_name]"
```

他のリソースでも同じように使用できるメソッド。


#### subscribe
他の特定のリソースのアクションが実行された場合に、指定したアクションを実行する。
記述形式は以下の通り。

```ruby:recipes/default.rb
  subscribe :action "resource_type[resource_name]"
```

他のリソースでも同じように使用できるメソッド。

## serviceリソース
引数に対象のサービス名を記述する。

```ruby:recipes/default.rb
service "httpd" do
  action [ :enable, :start ]
  supports status: true, restart: true, reload: true
end
```

#### ブロック内で使用するメソッド
##### action
:enable - サーバ起動時のサービス自動起動を有効にする。
:start - サービスが起動している状態にする。
##### supports
ハッシュ形式で、キー値に対象のオプション（status, restart, reload等）を指定し、値にBool値でオプションの利用可能/不可を指定する。
基本的には {オプション名: true} でサービスが利用可能なオプションを明示するために使用する。

supportsに記載がない場合、Chefは別の代替手段で対象のアクション実行を行う。
例えば、{status: true}の記述がなければ、サービス名と同名のプロセスが存在するかどうかで起動のチェックを行う。

## templateリソース
引数にテンプレートのファイル名を記述する。
ただし、.erbのテンプレートエンジンの拡張子は省いて指定する。
対象のファイルは、クックブックの"templates/default"内のディレクトリにあるものとする。

テンプレートではなく、静的なファイルの配置であればcookbook_fileリソースを使用する。

```ruby:recipes/default.rb
template "httpd.conf" do
  path "/etc/htttpd/conf/httpd.conf"
  owner "root"
  group "root"
  mode 0644
  notifies :reload, 'service[httpd]'
end
```

#### ブロック内で使用するメソッド
##### path
テンプレートの配置先。
pathの記述を省略した場合は、templateメソッドの引数に指定したパスに配置される。
##### source
配布元のテンプレートファイルの指定。
templates/default配下のファイルであれば、パスは不要でファイル名のみ指定すればよい。
sourceの記述を省略した場合は、templateメソッドの引数に指定したファイルをtemplates/defaultの下に探しに行く。
#### owner
ファイルのオーナー指定。
#### group
ファイルのグループ指定。
#### mode
ファイルのパーミッション指定。
#### notifies
テンプレートの配置をトリガーとして、別リソースのアクションを実行することができる。

例えば上記のサンプルの場合、テンプレートの配置後にhttpdサービスのリロードを行うという意味になる。
httpdのレシピには、"supports reload: true"の記述が必要な点に注意。

#### subscribe
他の特定のリソースのアクションが実行された場合に、指定したアクションを実行する。


## userリソース
引数にユーザー名を記述する。

```ruby:recipes/default.rb
user 'td-agenr' do
  comment  'td-agent'
  uid      403
  group    'td-agent'
  home     '/var/run/td-agent'
  shell    'bin/false'
  password nil
  supports manage_home: true
  action   [:create, :manage]
end
```

#### ブロック内で使用するメソッド
##### comment
コメントの指定。
##### uid
uidの指定。
##### group
グループの指定。
##### home
ホームディレクトリの指定。
##### shell
ユーザーが使用するシェルの指定。
##### password
パスワードの指定。
##### supports
:manage_home - 値にtrueを指定するとユーザー作成時にホームディレクトリの作成を行う。
##### action
:create - ユーザーを作成する。
:remove - ユーザーを削除する。
:modify - ユーザー情報を修正する。修正対象のユーザーが存在しないと例外が発生する。
:manage - 同名のユーザー存在した場合は既存のユーザーを管理対象とする。

## groupリソース
引数にグループ名を記述する。

```ruby:recipes/default.rb
group 'td-agent' do
  group_name 'td-agent'
  gid        403
  action     :create
end
```

#### ブロック内で使用するメソッド
##### group_name
グループ名の指定。

##### gid
gidの指定。
##### members
配列形式で、グループに所属させるユーザを文字列で指定する。
##### append
trueを指定すると、membersに含まれるユーザが追加され、excluded_membersに含まれるユーザは削除される。
falseを指定すると、グループメンバーはmembersに含まれるユーザでリセットされる。
デフォルトはfalse。
##### excluded_members
appendがtrueの場合にのみ設定する意味があり、グループから除外するユーザーを配列で指定する。
##### action
:create - グループの作成
:modify - グループの情報や、ユーザーの所属を修正する。

## directoryリソース
引数に管理対象のパスを記述する。

```ruby:recipes/default.rb
directory '/etc/td-agent/' do
  owner  'td-agent'
  group  'td-agent'
  mode   '0755'
  action :create
end
```

#### ブロック内で使用するメソッド
##### owner
ディレクトリのオーナー指定。
##### group
ディレクトリのグループ指定。
##### mode
ディレクトリのパーミッション指定。
##### action
:create - ディレクトリがなければ作成する。
:delete - ディレクトリを削除する。
##### source
配布元のテンプレートファイルのパスを指定する。
sourceメソッドの記述がない場合は、"templates/default"配下にdirectorメソッドの引数に指定したファイルを探しに行く。

## cookbook_fileリソース
静的なファイルを配置する際に使用するリソース。
引数に配置先のパスを指定する。	
下記の例ではテンポラリのパス指定にChefが設定で持っているパスを使用している。

```ruby:recipes/default.rb
cookbook_file "#{Chef::Config[:file_cache_path]}/supervisor-xxx.rpm" do
  mode 0644
end
```

#### ブロック内で使用するメソッド
##### source
転送元のファイルを明示的に指定する。
省略した場合は、cookbook_fileメソッドの引数のファイルをfiles/default配下に探しに行く。
##### mode
配置するファイルのパーミッションを指定。
##### owner
ファイルのオーナーを指定。
##### group
ファイルのグループを指定。
##### path
ファイルの配置先パスを指定。
##### checksum
ファイル転送の際、指定したチェックサムを利用してファイルの検証を行う。
引数にチェックサムの文字列を記述する。
なお、チェックサムが合致しない場合はエラーとなる。

ファイルからチェックサムを生成するコマンドは以下の通り。

```bash:Command
shasum -a 256 <配布するファイル>
```

## ifconfigリソース
ネットワークインターフェースを定義するリソース。
引数にIPアドレスを記述する。

```ruby:recipes/default.rb
ifconfig "192.168.30.1" do
    device "eth0"
end
```

#### ブロック内で使用するメソッド
##### device
インターフェースのデバイス名を指定。

## mountリソース
ディスクのマウントポイントを定義するリソース。
引数にマウントポイントを記述する。

```ruby:recipes/default.rb
mount "/mnt/volume1" do
  device "volume1"
  devicetype :label
  fstype "xfs"
  options "rw"
end
```

#### ブロック内で使用するメソッド
##### device
マウントするデバイスを指定。
##### devicetype
デバイスタイプを指定。
##### fstype
ファイルシステムのタイプを指定。
##### options
その他、マウントに関するオプションを指定。

## scriptリソース
特定のスクリプト言語を実行するためのリソース。
使用できるスクリプト言語として、bash、csh、perl、python、rubyがある。

メソッドとして使用する言語を記述する。
引数には、任意の処理名を記述する。

```ruby:recipes/default.rb
bash "install perlbrew" do
  user 'vagrant'
  group 'vagrant'
  cwd '/home/vagrant'
  environment "HOME" => '/home/vagrant'
  code <<-EOC
    curl -kL http://install.perlbrew.pl | bash
  EOC
  creates "/home/vagrant/perl5/perlbrew/bin/perlbrew"
end
```

#### ブロック内で使用するメソッド
##### user
スクリプト実行時のユーザを指定。
##### group
スクリプト実行時のグループを指定。
##### cwd
スクリプト実行時のワーキングディレクトリを指定。
##### environment
スクリプト実行時に使用する環境変数をハッシュ形式で指定。
##### code
スクリプトの内容を文字列で指定。
##### creates
ファイルのパスを指定して、プロビジョニング対象にそのファイルが存在していたらスクリプトを実行を行わないようにする。
プロビジョニングの度に繰り返し実行されるのを防ぐために使用される。
##### not_if
指定したブロックの処理を行い、戻り値がtrueでない場合にスクリプトを実行する。
ブロックの処理はbashやRubyで記述する。
bashの場合は終了ステータスで判定される。
##### only_if
指定したブロックの処理を行い、戻り値がtrueの場合のみスクリプトを実行する。
ブロックの処理はbashやRubyで記述する。
bashの場合は終了ステータスで判定される。

## gitリソース
gitリポジトリからファイルを取得するためのリソース。
引数には、取得したファイルを配置するパスを文字列で記述する。

```ruby:recipes/default.rb
git "/home/vagrant/.oh-my-zsh" do
  repository "git://github.com/robbyrussell/oh-my-zsh.git"
  reference "master"
  action :checkout
  user "vagrant"
  group "vagrant"
end
```

#### ブロック内で使用するメソッド
##### repository
gitリポジトリの指定。
##### reference
ブランチの指定。
##### action
:checkout - 初回のリボジトリ取得のみを行う。
:sync - こちらは初回のリポジトリ取得だけでなく、毎回実行時に更新も行う。
##### user
チェックアウトしたファイルのユーザーの指定。
##### group
チェックアウトしたファイルのグループの指定。

## gem_package
gemのパッケージを管理するリソース。
引数にgemの名前を指定する。

```ruby:recipes/default.rb
gem_package "rake" do
  action :install
end
```

#### ブロック内で使用するメソッド
##### action
:install - gemパッケージのインストールを行う。
##### version
文字列でgemのバージョンを指定する。
##### gem_binary
利用するgemコマンドのパスを文字列で指定する。

## ログ

### ログ出力
logメソッドによってレシピの実行時にログメッセージが表示される。

```ruby:Ruby
log <文字列>
```

# レシピでAttributeを使用する
レシピやテンプレートでは、Attributeと呼ばれるサーバー環境の情報を参照することが出来、環境に応じて処理を分岐させるといったことができる。

Attributeの情報を参照するには、nodeという名前のハッシュに参照したい情報のキーを指定する。

```ruby:recipes/default.rb
node['<キー名>']
```

取得できる情報になにがあるかを確認する場合は、ohaiコマンドを実行すると表示されるハッシュ形式の情報を確認する。

```bash:Command
ohai
```