[CentOS6][Chef] ChefでLAMP構成をつくる2 - Apacheの設定ファイル変更


Create: 2013/07/19
LastUpdate: 2013/07/31
[メニューに戻る]

ここでは、Chef11を使用して、段階的にLAMP環境を構築していきます。

今回は、前回の「 [CentOS6][Chef] ChefでLAMP構成をつくる1 - パッケージインストール」に引き続き、Apacheの設定ファイル(httpd.conf)を定義するレシピを追加します。

Chef11のテスト環境の詳細については、「メニュー」を参照してください。

  [テスト環境]
  • 管理サーバ
    192.168.1.67(chetos6g) ・・・ Chefサーバ + ワークステーション
  • 管理対象
    192.168.1.68(centos6h) ・・・ ノード

前回同様、テスト駆動開発のように、まずテストケースを作成してからレシピを作成し、実際にノードで実行する前に Cookbook が期待する動作を行うかテストすることにします。

Chefのレシピの書き方や、Chefspecのテストケースの書き方は、以下を参考にしました。

今回使用する管理対象のノードは、前回のレシピを実行した状態になっているので、Apacheの設定ファイル(httpd.conf)は、パッケージのデフォルト設定になっています。
そこで、今回作成する新しいレシピを実行することで、管理対象ノードのApacheの設定ファイル(httpd.conf)を変更します。

1.Apache 用のCookbook 修正


以下、管理サーバに chefユーザでログインして、Chefのワークステーションで作業します。

1.1.Chefspec のテストケース追加


以下のファイルにChefspecのテストケースを追加します。
  • ~/chef-repo/cookbooks/apache/spec/default_spec.rb 
今回は、レシピに httpd.conf を作成する記述があるかチェックするテストケースを1つ追加します。
内容は以下のとおり。赤字部分が修正箇所です。
require 'chefspec'

describe 'apache::default' do
  let (:chef_run) { ChefSpec::ChefRunner.new.converge 'apache::default' }

  # package
  it 'should install apache' do
    chef_run.should install_package 'httpd'
  end

  # template
  it 'should create httpd.conf' do
    expect(chef_run).to create_file '/etc/httpd/conf/httpd.conf'
    file = chef_run.template('/etc/httpd/conf/httpd.conf')
    expect(file.mode).to eq "0644"
    expect(file).to be_owned_by('root', 'root')
  end

end

このテストケースでは、httpd.conf ファイルの所有者(root,root)とパーミション(0644)もチェックしています。
まだ、レシピを作成していませんが、試しに、このテストケースを実行すると以下のようにエラーが表示されます。
テストケースは、"example" と表記され、"2 example, 1failure" は、全部で2件のテストケースがあり、そのうち1件が失敗したという意味になります。
$ cd ~/chef-repo/cookbooks
$ rspec -fd --color apache

apache::default
  should install apache
  should create httpd.conf (FAILED - 1)

Failures:

  1) apache::default should create httpd.conf
     Failure/Error: expect(chef_run).to create_file '/etc/httpd/conf/httpd.conf'
       No file resource named '/etc/httpd/conf/httpd.conf' with action :create found.
     # ./apache/spec/default_spec.rb:13:in `block (2 levels) in <top (required)>'

Finished in 0.13281 seconds
2 examples, 1 failure

Failed examples:

rspec ./apache/spec/default_spec.rb:12 # apache::default should create httpd.conf

1.2.レシピ修正


以下のファイルにレシピを追加します。
  • ~/chef-repo/cookbooks/apache/recipes/default.rb
今回は、テンプレートを用意してApacheの設定ファイル(httpd.conf)を作成します。
"ServerAdmin"、"ServerName"、"Listen"については、ノードなどの対象によって変更可能な値としてアトリビュートで設定することにします。
内容は以下のとおり
#
# Cookbook Name:: apache
# Recipe:: default
#
# Copyright 2013, YOUR_COMPANY_NAME
#
# All rights reserved - Do Not Redistribute
#

# package
package "httpd" do
  action :install
end

# httpd.conf
template "/etc/httpd/conf/httpd.conf" do
 source "httpd.conf.erb"
 owner "root"
 group "root"
 mode "0644"
 variables(
  :servername      => node["apache"]["servername"],
  :port            => node["apache"]["port"],
  :serveradmin     => node["apache"]["serveradmin"]
 )
end
Chefspecのテストケースを実行してレシピをチェックします。
結果が、以下のように "0 failures" であればOKです。
$ cd ~/chef-repo/cookbooks
$ rspec -fd --color apache

