「Chef」はChef Softwareが開発した製品で、2009年1月に最初のStable版がリリースされている。ライセンスはApache License Version 2.0で、現在の最新バージョンは2016年4月9日にリリースされたVer 12.9となっている。
Chefにはサーバ内部で構築を行う「Chef-solo」、リモートからnode上の「Chef-solo」を遠隔操作して構築を行う「Knife-solo」、大規模環境で集中管理を行うための「Chef-server」が提供されている。各製品の機能概要と使い分けについては、クリエーションラインの技術ブログ「あなたに合ったChefはどれ? 〜おすすめ構成確認チャート」に非常に詳しく記載されているので、こちらをご一読することをお勧めする。
今回の検証では、管理サーバからnodeに対して遠隔でのインストールを実施するため、Knife-soloを利用している。最新のChefをインストールするためには、Ruby 2.1以上が必要となる。CentOS 7.2の標準のリポジトリからインストールする場合、Ver 2.0.0でありインストールが行えないため、Rubyをソースからインストールすることになる。2016年4月現在、Rubyの最新バージョンは2.3.1だが、このバージョンを利用すると、インストール時、実行時に“`initialize': Object#timeout is deprecated, use Timeout.timeout instead.”のエラーメッセージが出力されてわずらわしいので、2.2系の最終版である2.2.4を選択している。(エラーが出力されるが、2.3系でも動作には支障はないようである)
$ sudo yum update -y
$ sudo yum install -y gcc zlib-devel openssl-devel sqlite sqlite-devel rsync
$ sudo su root -c "curl http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.4.tar.gz | tar zx -C /usr/local/src" $ sudo chown -R root:root /usr/local/src/ruby-2.2.4 $ cd /usr/local/src/ruby-2.2.4 $ sudo ./configure $ sudo make $ sudo make install $ which ruby /usr/local/bin/ruby $ /usr/local/bin/ruby --version ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-linux]
$ sudo /usr/local/bin/gem i chef --no-ri --no-rdoc
コマンド入力後の各設定は基本的に何も入力せずに行う形で問題ない。
$ cd ~ $ /usr/local/bin/knife configure WARNING: No knife configuration file found Where should I put the config file? [/home/maintain/.chef/knife.rb] Please enter the chef server URL: [https://tissvv097:443] Please enter an existing username or clientname for the API: [maintain] Please enter the validation clientname: [chef-validator] Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem] Please enter the path to a chef repository (or leave blank): ***** You must place your client key in: /home/maintain/.chef/maintain.pem Before running commands with Knife ***** You must place your validation key in: /etc/chef-server/chef-validator.pem Before generating instance data with Knife ***** Configuration file written to /home/maintain/.chef/knife.rb
$ sudo /usr/local/bin/gem i knife-solo --no-ri --no-rdoc
$ /usr/local/bin/knife solo init chef-repo $ ls -d1 ./chef-repo/* ./chef-repo/cookbooks ./chef-repo/data_bags ./chef-repo/environments ./chef-repo/nodes ./chef-repo/roles ./chef-repo/site-cookbooks
$ ssh -i ~/.ssh/id_rsa.pem tissvv096 $ exit
コマンドを実行すると、node側にchef-soloがインストールされ、ローカルの./chef-repo/node以下にnodeの設定を登録するjsonファイルが作成される。
$ cd ~/chef-repo
$ knife solo prepare -i ~/.ssh/id_rsa.pem tissvv096
Bootstrapping Chef...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 19602 100 19602 0 0 20929 0 --:--:-- --:--:-- --:--:-- 20919
el 7 x86_64
Getting information for chef stable 12.9.38 for el...
downloading https://omnitruck-direct.chef.io/stable/chef/metadata?v=12.9.38&p=el&pv=7&m=x86_64
to file /tmp/install.sh.4421/metadata.txt
trying curl...
sha1 5907edce1a3b0f7bd42359fe64960da8833385e9
sha256 1c3e680f106ab6829c3713307e447116f7bb3f2d9c30fd3943638b01d6246fe2
url https://packages.chef.io/stable/el/7/chef-12.9.38-1.el7.x86_64.rpm
version 12.9.38
downloaded metadata file looks valid...
downloading https://packages.chef.io/stable/el/7/chef-12.9.38-1.el7.x86_64.rpm
to file /tmp/install.sh.4421/chef-12.9.38-1.el7.x86_64.rpm
trying curl...
Comparing checksum with sha256sum...
Installing chef 12.9.38
installing with rpm...
警告: /tmp/install.sh.4421/chef-12.9.38-1.el7.x86_64.rpm: ヘッダー V4 DSA/SHA1 Signature、鍵 ID 83ef826a: NOKEY
準備しています... ################################# [100%]
更新中 / インストール中...
1:chef-12.9.38-1.el7 ################################# [100%]
Thank you for installing Chef!
Generating node config 'nodes/tissvv096.json'...
これでマネージャー、nodeサーバともにインストールが完了となり、./chef-repo以下でサーバ構築と設定を行うcookbockを作成、実行することが可能となる。
$ cd ~/chef-repo $ knife cookbook create wordpress_sample -o site-cookbooks ** Creating cookbook wordpress_sample in /root/chef-repo/site-cookbooks ** Creating README for cookbook: wordpress_sample ** Creating CHANGELOG for cookbook: wordpress_sample ** Creating metadata for cookbook: wordpress_sample
上記のコマンドを実行すると、site-cookbooksフォルダ内にcookbookを作成するために必要となるフォルダやファイルが作成される。
$ ls -1d ./ site-cookbooks/wordpress_sample/* site-cookbooks/wordpress_sample/CHANGELOG.md site-cookbooks/wordpress_sample/README.md site-cookbooks/wordpress_sample/attributes site-cookbooks/wordpress_sample/definitions site-cookbooks/wordpress_sample/files site-cookbooks/wordpress_sample/libraries site-cookbooks/wordpress_sample/metadata.rb site-cookbooks/wordpress_sample/providers site-cookbooks/wordpress_sample/recipes site-cookbooks/wordpress_sample/resources site-cookbooks/wordpress_sample/templates
作成したcookbookは以下となる。各処理のTIPSは後ほど機能ごとに説明する。
(1)cookbookとして作成するファイルおよびフォルダの構成
$ tree chef-repo/
chef-repo/
├── .chef
│ └── knife.rb
├── nodes
│ └── tissvv096.json
└── site-cookbooks
└── wordpress_sample
├── attributes
│ └── default.rb
├── recipes
│ ├── default.rb
└── templates
(2)recipe本体
実際にインストールや設定を行う処理を記述している。前述のシェルスクリプトと同一の処理を行う部分はコメントを一致させるようにしている。
$ vi ~/chef-repo/site-cookbooks/wordpress_sample/recipes/default.rb
#
# Cookbook Name:: wordpress_sample
# Parameter settings
hostname = node['hostinfo']['hostname']
mysql_root_pass = node['mariadb']['mysql_root_pass']
wordpress_latest = node['wordpress']['wordpress_latest']
wp_os_user = node['wordpress']['wp_os_user']
wp_os_group = node['wordpress']['wp_os_group']
wp_db_name = node['wordpress']['wp_db_name']
wp_db_user = node['wordpress']['wp_db_user']
wp_db_pass = node['wordpress']['wp_db_pass']
wp_uniqe_phrse = node['wordpress']['wp_uniqe_phrse']
# update packages
execute 'yum-update' do
user 'root'
command 'yum -y update'
action :run
end
# install packages
yum_package [ 'mariadb-server', 'httpd', 'php', 'php-mysql' ] do
action :install
end
# start/enable mariadb
service 'mariadb' do
supports :status => true, :restart => true, :reload => true
action [:start, :enable]
end
# set mariadb root password + restart mariadb
execute 'set mariadb root password' do
command <<-EOC
/usr/bin/rm -f /root/.my.cnf
mysql -u root -e "update mysql.user set password=password('#{mysql_root_pass}') where user = 'root'"
systemctl restart mariadb
EOC
onlyvariables({
:mysql_root_pass => mysql_root_pass
})
not_if { File.exists?('/root/.my.cnf') }
end
# mariadb logrotate setting
execute 'mariawp_db_logrotate' do
command <<-EOC
sed -i.bak -e '23,$ s/^#//' /etc/logrotate.d/mariadb
EOC
not_if { File.exists?('/etc/logrotate.d/mariadb.bak') }
end
# create wordpres db/user
bash 'create wordpres db/user' do
exists = <<-EOH
mysql -u root -p#{mysql_root_pass} -e 'show databases' | grep #{wp_db_name}
EOH
code <<-EOC
mysql -vvv -u root -p#{mysql_root_pass} -e "create user '#{wp_db_user}'@'localhost' identified by '#{wp_db_pass}'"
mysql -vvv -u root -p#{mysql_root_pass} -e "create database #{wp_db_name}"
mysql -vvv -u root -p#{mysql_root_pass} -e "grant all privileges on #{wp_db_name}.* to '#{wp_db_user}'@'localhost'"
mysql -vvv -u root -p#{mysql_root_pass} -e "flush privileges"
EOC
not_if exists
end
# install wordpress
execute 'install wordpress' do
command <<-EOC
curl #{wordpress_latest} | tar zx -C /var/www
EOC
not_if { File.exists?('/var/www/wordpress/index.php') }
end
# create wordpress config
bash 'create wordpress config' do
code <<-EOC
sed -e "s/\\(define.*'\\)database_name_here\\('.*\\)/\\1#{wp_db_name}\\2/" \
-e "s/\\(define.*'\\)username_here\\('.*\\)/\\1#{wp_db_user}\\2/" \
-e "s/\\(define.*'\\)password_here\\('.*\\)/\\1#{wp_db_pass}\\2/" \
-e "s/\\(define.*'\\)put your unique phrase here\\('.*\\)/\\1#{wp_unique_phrase}\\2/" \
/var/www/wordpress/wp-config-sample.php > /var/www/wordpress/wp-config.php
EOC
not_if { File.exists?('/var/www/wordpress/wp-config.php') }
end
# chown wordpress files
execute 'chown wordpress files' do
command <<-EOC
chown -R #{wp_os_user}:#{wp_os_group} /var/www/wordpress
EOC
not_if "test `find /var/www/wordpress -not -user #{wp_os_user} -or -not -group #{wp_os_group} | wc -l` == 0"
end
# create wordpres httpd config
template '/etc/httpd/conf.d/wordpress.conf' do
owner 'root'
group 'root'
source 'wordpress.conf.erb'
variables({
:hostname => hostname
})
not_if { File.exists?('/etc/httpd/conf.d/wordpress.conf') }
end
# modify httpd config
execute 'httpd.conf' do
command <<-EOC
sed -i.bak -e 's/^#ServerName.*/ServerName #{hostname}/' /etc/httpd/conf/httpd.conf
EOC
not_if { File.exists?('/etc/httpd/conf/httpd.conf.bak') }
end
# start/enable httpd
service 'httpd' do
supports :status => true, :restart => true, :reload => true
action [:start, :enable]
end
# open httpd port in firewall
execute 'open httpd port in firewall' do
command <<-EOC
firewall-cmd --add-service=http --zone=public --permanent
firewall-cmd --reload
EOC
only_if "test `firewall-cmd --list-service --zone=public | grep -c http` == 0"
end
(3)変数のdefault値の定義ファイル
recipe内で使用する変数のdefault値を定義する。
$ vi ~/chef-repo/site-cookbooks/wordpress_sample/attributes/default.rb
# Paramaters default default['hostinfo']['hostname'] = "localhost" default['mariadb']['mysql_root_pass'] = "password" default['wordpress']['wordpress_latest'] = "https://wordpress.org/latest.tar.gz" default['wordpress']['wp_os_user'] = "root" default['wordpress']['wp_os_group'] = "root" default['wordpress']['wp_db_name'] = "wordpress" default['wordpress']['wp_db_user'] = "wordpress" default['wordpress']['wp_db_pass'] = "password" default['wordpress']['wp_unique_phrase'] = "bMvc7W2eLuhKFewafVyirWJaXDhbSf"
(4)/etc/httpd/conf.d/wordpress.confのtemplateファイル
$ vi ~/chef-repo/site-cookbooks/wordpress_sample/templates/wordpress.conf.erb
<VirtualHost *:80>
ServerName <%= @hostname %>;
DocumentRoot /var/www/wordpress
<Directory "/var/www/wordpress">
AllowOverride All
Options -Indexes
</Directory>
<Files wp-config.php>
order allow,deny
deny from all
</Files>
</VirtualHost>
(5)/root/.my.cnfのtemplateファイル
$ vi ~/chef-repo/site-cookbooks/wordpress_sample/templates/my.cnf.erb
[client] user = root password = "<%= @mysql_root_pass %>" [mysqladmin] user = root password = "<%= @mysql_root_pass %>"
(6)nodeの設定に使用するrecipeとパラメータの定義ファイル
$ vi ~/chef-repo/nodes/tissvv096.json
{
"run_list": [
"wordpress_sample"
],
"mariadb" : {
"mysql_root_pass" : "FM11AD2+"
},
"wordpress" : {
"wordpress_latest" : "https://ja.wordpress.org/latest-ja.tar.gz",
"wp_os_user" : "root",
"wp_os_group" : "root",
"wp_db_name" : "WordPress",
"wp_db_user" : "wp_admin",
"wp_db_pass" : "HB-F1XDJ",
"wp_unique_phrase" : "FX702PFX801PPB100FX860PPB700PB500PB750PAI1000"
},
"hostinfo" : {
"hostname" : "tissvv096"
},
"automatic": {
"ipaddress": "10.255.202.96"
}
}
knife soloコマンドでcookbookを実行することになるが、最後に“--noop”オプションを付けると実行せずに、構文チェックのみが行われる。エラーが表示されなければ構文的には問題がない。
$ cd ~/chef-repo $ knife solo cook -i ~/.ssh/id_rsa.pem tissvv096 --why-run
knifeコマンドは実行時のディレクトリ直下の.chef/knife.rbを参照して処理を実行する。chef-repoフォルダ以外で実行すると、cookbookの参照が行えず、処理が正常に行えない状態となる。
コマンドを実行すると、node/[hostname].jsonに指定されたcookbookが実行される。
$ cd ~/chef-repo $ knife solo cook -i ~/.ssh/id_rsa.pem tissvv096
コマンドを実行すると、以下のログが出力され、nodeサーバの設定が行われる。
Running Chef on tissvv096...
Checking Chef version...
Uploading the kitchen...
Generating solo config...
Running Chef: sudo chef-solo -c ~/chef-solo/solo.rb -j ~/chef-solo/dna.json
Starting Chef Client, version 12.9.38
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 14 resources
Recipe: wordpress_sample::default
* execute[yum-update] action run
- execute yum -y update
* yum_package[mariadb-server, httpd, php, php-mysql] action install
- install version 5.5.47-1.el7_2 of package mariadb-server
- install version 2.4.6-40.el7.centos of package httpd
- install version 5.4.16-36.el7_1 of package php
- install version 5.4.16-36.el7_1 of package php-mysql
* service[mariadb] action start
- start service service[mariadb]
* service[mariadb] action enable
- enable service service[mariadb]
* execute[set mariadb root password] action run
- execute /usr/bin/rm -f /root/.my.cnf
mysql -u root -e "update mysql.user set password=password('FM11AD2+') where user = 'root'"
systemctl restart mariadb
* template[/root/.my.cnf] action create
- create new file /root/.my.cnf
- update content in file /root/.my.cnf from none to 8b2970
--- /root/.my.cnf 2016-05-07 13:30:05.447532208 +0900
+++ /root/.chef-.my.cnf20160507-2763-pjob7n 2016-05-07 13:30:05.447532208 +0900
@@ -1 +1,8 @@
+[client]
+user = root
+password = "FM11AD2+"
+
+[mysqladmin]
+user = root
+password = "FM11AD2+"
- change mode from '' to '0600'
- change owner from '' to 'root'
- change group from '' to 'root'
* execute[mariawp_db_logrotate] action run
- execute sed -i.bak -e '23,$ s/^#//' /etc/logrotate.d/mariadb
* bash[create wordpres db/user] action run
- execute "bash" "/tmp/chef-script20160507-2763-1df3arv"
* execute[install wordpress] action run
- execute curl https://ja.wordpress.org/latest-ja.tar.gz | tar zx -C /var/www
* bash[create wordpress config] action run
- execute "bash" "/tmp/chef-script20160507-2763-kw4xvg"
* execute[chown wordpress files] action run
- execute chown -R root:root /var/www/wordpress
* template[/etc/httpd/conf.d/wordpress.conf] action create
- create new file /etc/httpd/conf.d/wordpress.conf
- update content in file /etc/httpd/conf.d/wordpress.conf from none to 127163
--- /etc/httpd/conf.d/wordpress.conf 2016-05-07 13:30:08.358562342 +0900
+++ /etc/httpd/conf.d/.chef-wordpress.conf20160507-2763-1p7qqgk 2016-05-07 13:30:08.358562342 +0900
@@ -1 +1,14 @@
+<VirtualHost *:80>
+ ServerName tissvv096;
+ DocumentRoot /var/www/wordpress
+ <Directory "/var/www/wordpress">
+ AllowOverride All
+ Options -Indexes
+ </Directory>
+
+ <Files wp-config.php>
+ order allow,deny
+ deny from all
+ </Files>
+</VirtualHost>
- change owner from '' to 'root'
- change group from '' to 'root'
* execute[httpd.conf] action run
- execute sed -i.bak -e 's/^#ServerName.*/ServerName tissvv096/' /etc/httpd/conf/httpd.conf
* service[httpd] action start
- start service service[httpd]
* service[httpd] action enable
- enable service service[httpd]
* execute[open httpd port in firewall] action run
- execute firewall-cmd --add-service=http --zone=public --permanent
firewall-cmd --reload
Running handlers:
Running handlers complete
Chef Client finished, 16/16 resources updated in 26 seconds
Running Chef on tissvv096...
Checking Chef version...
Uploading the kitchen...
Generating solo config...
Running Chef: sudo chef-solo -c ~/chef-solo/solo.rb -j ~/chef-solo/dna.json
Starting Chef Client, version 12.9.38
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 14 resources
Recipe: wordpress_sample::default
* execute[yum-update] action run
- execute yum -y update
* yum_package[mariadb-server, httpd, php, php-mysql] action install (up to date)
* service[mariadb] action start (up to date)
* service[mariadb] action enable (up to date)
* execute[set mariadb root password] action run (skipped due to only_if)
* template[/root/.my.cnf] action create (skipped due to not_if)
* execute[mariawp_db_logrotate] action run (skipped due to not_if)
* bash[create wordpres db/user] action run (skipped due to not_if)
* execute[install wordpress] action run (skipped due to not_if)
* bash[create wordpress config] action run (skipped due to not_if)
* execute[chown wordpress files] action run (skipped due to not_if)
* template[/etc/httpd/conf.d/wordpress.conf] action create (skipped due to not_if)
* execute[httpd.conf] action run (skipped due to not_if)
* service[httpd] action start (up to date)
* service[httpd] action enable (up to date)
* execute[open httpd port in firewall] action run (skipped due to only_if)
Running handlers:
Running handlers complete
Chef Client finished, 1/16 resources updated in 07 seconds
Copyright © ITmedia, Inc. All Rights Reserved.