はじめに
前回の記事では、Chef環境の構築から仮想マシンの基本設定を行うレシピの実行までを解説しました。今回は、LAMP環境を構築するレシピを作成し、プロビジョニングを行う方法を解説します。
構築前の準備
今回構築するLAMP環境は、LAMP開発環境の構築方法~LAMP環境構築編と同様です。
また、Chefプロビジョニングで使用するサーバー設定ファイルを、LAMP環境構築編で作成したサーバーからローカルにコピーします。
$ cd ~/vagrant/lamp $ vagrant up $ vagrant ssh $ cp /etc/httpd/conf/httpd.conf /vagrant $ cp /etc/php.ini /vagrant $ cp /etc/my.cnf /vagrant
$ cd ~/vagrant/lamp $ vagrant up Bringing machine 'default' up with 'virtualbox' provider... [default] Clearing any previously set forwarded ports... [default] Clearing any previously set network interfaces... [default] Preparing network interfaces based on configuration... [default] Forwarding ports... [default] -- 22 => 2222 (adapter 1) [default] Booting VM... [default] Waiting for machine to boot. This may take a few minutes... DL is deprecated, please use Fiddle [default] Machine booted and ready! [default] Configuring and enabling network interfaces... [default] Mounting shared folders... [default] -- /vagrant [default] VM already provisioned. Run `vagrant provision` or use `--provision` to force it $ vagrant ssh Last login: Thu Jan 16 15:30:31 2014 from 10.0.2.2 [vagrant@lamp ~]$ cp /etc/httpd/conf/httpd.conf /vagrant [vagrant@lamp ~]$ cp /etc/php.ini /vagrant [vagrant@lamp ~]$ cp /etc/my.cnf /vagrant [vagrant@lamp ~]$
リポジトリのインストール
サードパーティリポジトリをインストールするCookbookを作成します。
- レシピの指定
Vagrantfileを下記のとおり編集します。
実行するレシピを追加しています。$ vi Vagrantfile
chef.add_recipe "repo"
- Repo Cookbookの作成
Repo Cookbookを作成します。
$ knife cookbook create repo -o site-cookbooks
$ knife cookbook create repo -o site-cookbooks ** Creating cookbook repo ** Creating README for cookbook: repo ** Creating CHANGELOG for cookbook: repo ** Creating metadata for cookbook: repo
- 属性の設定
サードパーティリポジトリをダウンロードするサイトなどの設定を、Cookbookのattributeとして設定します
$ vi site-cookbooks/repo/attributes/default.rb
# EPEL default['epel']['file_name'] = "epel-release-6-8.noarch.rpm" default['epel']['remote_uri'] = "ftp://ftp.kddilabs.jp/Linux/distributions/fedora/epel/6/i386/epel-release-6-8.noarch.rpm" # remi default['remi']['file_name'] = "remi-release-6.rpm" default['remi']['remote_uri'] = "http://rpms.famillecollet.com/enterprise/remi-release-6.rpm" # RPMForge default['rpmforge']['file_name'] = "rpmforge-release-0.5.3-1.el6.rf.i686.rpm" default['rpmforge']['remote_uri'] = "http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.i686.rpm"
- レシピの作成
attributeで指定したリポジトリを参照して、リモートサイトからダウンロードしインストールするレシピを作成します。
$ vi site-cookbooks/repo/recipes/default.rb
# EPELリポジトリのインストール remote_file "/tmp/#{node['epel']['file_name']}" do source "#{node['epel']['remote_uri']}" not_if { ::File.exists?("/tmp/#{node['epel']['file_name']}") } end package node['epel']['file_name'] do action :install provider Chef::Provider::Package::Rpm source "/tmp/#{node['epel']['file_name']}" not_if "yum list installed | grep installed | grep -q epel" end # remiリポジトリのインストール remote_file "/tmp/#{node['remi']['file_name']}" do source "#{node['remi']['remote_uri']}" not_if { ::File.exists?("/tmp/#{node['remi']['file_name']}") } end package node['remi']['file_name'] do action :install provider Chef::Provider::Package::Rpm source "/tmp/#{node['remi']['file_name']}" not_if "yum list installed | grep installed | grep -q remi" end # RPMForgeリポジトリのインストール remote_file "/tmp/#{node['rpmforge']['file_name']}" do source "#{node['rpmforge']['remote_uri']}" not_if { ::File.exists?("/tmp/#{node['rpmforge']['file_name']}") } end package node['rpmforge']['file_name'] do action :install provider Chef::Provider::Package::Rpm source "/tmp/#{node['rpmforge']['file_name']}" not_if "yum list installed | grep installed | grep -q rpmforge" end # リポジトリの設定変更 bash 'repo' do user 'root' code <<-EOC cd /etc/yum.repos.d for r in epel.repo remi.repo rpmforge.repo; do cp -p $r $r.old; cat $r.old | sed 's/^enabled.*$/enabled = 0/' > $r; done EOC not_if "grep -q 'enabled = 0' /etc/yum.repos.d/epel.repo" end
- レシピの実行
レシピが作成できましたので、プロビジョニングを行います。
$ vagrant provision
$ vagrant provision DL is deprecated, please use Fiddle [default] Chef 11.8.2 Omnibus package is already installed. [default] Running provisioner: chef_solo... Generating chef JSON and uploading... Running chef-solo... [2014-01-17T14:41:43+09:00] INFO: Forking chef instance to converge... [2014-01-17T14:41:43+09:00] INFO: *** Chef 11.8.2 *** [2014-01-17T14:41:43+09:00] INFO: Chef-client pid: 3005 [2014-01-17T14:41:44+09:00] INFO: Setting the run_list to ["recipe[base]", "recipe[repo]"] from JSON [2014-01-17T14:41:44+09:00] INFO: Run List is
, recipe[repo]] [2014-01-17T14:41:44+09:00] INFO: Run List expands to [base, repo] [2014-01-17T14:41:44+09:00] INFO: Starting Chef Run for chef-lamp.vagrantup.com [2014-01-17T14:41:44+09:00] INFO: Running start handlers [2014-01-17T14:41:44+09:00] INFO: Start handlers complete. [2014-01-17T14:41:46+09:00] INFO: remote_file[/tmp/epel-release-6-8.noarch.rpm] created file /tmp/epel-release-6-8.noarch.rpm [2014-01-17T14:41:51+09:00] INFO: remote_file[/tmp/epel-release-6-8.noarch.rpm] updated file contents /tmp/epel-release-6-8.noarch.rpm [2014-01-17T14:41:55+09:00] INFO: remote_file[/tmp/remi-release-6.rpm] created file /tmp/remi-release-6.rpm [2014-01-17T14:42:01+09:00] INFO: remote_file[/tmp/remi-release-6.rpm] updated file contents /tmp/remi-release-6.rpm [2014-01-17T14:42:02+09:00] INFO: remote_file[/tmp/rpmforge-release-0.5.3-1.el6.rf.i686.rpm] created file /tmp/rpmforge-release-0.5.3-1.el6.rf.i686.rpm [2014-01-17T14:42:26+09:00] INFO: remote_file[/tmp/rpmforge-release-0.5.3-1.el6.rf.i686.rpm] updated file contents /tmp/rpmforge-release-0.5.3-1.el6.rf.i686.rpm [2014-01-17T14:42:28+09:00] INFO: bash[repo] ran successfully [2014-01-17T14:42:28+09:00] INFO: Chef Run complete in 44.31108137 seconds [2014-01-17T14:42:28+09:00] INFO: Running report handlers [2014-01-17T14:42:28+09:00] INFO: Report handlers complete [2014-01-17T14:41:43+09:00] INFO: Forking chef instance to converge... - 動作確認
リポジトリがインストールされているか確認します。
$ vagrant ssh $ for r in epel remi rpmforge; do yum list installed | grep installed | grep $r; done
$ vagrant ssh Last login: Fri Jan 17 14:47:50 2014 from 10.0.2.2 [vagrant@chef-lamp ~]$ for r in epel remi rpmforge; do yum list installed | grep installed | grep $r; done epel-release.noarch 6-8 installed remi-release.noarch 6.4-1.el6.remi installed rpmforge-release.i686 0.5.3-1.el6.rf installed [vagrant@chef-lamp ~]$
Apache環境の構築
ApacheをインストールするCookbookを作成します。
- レシピの指定
Vagrantfileを下記のとおり編集します。
ServerAdminおよび、ServerNameに指定するパラメタも合わせて指定しています。chef.add_recipe "httpd" httpd: { admin: "root@chef-lamp.vagrantup.com", fqdn: "chef-lamp.vagrantup.com", port: 80 },
- httpd Cookbookの作成
httpd Cookbookを作成します。
$ knife cookbook create httpd -o site-cookbooks
$ knife cookbook create httpd -o site-cookbooks ** Creating cookbook httpd ** Creating README for cookbook: httpd ** Creating CHANGELOG for cookbook: httpd ** Creating metadata for cookbook: httpd
- httpd.confテンプレートの作成
構築前の準備でローカルにコピーしたhttpd.confを下記のとおり編集します。
編集によって、Vagrantfileで指定したadmin/fqdn/port変数がhttpd.confに反映されるようになります。$ cp ../lamp/httpd.conf site-cookbooks/httpd/templates/default/httpd.conf.erb $ vi site-cookbooks/httpd/templates/default/httpd.conf.erb
ServerAdmin ServerName :
- レシピの作成
Apacheのインストール、httpd.confの設定、自動起動を設定するレシピを作成します。
レシピでは、先に作成したhttpd.confテンプレートを指定し、毎回実行されないようにaction=nothingとしています。また、パッケージをインストールした時に、httpd.confを設定するようにnotifyリソースを指定しています。$ vi site-cookbooks/httpd/recipes/default.rb
# httpd.conf設定 template "httpd.conf" do path "/etc/httpd/conf/httpd.conf" source "httpd.conf.erb" mode 0644 action :nothing end # パッケージインストール package "httpd" do action :install notifies :create, resources( :template => "httpd.conf" ) end # サービス起動と自動起動設定 service "httpd" do action [:start, :enable] end
- レシピの実行
レシピが作成できましたので、プロビジョニングを行います。
$ vagrant provision
$ vagrant provision DL is deprecated, please use Fiddle [default] Chef 11.8.2 Omnibus package is already installed. [default] Running provisioner: chef_solo... Generating chef JSON and uploading... Running chef-solo... [2014-01-17T18:07:38+09:00] INFO: Forking chef instance to converge... [2014-01-17T18:07:38+09:00] INFO: *** Chef 11.8.2 *** [2014-01-17T18:07:38+09:00] INFO: Chef-client pid: 2253 [2014-01-17T18:07:39+09:00] INFO: Setting the run_list to ["recipe[base]", "recipe[repo]", "recipe[httpd]"] from JSON [2014-01-17T18:07:39+09:00] INFO: Run List is
, recipe[repo], recipe[httpd]] [2014-01-17T18:07:39+09:00] INFO: Run List expands to [base, repo, httpd] [2014-01-17T18:07:39+09:00] INFO: Starting Chef Run for chef-lamp.vagrantup.com [2014-01-17T18:07:39+09:00] INFO: Running start handlers [2014-01-17T18:07:39+09:00] INFO: Start handlers complete. [2014-01-17T18:08:09+09:00] INFO: package[httpd] installing httpd-2.2.15-29.el6.centos from base repository [2014-01-17T18:08:20+09:00] INFO: service[httpd] started [2014-01-17T18:08:20+09:00] INFO: service[httpd] enabled [2014-01-17T18:08:20+09:00] INFO: package[httpd] sending create action to template[httpd.conf] (delayed) [2014-01-17T18:08:21+09:00] INFO: template[httpd.conf] backed up to /var/chef/backup/etc/httpd/conf/httpd.conf.chef-20140117180821.039793 [2014-01-17T18:08:21+09:00] INFO: template[httpd.conf] updated file contents /etc/httpd/conf/httpd.conf [2014-01-17T18:08:21+09:00] INFO: Chef Run complete in 41.276097145 seconds [2014-01-17T18:08:21+09:00] INFO: Running report handlers [2014-01-17T18:08:21+09:00] INFO: Report handlers complete [2014-01-17T18:07:38+09:00] INFO: Forking chef instance to converge... - 動作確認
ブラウザでアクセスすると、デフォルトページが表示されます。
MySQL環境の構築
MySQLをインストールするCookbookを作成します。
- レシピの指定
Vagrantfileを下記のとおり編集します。
実行するレシピおよび、MySQLのrootユーザーパスワードを指定しています。chef.add_recipe "mysql" mysql: { passwd: "ro0tUser" },
- MySQL Cookbookの作成
MySQL Cookbookを作成します。
$ knife cookbook create mysql -o site-cookbooks
$ knife cookbook create mysql -o site-cookbooks ** Creating cookbook mysql ** Creating README for cookbook: mysql ** Creating CHANGELOG for cookbook: mysql ** Creating metadata for cookbook: mysql
- my.cnfテンプレートの作成
構築前の準備でローカルにコピーしたmy.cnfを、テンプレートとして保存します。
$ cp ../lamp/my.cnf site-cookbooks/mysql/templates/default/my.cnf.erb
- レシピの作成
MySQLのインストール、my.cnfの設定、自動起動および、セキュリティを設定するレシピを作成します。
Apacheのレシピと同様に、パッケージがインストールされた後、MySQL設定ファイルを作成します。$ vi site-cookbooks/mysql/recipes/default.rb
# my.cnf設定 template "my.cnf" do path "/etc/my.cnf" source "my.cnf.erb" mode 0644 action :nothing end # パッケージインストール package "mysql-server" do action :install options "--enablerepo=remi" notifies :create, resources( :template => "my.cnf" ) end # サービス起動と自動起動設定 service "mysqld" do action [:start, :enable] end # セキュリティ設定 # 匿名ユーザーの削除 # リモートからのrootユーザー接続を禁止 # testデータベースの削除 # rootユーザーパスワードの設定 # 権限データベースのリロード script "secure_setting" do interpreter 'bash' user "root" not_if "mysql -u root -p#{node[:mysql][:passwd]} -e 'show status'" code <<-EOC mysql -u root -e "DELETE FROM mysql.user WHERE User='';" mysql -u root -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');" mysql -u root -e "DROP DATABASE test;" mysql -u root -e "UPDATE mysql.user SET Password=PASSWORD('#{node[:mysql][:passwd]}') WHERE User='root';" mysql -u root -e "FLUSH PRIVILEGES;" EOC end # サービス再起動 service "mysqld" do action :restart end
- レシピの実行
レシピが作成できましたので、プロビジョニングを行います。
$ vagrant provision
$ vagrant provision DL is deprecated, please use Fiddle [default] Chef 11.8.2 Omnibus package is already installed. [default] Running provisioner: chef_solo... Generating chef JSON and uploading... Running chef-solo... [2014-01-17T18:50:24+09:00] INFO: Forking chef instance to converge... [2014-01-17T18:50:24+09:00] INFO: *** Chef 11.8.2 *** [2014-01-17T18:50:24+09:00] INFO: Chef-client pid: 4371 [2014-01-17T18:50:24+09:00] INFO: Setting the run_list to ["recipe[base]", "recipe[repo]", "recipe[httpd]", "recipe[mysql]"] from JSON [2014-01-17T18:50:24+09:00] INFO: Run List is
, recipe[repo], recipe[httpd], recipe[mysql]] [2014-01-17T18:50:24+09:00] INFO: Run List expands to [base, repo, httpd, mysql] [2014-01-17T18:50:24+09:00] INFO: Starting Chef Run for chef-lamp.vagrantup.com [2014-01-17T18:50:24+09:00] INFO: Running start handlers [2014-01-17T18:50:24+09:00] INFO: Start handlers complete. [2014-01-17T18:50:25+09:00] WARN: Cloning resource attributes for service[mysqld] from prior resource (CHEF-3694) [2014-01-17T18:50:25+09:00] WARN: Previous service[mysqld]: /tmp/vagrant-chef-1/chef-solo-1/cookbooks/mysql/recipes/default.rb:21:in `from_file' [2014-01-17T18:50:25+09:00] WARN: Current service[mysqld]: /tmp/vagrant-chef-1/chef-solo-1/cookbooks/mysql/recipes/default.rb:45:in `from_file' [2014-01-17T18:50:34+09:00] INFO: package[mysql-server] installing mysql-server-5.5.35-1.el6.remi from remi repository [2014-01-17T18:51:14+09:00] INFO: service[mysqld] started [2014-01-17T18:51:15+09:00] INFO: service[mysqld] enabled [2014-01-17T18:51:22+09:00] INFO: service[mysqld] restarted [2014-01-17T18:51:22+09:00] INFO: package[mysql-server] sending create action to template[my.cnf] (delayed) [2014-01-17T18:51:22+09:00] INFO: Chef Run complete in 57.572522985 seconds [2014-01-17T18:51:22+09:00] INFO: Running report handlers [2014-01-17T18:51:22+09:00] INFO: Report handlers complete [2014-01-17T18:50:24+09:00] INFO: Forking chef instance to converge... - 動作確認
MySQLがインストールされているか確認します。
mysqlコマンド実行時のパスワードには、Vagrantfileで指定したパスワードを入力します。$ vagrant ssh $ mysql -u root -p -e 'status'
PHP環境の構築
PHPをインストールするCookbookを作成します。
- レシピの指定
Vagrantfileを下記のとおり編集します。
実行するレシピおよび、PHPのtimezoneを指定しています。chef.add_recipe "php54" php54: { timezone: "Asia/Tokyo" },
- MySQL Cookbookの作成
PHP Cookbookを作成します。
$ knife cookbook create php54 -o site-cookbooks
$ knife cookbook create php54 -o site-cookbooks ** Creating cookbook php54 ** Creating README for cookbook: php54 ** Creating CHANGELOG for cookbook: php54 ** Creating metadata for cookbook: php54
- php.iniテンプレートの作成
構築前の準備でローカルにコピーしたphp.iniを下記のとおり編集します。
編集によって、Vagrantfileで指定したtimezone変数がphp.iniに反映されるようになります。$ cp ../lamp/php.ini site-cookbooks/php54/templates/default/php.ini.erb $ vi site-cookbooks/php54/templates/default/php.ini.erb
date.timezone = '<%= node[:php54][:timezone]%>'
- PHPサンプルテンプレートの作成
PHPをインストールした後の動作確認用に、PHPサンプルのテンプレートを作成します。
$ vi site-cookbooks/php54/templates/default/phpinfo.php.erb
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> phpinfo</title> </head> <body> <?php phpinfo(); ?> </body> </html>
- レシピの作成
PHPのインストール、php.iniの設定、PHPサンプルファイルを作成するレシピを作成します。
Apacheのレシピと同様に、パッケージがインストールされた後、PHP設定ファイルおよび、PHPサンプルファイルを作成します。$ vi site-cookbooks/php54/recipes/default.rb
# php.ini設定 template "php.ini" do path "/etc/php.ini" source "php.ini.erb" mode 0644 action :nothing end # PHPサンプル template "phpinfo.php" do path "/var/www/html/phpinfo.php" source "phpinfo.php.erb" mode 0644 action :nothing end # パッケージインストール package "php" do action :install options "--enablerepo=remi" notifies :create, resources( :template => "php.ini" ) notifies :create, resources( :template => "phpinfo.php" ) notifies :restart, 'service[httpd]' end # 関連パッケージのインストール %w{ php-mysql php-gd php-pdo php-pear php-mbstring php-devel }.each do |p| package p do action :install options "--enablerepo=remi" end end # php-mcryptパッケージのインストール package "php-mcrypt" do action :install options "--enablerepo=epel,remi,rpmforge" end
- レシピの実行
レシピが作成できましたので、プロビジョニングを行います。
$ vagrant provision
$ vagrant provision DL is deprecated, please use Fiddle [default] Chef 11.8.2 Omnibus package is already installed. [default] Running provisioner: chef_solo... Generating chef JSON and uploading... Running chef-solo... [2014-01-17T19:22:59+09:00] INFO: Forking chef instance to converge... [2014-01-17T19:22:59+09:00] INFO: *** Chef 11.8.2 *** [2014-01-17T19:22:59+09:00] INFO: Chef-client pid: 5808 [2014-01-17T19:23:00+09:00] INFO: Setting the run_list to ["recipe[base]", "recipe[repo]", "recipe[httpd]", "recipe[mysql]", "recipe[php54]"] from JSON [2014-01-17T19:23:00+09:00] INFO: Run List is
, recipe[repo], recipe[httpd], recipe[mysql], recipe[php54]] [2014-01-17T19:23:00+09:00] INFO: Run List expands to [base, repo, httpd, mysql, php54] [2014-01-17T19:23:00+09:00] INFO: Starting Chef Run for chef-lamp.vagrantup.com [2014-01-17T19:23:00+09:00] INFO: Running start handlers [2014-01-17T19:23:00+09:00] INFO: Start handlers complete. [2014-01-17T19:23:00+09:00] WARN: Cloning resource attributes for service[mysqld] from prior resource (CHEF-3694) [2014-01-17T19:23:00+09:00] WARN: Previous service[mysqld]: /tmp/vagrant-chef-1/chef-solo-1/cookbooks/mysql/recipes/default.rb:21:in `from_file' [2014-01-17T19:23:00+09:00] WARN: Current service[mysqld]: /tmp/vagrant-chef-1/chef-solo-1/cookbooks/mysql/recipes/default.rb:45:in `from_file' [2014-01-17T19:23:23+09:00] INFO: service[mysqld] restarted [2014-01-17T19:23:23+09:00] INFO: package installing php-5.4.24-1.el6.remi from remi repository [2014-01-17T19:25:10+09:00] INFO: package[php-mysql] installing php-mysql-5.4.24-1.el6.remi from remi repository [2014-01-17T19:25:21+09:00] INFO: package[php-gd] installing php-gd-5.4.24-1.el6.remi from remi repository [2014-01-17T19:25:44+09:00] INFO: package[php-pear] installing php-pear-1.9.4-23.el6.remi from remi repository [2014-01-17T19:26:03+09:00] INFO: package[php-mbstring] installing php-mbstring-5.4.24-1.el6.remi from remi repository [2014-01-17T19:26:19+09:00] INFO: package[php-devel] installing php-devel-5.4.24-1.el6.remi from remi repository [2014-01-17T19:27:24+09:00] INFO: package[php-mcrypt] installing php-mcrypt-5.4.24-1.el6.remi from remi repository [2014-01-17T19:27:50+09:00] INFO: package sending create action to template (delayed) [2014-01-17T19:27:51+09:00] INFO: template backed up to /var/chef/backup/etc/php.ini.chef-20140117192751.083477 [2014-01-17T19:27:51+09:00] INFO: template updated file contents /etc/php.ini [2014-01-17T19:27:51+09:00] INFO: package sending create action to template[phpinfo.php] (delayed) [2014-01-17T19:27:51+09:00] INFO: template[phpinfo.php] created file /var/www/html/phpinfo.php [2014-01-17T19:27:51+09:00] INFO: template[phpinfo.php] updated file contents /var/www/html/phpinfo.php [2014-01-17T19:27:51+09:00] INFO: template[phpinfo.php] mode changed to 644 [2014-01-17T19:27:51+09:00] INFO: package sending restart action to service[httpd] (delayed) [2014-01-17T19:27:54+09:00] INFO: service[httpd] restarted [2014-01-17T19:27:54+09:00] INFO: Chef Run complete in 293.646192177 seconds [2014-01-17T19:27:54+09:00] INFO: Running report handlers [2014-01-17T19:27:54+09:00] INFO: Report handlers complete [2014-01-17T19:22:59+09:00] INFO: Forking chef instance to converge... - 動作確認
ブラウザでアクセスすると、PHPの構成情報が表示されます。
まとめ
ここまで、LAMP環境を構築するレシピを作成し、プロビジョニングを行う方法を解説しました。CHefを用いたプロビジョニングでは、Cookbookを作成しCookbookのレシピを記述することで、サーバーの構成管理を行います。今回作成したVagrantfileとsite-cookbooksをGitなどのバージョン管理ソフトウエアで管理することで、複数のメンバーが今回作成したサーバーをローカルマシン上で利用できるようになります。今回解説した記事を参考にして、Chefプロビジョニングにチャレンジしてみては如何でしょうか。