apache::default
  should install apache
  should create httpd.conf

Finished in 0.07624 seconds
2 examples, 0 failures
まだ、テンプレートを作成していませんが、試しに、Foodcritic で Cookbookの全体的なチェック(文法、矛盾など)をしてみます。
以下のようにテンプレートが無いというエラーになります。
$ cd ~/chef-repo/cookbooks
$ foodcritic ./apache
FC033: Missing template: ./apache/recipes/default.rb:16

1.3.テンプレート作成


以下のファイルにApacheの設定ファイル(httpd.conf)のテンプレートを作成します。
  • ~/chef-repo/cookbooks/apache/templates/default/httpd.conf.erb
まずは、管理対象ノードにあるデフォルトの設定ファイルをコピーします。
$ cd ~/chef-repo/cookbooks/apache/templates/default
$ ssh root@192.168.1.68 'cat /etc/httpd/conf/httpd.conf' > ./httpd.conf.erb
次に、テンプレート(httpd.conf.erb)を修正して、変更可能なパラメータを設定します。
~省略~
#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, in addition to the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
#
#Listen 12.34.56.78:80
Listen <%= @port %>

~省略~

#
# ServerAdmin: Your address, where problems with the server should be
# e-mailed.  This address appears on some server-generated pages, such
# as error documents.  e.g. admin@your-domain.com
#
ServerAdmin <%= @serveradmin %>

#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If this is not set to valid DNS name for your host, server-generated
# redirections will not work.  See also the UseCanonicalName directive.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
# You will have to access it by its address anyway, and this will make
# redirections work in a sensible way.
#
ServerName <%= @servername %>
これで、もう一度、Foodcritic を実行します。以下のように何も表示されなければOKです。
$ foodcritic ./apache

この時点で、アトリビュートは定義していませんがエラーにはなりません。

1.4.アトリビュートの設定


アトリビュートはWebGUIでも設定できますが、今回は、以下のファイルにデフォルト値を定義しておきます。
  • ~/chef-repo/cookbooks/apache/attributes/default.rb
内容は、以下のとおり。
default["apache"]["serveradmin"] = "admin@example.com"
default["apache"]["servername"] = "127.0.0.1:80"
default["apache"]["port"] = "80"

1.5.バージョンの変更


以下のファイルを修正して Cookbookのバージョン番号を変更します。
  • ~/chef-repo/cookbooks/apache/metadata.rb
赤字部分の番号を "'0.1.1" にします。
name             'apache'
maintainer       'blue21'
maintainer_email 'canopus@blue21.ddo.jp'
license          'All rights reserved'
description      'Installs/Configures apache'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version          '0.1.1'

2.CookbookをChefサーバに登録


管理サーバに chefユーザでログインして、Chefのワークステーションで作業します。
i以下のようにコマンドを実行して、修正した Cookbook をChefサーバにアップロードします。
$ cd ~/chef-repo/cookbooks
$ knife cookbook upload apache
Uploading apache         [0.1.1]
Uploaded 1 cookbook.
ブラウザ(WebGUI)で確認すると下図のとおり。バージョンが2つ表示されます。



3.ノードでレシピの実行


管理対象のノードでレシピを実行してApacheの設定ファイルを変更します。
ノードのChefクライアントをデーモン化していれば、自動的にレシピが実行されるのですが、今回はデーモン化していないので、管理対象のノードにログインして、Chefクライアントを実行します。
管理対象に、root ユーザでログインし、以下のようにコマンドを実行します。
# /opt/chef/bin/chef-client
Starting Chef Client, version 11.4.4
resolving cookbooks for run list: ["apache", "php", "mysql"]
Synchronizing Cookbooks:
  - mysql
  - php
  - apache
Compiling Cookbooks...
Converging 6 resources
Recipe: apache::default
  * package[httpd] action install (up to date)
  * template[/etc/httpd/conf/httpd.conf] action create
    - update template[/etc/httpd/conf/httpd.conf] from f46217 to c64fc8
        --- /etc/httpd/conf/httpd.conf  2013-07-19 10:54:33.373043664 +0900
        +++ /tmp/chef-rendered-template20130719-17451-1x8f6m4   2013-07-19 10:54:45.286054595 +0900
        @@ -259,7 +259,7 @@
         # e-mailed.  This address appears on some server-generated pages, such
         # as error documents.  e.g. admin@your-domain.com
         #
        -ServerAdmin admin@your-domain.com
        +ServerAdmin admin@example.com

         #
         # ServerName gives the name and port that the server uses to identify itself.
        @@ -273,7 +273,7 @@
         # You will have to access it by its address anyway, and this will make
         # redirections work in a sensible way.
         #
        -#ServerName 127.0.0.1:80
        +ServerName 127.0.0.1:80

         #
         # UseCanonicalName: Determines how Apache constructs self-referencing

