連載
» 2016年06月24日 05時00分 公開

実際に検証済み!OSS徹底比較(4)サーバ構築自動化【後編】:OSSのサーバ構築自動化ツール、4製品徹底検証 2016年版 (7/8)

[森元敏雄,TIS]

Itamae cookbookのTIPS

1.recipeへのパラメータ受け渡し

 recipe内で動的に変更したい変数はnode定義のjsonファイルに記述する。

$ cat /etc/itamae/nodes/tissvv096.json
{
    "ipaddress"        : "10.255.202.96",
    "hostname"         : "tissvv096",
    "mysql_root_pass"  : "FM11AD2+",
    "mysql_wp_db"      : "WordPress",
    "mysql_wp_user"    : "wp_admin",
    "mysql_wp_pass"    : "HB-F1XDJ",
    "wp_unique_phrase" : "FX702PFX801PPB100FX860PPB700PB500PB750PAI1000",
    "wp_os_user"       : "root",
    "wp_os_group"      : "root",
    "wp_latest"        : "https://ja.wordpress.org/latest-ja.tar.gz"
}

 node定義のjsonファイルからの設定値の取得は、node['変数名']で行える。

$ cat /etc/itamae/cookbooks/wordpress/default.rb
# Parameter settings
ipaddress        = node['ipaddress']
hostname         = node['hostname']
mysql_root_pass  = node['mysql_root_pass']
mysql_wp_db      = node['mysql_wp_db']
mysql_wp_user    = node['mysql_wp_user']
mysql_wp_pass    = node['mysql_wp_pass']
wp_unique_phrase = node['wp_unique_phrase']
wp_os_user       = node['wp_os_user']
wp_os_group      = node['wp_os_group']
wp_latest        = node['wp_latest']

 node定義のjsonファイル中で未定義の場合でもエラーとならず、値が未設定となるため、default値を設定するのであれば、if文で未設定を判定して補充する処理を追加することとなる。

# defautl settings
if ipaddress == '' then
  ipaddress = '10.255.202.96'
end

2.recipeの記述方法

 Itamaeのrecipeの記述方法は、公式サイトのItamae Wikiに記載されているので、こちらも参照いただきたい。

(1)yumコマンドでのパッケージの制御

 yumコマンドでのパッケージのインストールはpackageリソースを使用する。

# install package
package mariadb-server do
  action :install
end

 複数のパッケージをインストールする場合は、Rubyのループ処理でパッケージ名を変数に設定する形で対応する。

# install packages
%w( mariadb-server httpd php php-mysql ).each do |pkg|
  package pkg do
    action :install
  end
end

(2)serviceの起動制御

 serviceの起動(CentOS 7.2の場合、systemctlコマンド)の実行はserviceリソースで行う。下記の例ではサービスの起動とenableを設定している。

# enable/start mariadb
service "mariadb" do
  action [:enable,:start]
end

(3)ノード上でのコマンドを実行

 recipe内で任意のコマンドを実行する方法として、executeリソースを使用する。commandパラメータの後ろに実行するコマンドを記述するが、複数行の場合、;\で接続することで、1行のコマンドして実行される。

# mariadb logrotate setting
execute "modify maridb logrotate config" do
  command "sed -i.bak -e '23,$ s/^#//' /etc/logrotate.d/mariadb"
  user "root"
  not_if "test -f /etc/logrotate.d/mariadb.bak"
end

 複数行の処理を実行する場合はtemplateを利用して、一時ファイルを作成して実行する形が良いと考えられる。

# create wordpres db/user
template "/tmp/wordpress.createdb.sql" do
  action :create
  source "/etc/itamae/cookbooks/wordpress/templates/wordpress.createdb.sql.erb"
  variables( mysql_wp_db: "#{mysql_wp_db}",
             mysql_wp_user: "#{mysql_wp_user}",
             mysql_wp_pass: "#{mysql_wp_pass}" )
  owner "root"
  group "root"
  not_if "test -f /tmp/wordpress.createdb.sql"
end
execute "create wordpress db/user" do
  command "mysql -u root -p#{mysql_root_pass} < /tmp/wordpress.createdb.sql"
  only_if "test `mysql -u root -p#{mysql_root_pass} -e \"show databases\" | grep -c #{mysql_wp_db}` == 0"
end
execute "remove /tmp/wordpress.createdb.sql"
  command "rm -f "/tmp/wordpress.createdb.sql"
  only_if "test -f /tmp/wordpress.createdb.sql"
end

(4)templateを使用したファイルの作成

 設定ファイルなどを新規に作成する場合、templateリソースを使用する。 以下のようなテンプレートファイルを作成する。上位のrecipeから変数を受け取る場合、<%= @[変数名] %>と記載しておくと、ファイル生成時にその部分が呼び出し元のrecipeの変数の値で置換される。

$ cat /etc/itamae/cookbooks/wordpress/templates/my.cnf.erb
[client]
user = root
password = "<%= @mysql_root_pass %>"
[mysqladmin]
user = root
password = "<%= @mysql_root_pass %>"

 templateファイルはrecipe内からは以下の形で使用される。templateファイルに引き渡す変数と設定値はvariablesパラメータを使用する。

# create /root/.my.cnf
template "/root/.my.cnf" do
  action :create
  source "/etc/itamae/cookbooks/wordpress/templates/my.cnf.erb"
  variables( mysql_root_pass: "#{mysql_root_pass}" )
  owner "root"
  group "root"

