初期知識
- コーディング規約は Ruby コーディング規準 に準拠する
- デフォルトのactionはcreateです。それ以外の操作がしたい場合はactionを記述しましょう
- コメントアウトでどういう動作をしてるか、resource毎に日本語で書きましょう。
- fileやtemplate、user、group resourceなどは、resourceブロックの名前に書く事で、
path(実際に配置するpath)や、group_name部分を省略してます。
(例)file '/tmp/hogehoge.txt' do ・・・/tmp/hogehoge.txtを配置 - 定数、分岐はなるべく少なくしましょう。
- environments, roleを有効活用しましょう
①bash : スクリプトを打ちたいとき、git cloneしたいとき
- bash, execute, scriptなど色々有りますが、どれもやってることはほぼ同じなのでbashに統一します。
- scriptだと、スクリプトがtypoしてたり間違ってたら止まっちゃいます。くらい
### /tmp/hogeにhogehogeと書き込む
bash 'write to /tmp/hoge' do
code <<-EOS
echo "hogehoge" >> /tmp/hoge
EOS
end
②bash or package : yum操作をするとき
- package resourceを使う方法もありますが、色々とエラーが出てしまう場合が多いので、bashでやるのがおすすめです。(一応packageの方法も乗せます)
- yumコマンドのinstallはupdateもするが、
package resourceのupgradeは、既にパッケージがインストールされてないとupdateはしない。
しかもupgradeで読みにいったファイルが、インストールされてる物より古かった場合、下記のようなエラーを吐いて処理が止まる
「Installed package prelink-0.4.6-3.1.el6_4 is newer than candidate package prelink-0.4.6-3.el6」 - package resourceのinstall➡installのみ。upgradeはしない
- package resourceのupgrade➡installもupgradeもする
- packageが多い場合はattributeディレクトリで管理するのがおすすめです。
### symlinksとprelink packageのインストール + アップデート
%w(symlinks prelink).each.do |package|
bash 'install #{package}' do
code <<-EOS
yum -y install #{package}
EOS
end
end
### symlinksとprelink packageのインストール + アップデート
### パッケージ名の部分は12.1以降の記述方法です。それ以前のバージョンであれば、パッケージはeach doで回しましょう。
package 'install package' do
package_name [
'symlinks',
'prelink'
]
options "--disablerepo=* --enablerepo=base,epel"
action :upgrade
end
③gem_package : gemパッケージをインストールしたいとき
### ruby2.2.1のrakeとbundlerをインストール
%w(rake bundler).each do |package|
gem_package "#{package}" do
gem_binary '/usr/local/bin/gem'
version '2.2.1'
action :install
end
end
# %w・・・,(コンマ)や' "(クォート)を使わずに配列を作るrubyの記法
④file, directory : 空ファイル、空ディレクトリを作成、パーミッション変更したいとき
- file : 空ファイルを作成、パーミッション変更
- directory : 空ディレクトリ作成、パーミッション変更。recursiveで再帰的に作成も出来る。
が、再帰的にパーミッションは変更出来ないので注意。対象がファイルでもパーミッション変更されます。
### /tmp/hoge.txtを作成
file '/tmp/hoge.txt' do
owner 'root'
group 'root'
mode '0644'
end
# action :deleteを使うと、ファイルが削除出来るが、
# 削除対象がシンボリックリンクの場合は警告が出るので、link resourceを使うのがベスト。
### /tmp/hoge/fugaを作成
directory '/tmp/hoge/fuga' do
owner 'root'
group 'root'
mode '0644'
recursive true
end
⑤template, cookbook_file, remote_directory :
cookbook内のファイル、ディレクトリを配置したいとき
- template、cookbook_file、remote_directoryを使い分けましょう。
①template : ファイル内に変数を置いたり、配置する際に書き込みできる。
なので、配置する際に中身を読み込んでしまう。
圧縮ファイルやバイナリ、ディレクトリ以外は基本ココに置きましょう。
erb記述のファイルも扱えます。
②cookbook_file : 配置する際に中身は読み込まない。圧縮ファイルとか、rpmファイルとか、バイナリファイルなど置くと良い。
③remote_directory : files/default/のディレクトリとその中のファイルを配置。またファイルに対して必要なパーミッションを付与出来る - 上書きが困る場合はaction: create_if_missing や not_if {File.exist?} などを使いましょう
### templateディレクトリのhogehoge_producrtion.txtを/tmp/hogehoge.txtとして配置する
template '/tmp/hogehoge.txt' do
source 'hogehoge_producrtion.txt'
owner 'root'
group 'root'
mode '0644'
end
### filesからrpmを配置する
### files/default/hogehoge.el6.x86_64.rpmを配置しておく。
cookbook_file '/tmp/hogehoge.el6.x86_64.rpm' do
source 'hogehoge.el6.x86_64.rpm'
owner 'root'
group 'root'
mode '0644'
end
### filesから/etc/httpd/conf.dディレクトリを配置する。またその中のファイルのパーミッションを変更する
### files/default/plugins/....を配置しておく。
remote_directory '/etc/httpd/conf.d' do
source 'conf.d'
files_owner 'apache'
files_group 'apache'
files_mode '0755'
owner 'apache'
group 'apache'
mode '0755'
recursive true
action :create
end
# files_ownerでファイルのパーミッション変更、ownerでディレクトリの変更
⑥remote_file : 外部からファイルをダウンロードしたいとき
### http://hoge.example.com/fugafuga.rpmをダウンロードし、/tmp/fugafuga.rpmに配置
remote_file '/tmp/fugafuga.rpm' do
source 'http://hoge.example.com/fugafuga.rpm'
owner 'root'
group 'root'
mode '0644'
end
⑦data_bags : ユーザを作成
### ユーザを定義
$ data_bags/users/alice.json
// alice
{
"id": "alice",
"uid": "1234",
"gid": "alice"
"shell": "/bin/bash",
"password": "password"
}
### ⑧ユーザ作成
$ vim site-cookbooks/hoge/recipes/default.rb
data_bag('users').each do |id|
u = data_bag_item('users', id)
user u['id'] do
shell u['shell']
uid u['uid']
gid u['gid']
password u['password']
supports :manage_home => true, :non_unique => false
action [:create]
end
end
⑧user : ユーザの作成、変更をしたいとき
- ユーザ管理は出来る限りdata_bagsで管理しましょう〜。
### hogeユーザ作成
user 'hoge' do
uid 1234
gid 'hoge'
home '/home/hoge'
supports :manage_home => true
password 'passworddayo'
end
# supports :manage_home => trueは、ホームディレクトリを作成するオプション
⑨group : グループの作成、変更をしたいとき
### apache groupを作成して、"hoge"と"fuga"ユーザを所属させる
group 'apache' do
gid 48
members ['hoge', 'fuga']
append true
action :modify
end
# append trueにすると、追加するユーザだけ記述すればいい。
# append falseにすれば、apacheに属しているユーザを全て書かなければならない。
# 新しくgroupを作りたい場合はデフォルトのcreateです。
⑩service : サービスの起動、停止、再起動をしたいとき
### httpdの起動 + chkconfig on を実施
service 'start httpd add chkconfig on' do
service_name 'httpd'
action [:enable, :start]
end
# actionは複数じゃなければ、[]はいらないが、文言統一のために毎回[]でくくった方が良い
# supports status: true, restart: true, reload: true を指定すると、httpdではこのコマンドが使えるよ!と教えて上げれる。使う場合は記述しましょう。
# restart => trueを指定しない場合、stop + start で代用される
# ignore_failure true を指定すると、エラーは無視します。
### Action 説明
# :enable ブート時の起動を有効化
# :disable ブート時の起動を無効化
# :nothing 何もしない(default)
# :start サービスを起動
# :stop サービスを停止
# :restart サービスを再起動
# :reload
### virtualhosts.confを作成した後、httpdを再起動する。service resourceは先に書いても、後に書いてもどちらでも動く
template '/etc/httpd/conf.d/virtualhosts.conf' do
source 'virtualhosts.conf'
owner 'root'
group 'root'
mode '0644'
notifies :restart, 'service[httpd]', :immediately
end
service 'httpd' do
action [ :nothing ]
end
# notifies:該当のResourceが実行された際、他のResourceに通知してそのResourceの実行を促す。複数行記述することができる。
# subscriibes:notifiesと逆で、他のResourceの実行終了後に該当ResourceのActionを指定して実行する。
⑪link : シンボリックリンク、ハードリンクを貼る
### /tmp/passwdに/etc/passwdを参照するシンボリックリンクを作成
link '/tmp/passwd' do
to '/etc/passwd'
end
# link_type :hard を指定するとハードリンクが貼られる。:symbolicだとシンボリックリンク。
# ハードリンクってあまり使わないので、基本シンボリックリンクだと思います。
# なので、link_typeは明示的に書かなくても良いでしょう。
⑫文字列置換したいとき
### /tmp/hoge.txtに書かれてるeth0をeth1に変更
file '/tmp/hoge.txt' do
f = Chef::Util::FileEdit.new(path)
f.searchfile_replace_line('eth0', 'eth10')
content f.send(:editor).lines.join
end
⑬only_ifとnot_ifの違い
- not_if : 既にファイルが存在している場合コマンドを実行しない
- only_if : 既にファイルが存在している場合コマンドを実行する
- デフォルトはファイル上書き
### only_ifの例
# file が存在し、シンボリックリンクであれば、削除を実行する。
link "/tmp/mylink" do
action :delete
only_if "test -L /tmp/mylink"
end
# /var/lib/mysqlが存在した場合、/tmp/hoge.txtを作成する
file '/tmp/hoge.txt' do
owner 'root'
group 'root'
mode '0644'
only_if {Dir.exist?("/var/lib/mysql")}
end
### not_ifの例
# /tmp/hogeが存在した場合、書き込まない
bash "fugaaa" do
code <<-EOS
echo "fugaaaaa" >> /tmp/hoge
EOS
not_if { File.exist?('/tmp/hoge') }
end
⑭attributeについて
- attributeに値を定義することができます。こんな感じに。(それぞれの書き方は公式のexampleを見ると良いでしょう。https://docs.chef.io/attributes.html)
### 定義
$ vim site-cookbooks/hogehoge/attributes/default.rb
# インストールしたいrpmパッケージを定義
default['rpm_package'] = %w(
httpd
httpd-devel
)
### environmentなどはjson形式で定義
$ vim environments/development.json
# hoge = development dayoと定義
"default_attributes": {
"hoge": "development dayo"
}
### recipeで実際に使う
$ vim site-cookbooks/hogehoge/recipes/default.rb
# rpmをインストール
node['rpm_package'].each do |package|
bash "install #{package}" do
code <<-EOS
yum -y install #{package}
EOS
end
end
# ⑮ohaiで取得した、対象サーバのipアドレス。その名前をファイル名として、/tmp/配下にファイル作成
file "/tmp/#{node['ipaddress']}" do
owner 'root'
group 'root'
mode '0644'
end
### erb形式など
$ vim site-cookbooks/hogehoge/templates/default/test.txt
# development dayoと書く
<%= node['hoge'] %>
- 優先順位は弱い順に下記。どんどん上書きされて行きます。
①recipes/attribute/
②recipes/default/
③environments/
④roles/
⑤nodes/
- Attributeの強さは弱い順に下記。同じく上書きされて行きます。
①default
②force_default
③normal
④override
⑤force_override
⑥automatic
- ルールを作って運用するのが一番。自分は下記でやってます。
- なるべく変数、定数を使わないように構成する。
- defaultとoverrideのみ使います。
①recipes/attribute/:インストールするパッケージ一覧や、rubyのバージョンなどのような変動が多い部分。
また③④のjson形式で解消出来ない部分。
②recipes/default/:使わない
③environments/:development(開発)、production(本番)でのサーバ収容先、またはネットワーク差異の分岐。
④roles/:基本構成、AP(apache用)、AP(nginx用)、DBサーバの分岐。
⑤nodes/:使わない
⑮environmentsの情報を取ってくる
### もしenvironmentsがproductionだったら・・・
### もしenvironmentsがdevelopmentだったら・・・
if node.chef_environment == "production"
・・・・
elsif node.chef_environment == "development"
・・・・
end
⑯ohai便利
- ohaiはchefが実行環境の情報を取得するためのライブラリです。
- ohai | lessなどで、取って来れる情報がJSON形式で出力されます。
- #{node['ipaddress']}で、IPが取ってこれたり、
- #{node['virtualization']['system']}で、kvmかopenstackかを取ってこれたりします。
### CPUが1コアの場合、1coreと記述、1コアじゃない場合は、not 1coreと記述。
bash "hoge" do
if node['cpu']['total'] == 1
code <<-EOS
echo "1core" >> /tmp/hoge
EOS
else
code <<-EOS
echo "not 1core" >> /tmp/hoge
EOS
end
end
chefエラー対応
ERROR: Cookbook repository not found.とエラーが出たら
- キッチン(リポジトリ)のトップディレクトリにいって、$ knife solo init .を実行する
ERROR: Net::SSH::HostKeyMismatch: fingerprint 0c:82:e9:23:22:6b:b0:73:f6:06:cb:e6:55:49:7a:0a does not match for "10.26.2.19"
の場合は、known_hostsで対象行を消しましょう
- エラー見たら分かるかと思います。
chef豆知識編
cookbook名に .(ドット)は使えません
下記は同じ動き
- %w{test test2 test3}
- ['test', 'test2', 'test3']
chef 12から cookbookのmetadata.rb内のname attributeの記述が必須になった
- metadata.rbのnameを、cookbook名にすればOK
rubocopで整形しましょう
$ gem install rubocop --no-ri --no-rdocで、インストールして、$ rubocop site-cookbooksで
- 整形すると綺麗になります
- warningやcriticalが出た部分は適宜修正しましょう
erbを使うときでもファイル名をerbにしなくても通ります。
resourceの使い回しは出来ます
### 当然と言えば当然ですが。こんな感じでもいけます。
service "httpd" do
action [:start]
end
service "httpd" do
action [:stop]
end
MySQL5.6を使ってる方は/usr/my.cnfを事前に作りましょう
- rpmでmysql5.6をインストールすると、その時点でmysql_install_dbが走ります。
- パスワードを設定する処理などが走りますので、/usr/my.cnfを事前に作っておきましょう
gitリソースを使って、cloneするときはenable_checkout falseをオプションに入れてあげましょう
- gitリソースを使うと、下記のように新しくdeployがbranchとして切られます。
- enable_checkout falseをオプションにつけるとdeployブランチが切られません。