Recipe: php::default
  * package[php] action install (up to date)
  * package[php-mysql] action install (up to date)
Recipe: mysql::default
  * package[mysql] action install (up to date)
  * package[mysql-server] action install (up to date)
Chef Client finished, 1 resources updated

パッケージのインストールを行うレシピについては実行済みなので、何も行われていません。(up to date)
Apacheの設定ファイルについては、変更箇所が表示されています。
ちゃんと修正されたか、確認してみます。
# egrep '^(ServerAdmin|ServerName|Listen)' /etc/httpd/conf/httpd.conf
Listen 80
ServerAdmin admin@example.com
ServerName 127.0.0.1:80

WebGUIでノードを見ると下図のとおり。アトリビュートの値が表示されるようになります。
この値は、knifeコマンドやWebGUIで変更できます。



4.アトリビュートを変更してレシピを実行


WebGUIでアトリビュートの"port"と"servername"を変更して、再度、レシピを実行してみます。
下図のように、管理対象ノードの編集画面を開きます。
[Attributes]欄でアトリビュートの値を設定できます。



[source]タブでjson形式のデータを編集することもできますが、今回は[editor]タブを使用してみます。
まず、以下の手順で操作して、"apache"オブジェクトを追加します。
① 左の[json] をクリック
② 右の[editor]タブをクリック
③ [+] をクリック
④ [type]メニューで、"object" を選択
⑤ [name]欄に "apache" を入力
⑥ "{}" を入力
⑦ [Autodetect type of attribute?]のチェックを外す
⑧ [Add Attribute]ボタンをクリック



以下の手順で操作して、"port" と "servername" の値を設定します。
① 左の [apache] を選択
② 右の [editor]タブを選択
③ [+]を選択
④ [type]メニューで、"string" を選択
⑤ [name]欄に "port" または "servername" を入力
⑥ 値 を入力
⑦ [Autodetect type of attribute?]のチェックを外す
⑧ [Add Attribute]ボタンをクリック



[Save Node]ボタンをクリックします。



ノードの[show]画面で、Attributes を確認し、下図のように設定した値が表示されていればOKです。



これで、このノードのアトリビュートの設定完了です。
実際に管理対象ノードのApacheの設定ファイルを更新してみます。
管理対象に、root ユーザでログインし、以下のようにChefクライアントを実行します。
# /opt/chef/bin/chef-client
Starting Chef Client, version 11.4.4
resolving cookbooks for run list: ["apache", "php", "mysql"]
Synchronizing Cookbooks:
  - mysql
  - php
  - apache
Compiling Cookbooks...
Converging 6 resources
Recipe: apache::default
  * package[httpd] action install (up to date)
  * template[/etc/httpd/conf/httpd.conf] action create
    - update template[/etc/httpd/conf/httpd.conf] from c64fc8 to 9b2aa5
        --- /etc/httpd/conf/httpd.conf  2013-07-19 10:54:45.359054595 +0900
        +++ /tmp/chef-rendered-template20130719-19811-169lp8o   2013-07-19 11:43:24.073054595 +0900
        @@ -133,7 +133,7 @@
         # prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
         #
         #Listen 12.34.56.78:80
        -Listen 80
        +Listen 8888

         #
         # Dynamic Shared Object (DSO) Support
        @@ -273,7 +273,7 @@
         # You will have to access it by its address anyway, and this will make
         # redirections work in a sensible way.
         #
        -ServerName 127.0.0.1:80
        +ServerName 127.0.0.1

         #
         # UseCanonicalName: Determines how Apache constructs self-referencing

Recipe: php::default
  * package[php] action install (up to date)
  * package[php-mysql] action install (up to date)
Recipe: mysql::default
  * package[mysql] action install (up to date)
  * package[mysql-server] action install (up to date)
Chef Client finished, 1 resources updated
ちゃんと修正されたか、確認してみます。
# egrep '^(ServerAdmin|ServerName|Listen)' /etc/httpd/conf/httpd.conf
Listen 8888
ServerAdmin admin@example.com
ServerName 127.0.0.1