(5)設定処理の実行要否の判定

 再実行時に設定処理の実行要否の判定のために、各リソースの共通属性としてonly_if/not_ifが提供されている。only_if [条件式]は条件式の結果が≠0の場合、not_if [条件式]は条件式の結果が=0の場合に実行される。

 こちらはMySQLのコマンドが正常に実行できなかった場合に処理を実行している(rootのパスワードが未設定の場合、パスワードを指定するとMariaDBに接続できず、結果を取得できない)。

# set mariadb root password
execute "create mariadb root" do
  command "mysql -e \"update mysql.user set password=password(\'#{mysql_root_pass}\') where user = \'root\'\""
  only_if "test `mysql -u root -p#{mysql_root_pass} -e \"show databases\" | grep -c mysql` == 0"
end

 こちらは単純にバックアップファイルが作成されていない場合に処理を実行している。

# mariadb logrotate setting
execute "modify maridb logrotate config" do
  command "sed -i.bak -e '23,$ s/^#//' /etc/logrotate.d/mariadb"
  user "root"
  not_if "test -f /etc/logrotate.d/mariadb.bak"
end

(6)ファイルの文字列置換

 ファイルの操作を行うfileリソースで、対象ファイルの文字列の置換機能が提供されている。

 atction :editでファイルの編集を宣言し、block do |content| 〜 endで編集対象ファイルを一括読み込みしている。その内部で、gsub関数により文字列の置換を行っている。正規表現を使用することも可能で、詳細な変換パターンを定義できる。ただ、変換する行数の指定はできないため、行数で制御を行う場合は、executeコマンドでsedなどを利用する必要がある。

 file "/var/www/wordpress/wp-config.php" do
  action :edit
  block do |content|
    content.gsub!( /(^.+?)database_name_here(.+?$)/, "\\1#{mysql_wp_db}\\2" )
    content.gsub!( /(^.+?)username_here(.+?$)/, "\\1#{mysql_wp_user}\\2" )
    content.gsub!( /(^.+?)password_here(.+?$)/, "\\1#{mysql_wp_pass}\\2" )
    content.gsub!( /(^.+?)put your unique phrase here(.+?$)/, "\\1#{wp_unique_phrase}\\2" )
  end
  owner "root"
  group "root"
  not_if "test `grep -c database_name_here /var/www/wordpress/wp-config.php` == 0"
end

(7)変数の使用上の注意点

 Itamaeの変数は #{変数名} で変数の値に変換され処理される。ただし、 '(single quotation)で変数を囲むと、変数の値に変換されない。変数の値を利用する場合は"(double quotation)で囲む必要がある。処理の都合上、'で変数を囲む場合、および、"の中で"を利用する場合は、\(back slash)でエスケープできる。使用例は以下の通りだ。

# set mariadb root password
execute "create mariadb root" do
  command "mysql -e \"update mysql.user set password=password(\'#{mysql_root_pass}\') where user = \'root\'\""
  only_if "test `mysql -u root -p#{mysql_root_pass} -e \"show databases\" | grep -c mysql` == 0"
end

 wikiでも十分な解説がなされているが、公式サイト以外でも日本語での情報を非常に入手しやすい。国産製品であるため国内の利用者も多い。構築に必要な技術情報はQiitaなどの技術情報共有サービスで入手できるので、ぜひ活用したい。

Itamae Recipe Pluginsについて

 Itamaeで利用可能なレシピも公開されており、Recipe Pluginsとして利用することもできる。2016年5月時点で、以下のitamae_plugin_recipeが公開されている。

$ gem list -r itamae-plugin-recipe
*** REMOTE GEMS ***
itamae-plugin-recipe-android_sdk (0.1.0)
itamae-plugin-recipe-anyenv (0.3.0)
itamae-plugin-recipe-atom (0.0.1)
itamae-plugin-recipe-docker (0.2.2)
itamae-plugin-recipe-etcd (0.1.0)
itamae-plugin-recipe-git_now (0.1.1)
itamae-plugin-recipe-homebrew (0.0.3)
itamae-plugin-recipe-idcf-backup_to_object_storage (0.1.6)
itamae-plugin-recipe-kzyty_mysql (0.1.0)
itamae-plugin-recipe-kzyty_redis (0.1.1)
itamae-plugin-recipe-minecraft (0.0.5)
itamae-plugin-recipe-nginx_build (0.1.2)
itamae-plugin-recipe-nm_chruby (0.1.0)
itamae-plugin-recipe-nodebrew (0.1.1)
itamae-plugin-recipe-openresty (0.0.1)
itamae-plugin-recipe-openssh (0.1.0)
itamae-plugin-recipe-oracle_jdk (0.0.2)
itamae-plugin-recipe-phantomjs (0.0.1)
itamae-plugin-recipe-plenv (0.1.0)
itamae-plugin-recipe-pyenv (0.1.0)
itamae-plugin-recipe-raspberry_pi (0.1.1)
itamae-plugin-recipe-rbenv (0.6.2)
itamae-plugin-recipe-ros (0.2.2)
itamae-plugin-recipe-rtn_git (0.1.4)
itamae-plugin-recipe-rtn_php_nabe (0.0.1)
itamae-plugin-recipe-rtn_rbenv (0.1.5)
itamae-plugin-recipe-rvm (1.0.1)

 残念ながら今回の検証に適合しそうなrecipeが存在しなかったため、本稿では評価を行っていないが、今後、利用者の拡大とともにItamae Recipe Pluginsも増えていくことが期待される。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。