はじめに
新しい人がチームに入った場合に、最初にやってもらうこととして開発環境構築があると思います。で、プロダクトが最初の頃はまだそれほどコード量も多くなく、使っているミドルウェアも少ないので環境構築もそれほど苦ではないと思いますが、月日が経ちコード量も増え、使っているミドルウェアが多くなってくると、その分環境を新しく作るのが大変になってきます。
そういう時にChefやAnsible、そして今回紹介するitamaeが役に立つと思います。
筆者もChef(正確にはChef Solo)を使っていた時期もありました。ただChef Soloが終了となり、Chef Zeroの切り替えてということになりました。そこでChef Zeroを使おうとやってみたのですが乗り換えが結構大変だったので、これを機に別にものを使おうと思い検討た結果itamaeを使うことにしました。
理由は
- ライトに使える
- 覚えることが少ない
- sshが使える(Chefとの大きな違い)
といった点からです。
この記事ではitamaeを使って環境構築をする例を紹介しようと思います。
環境
- ruby2.2
- github
- elasticsearch2
- redis
- java 1.8
- itamae 1.9
- vagrant
レシピ
今回やることは次の項目をやっていきます。
- ruby、javaのインストール
- elasticsearch、redis等ミドルウェアのインストール
- githubから対象リポジトリを取得
レシピの構成
先日itamae meet upが開催され、その時にフォルダ構成の話も出ました。今回はその時紹介されたような構成に変更するのが間に合わなかったので若干「むむむ!!」というところがあるかもしれませんが、そこはご了承いただければと思います。
簡単にいうと以下のようにフォルダを分けています。
- recipes
- elasticsearch
- redis
app.rb
- nodes
- templates
nodeの設定
nodeの設定はyaml形式でも書けますが、今回はjsonの形式で書かせていただきます。
{
"rbenv": {
"user": "vagrant",
"versions": ["2.2.1", "2.2.2"],
"global": "2.2.2",
"gems": ["bundler", "rails"]
},
"elasticsearch": {
"cluster_name": "nakamura-elasticsearch",
"version": "2.1.0",
"index_shards_num": "5",
"index_replicas_num": "1"
},
"redis": {
"version": "3.0.4"
},
"git": {
"git_user": "#{ENV['git_user']}",
"git_password": "#{ENV['git_password']}",
"repository": "hoge/fuga_repo",
"app_path": "rails_app"
}
}
ruby、javaのインストール
今回rubyのインストールは公開されているプラグインを使います。javaはpackageで提供されているものを使うことにします。java以外にもgitとか後々使うので、ここで一緒にインストールしてしまいます。
gem 'itamae-plugin-recipe-rbenv'
%w( yum wget java-1.8.0-openjdk git ).each do |pkg|
package pkg do
action :install
end
end
# rubyをinstall
include_recipe "rbenv::user"
elasticsearch、redis等ミドルウェアのインストール
続いてミドルウェアを入れます。
mysqlやelasticsearch、redisのレシピは別のファイルで書いて、cookbooks/app.rbの中ではそれをinclude_recipeすることにします。
elasticsarchのレシピは次のようになります
if /\A1.*/ =~ node[:elasticsearch][:version]
include_recipe 'version/1_x.rb'
else
include_recipe 'version/2_x.rb'
end
バージョン毎にレシピを分けています。
%w( yum java-1.8.0-openjdk wget ).each do |pkg|
package pkg do
action :install
end
end
execute 'rm elasticsearch.tar.gz' do
only_if "test -e ~/elaticsearch.tar.gz"
end
execute 'elasticsearch file get' do
command "wget https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-#{node[:elasticsearch][:version]}.tar.gz -O elasticsearch.tar.gz"
end
execute 'file unzip' do
command 'tar -zxf elasticsearch.tar.gz'
end
execute 'sudo rm -R /usr/local/share/elasticsearch' do
only_if 'ls /usr/local/share/elasticsearch'
end
execute 'sudo mv elasticsearch-* /usr/local/share/elasticsearch' do
not_if 'ls /usr/local/share/elasticsearch'
end
execute 'sudo chmod -R 755 /usr/local/share/elasticsearch' do
only_if 'ls /usr/local/share/elasticsearch'
end
execute 'mkdir /usr/local/share/elasticsearch/plugins' do
not_if 'ls /usr/local/share/elasticsearch/plugins'
end
# elasticsearch.ymlをコピー
template "/usr/local/share/elasticsearch/config/elasticsearch.yml" do
path "/usr/local/share/elasticsearch/config/elasticsearch.yml"
source "../../../templates/elasticsearch/config/elasticsearch_yml.erb"
variables({cluster_name: 'nakamura-elasticsearch', index_shards_num: "5", index_replicas_num: "1"})
end
# プラグイン
execute 'bin/plugin --remove mobz/elasticsearch-head' do
only_if 'cd /usr/local/share/elasticsearch/plugins/head'
cwd '/usr/local/share/elasticsearch'
end
execute 'bin/plugin -install mobz/elasticsearch-head' do
cwd '/usr/local/share/elasticsearch'
end
execute 'bin/plugin --remove elasticsearch/marvel/latest' do
only_if 'cd /usr/local/share/elasticsearch/plugins/mavel'
cwd '/usr/local/share/elasticsearch'
end
execute 'bin/plugin -install elasticsearch/marvel/latest' do
cwd '/usr/local/share/elasticsearch'
end
execute "bin/plugin --remove elasticsearch/elasticsearch-analysis-kuromoji/#{node['elasticsearch']['plugin']['kuromoji']['version']}" do
only_if 'cd /usr/local/share/elasticsearch/plugins/analysis-kuromoji'
cwd '/usr/local/share/elasticsearch'
end
execute "bin/plugin -install elasticsearch/elasticsearch-analysis-kuromoji/#{node['elasticsearch']['plugin']['kuromoji']['version']}" do
cwd '/usr/local/share/elasticsearch'
end
version2を使った場合
%w( yum java-1.8.0-openjdk wget ).each do |pkg|
package pkg do
action :install
end
end
execute 'rm elasticsearch.tar.gz' do
only_if "test -e ~/elaticsearch.tar.gz"
end
execute 'elasticsearch file get' do
command "wget https://download.elasticsearch.org/elasticsearch/release/org/elasticsearch/distribution/tar/elasticsearch/#{node[:elasticsearch][:version]}/elasticsearch-#{node[:elasticsearch][:version]}.tar.gz -O elasticsearch.tar.gz"
end
execute 'file unzip' do
command 'tar -zxf elasticsearch.tar.gz'
end
execute 'sudo rm -R /usr/local/share/elasticsearch' do
only_if 'ls /usr/local/share/elasticsearch'
end
execute 'sudo mv elasticsearch-* /usr/local/share/elasticsearch' do
not_if 'ls /usr/local/share/elasticsearch'
end
execute 'sudo chmod -R 755 /usr/local/share/elasticsearch' do
only_if 'ls /usr/local/share/elasticsearch'
end
execute 'mkdir /usr/local/share/elasticsearch/plugins' do
not_if 'ls /usr/local/share/elasticsearch/plugins'
end
# プラグイン
## HEAD
execute 'bin/plugin remove mobz/elasticsearch-head' do
only_if 'cd /usr/local/share/elasticsearch/plugins/head'
cwd '/usr/local/share/elasticsearch'
end
execute 'bin/plugin install mobz/elasticsearch-head' do
cwd '/usr/local/share/elasticsearch'
end
## kuromoji
execute "bin/plugin remove analysis-kuromoji" do
only_if 'cd /usr/local/share/elasticsearch/plugins/analysis-kuromoji'
cwd '/usr/local/share/elasticsearch'
end
execute "bin/plugin install analysis-kuromoji" do
cwd '/usr/local/share/elasticsearch'
end
# elasticsearch.yml
template "/usr/local/share/elasticsearch/config/elasticsearch.yml" do
path "/usr/local/share/elasticsearch/config/elasticsearch.yml"
source "../../../templates/elasticsearch/config/elasticsearch2_yml.erb"
variables({cluster_name: 'nakamura-elasticsearch', index_shards_num: "5", index_replicas_num: "1"})
end
execute "bin/elasticsearch -d" do
cwd '/usr/local/share/elasticsearch'
end
elasticsearchはバージョン1系と2系で変わったところがあるので、今回レシピも分けて書くようにしました。どちらを使うかはnodeの中の値で変わるようにしました。
続いてredisです。
%w( yum wget ).each do |pkg|
package pkg do
action :install
end
end
execute "rm redis-#{node['redis']['version']}.tar.gz" do
only_if "test -e redis-#{node['redis']['version']}.tar.gz"
end
execute 'redis file get' do
command "wget http://download.redis.io/releases/redis-#{node['redis']['version']}.tar.gz"
end
execute 'unzip' do
command "tar -zxf redis-#{node['redis']['version']}.tar.gz"
end
execute 'make' do
cwd "redis-#{node['redis']['version']}"
end
有効なプラグインがあれば、それに乗り換えようと思っています。Chefに比べてitamaeはまだプラグインが十分でないので。若干力技な感じがしつつ、取り敢えずということで。
githubから対象リポジトリを取得
次にgithubからレシピは次のようになります。
# アプリケーションの配置場所を作成
directory "#{node[:git][:app_path]}" do
mode "755"
end
git "#{node[:git][:app_path]}" do
repository "https://#{node[:git][:git_user]}:#{node[:git][:git_password]}@github.com/#{node[:git][:repository]}.git"
end
実行は次のようにやればできます。
ローカルの場合
bundle exec itamae local -j [nodeファイルを指定] -h [ホストを指定] [レシピファイルを指定]
SSH経由で他のマシンに構築する場合
bundle exec itamae ssh -j [nodeファイルを指定] -h [ホストを指定] [レシピファイルを指定]
vagrantを使ってVM上に構築する場合
bundle exec itamae ssh -j [nodeファイルを指定] -h [ホストを指定] --vagrant [レシピファイルを指定]
以上で必要なミドルウィエアのインストール等をitamaeで自動化してみました。これにより後はitamaeさえ動けば、環境構築が楽にできますね!
補足
先日のitamae meetup1で発表があった事の共有になるのですが、レシピの実行に「どこにどのくらいの時間がかかっているのかを見たい」という場合は、itamaeが最新のバージョンであれば、--profile profile.json
とprofileオプションを実行時に指定するとプロファイリングの結果がjson形式で出力されます。あまりにも実行が遅い、何故だろうって思ったら使ってみると良いなと思いました。
複数のマシンに対してレシピをそれぞれ役割に応じて適用したい場合
rundockというgemを使うと簡単にできます。どのマシンに何を適用するかをyml形式のファイルに記述し実行時に、そのファイルを指定すると各マシンに必要な設定を入れることができます。ロール単位でレシピを記述し、それをrundockで指定します。
rundockのインストール
Gemfileに追加してbundle installでインストールします。
# rundocによる複数ホストの実行
gem 'rundock'
gem 'rundock-plugin-operation-itamae'
rundock.yml
rundockの設定の例です。dev-el2とdev-el4というVM上に作った2つのローカル環境にそれぞれミドルウェアをitamaeのレシピを指定してインストールしています。このようにしておけば、各環境ごとにyamlファイルを作成し、その中で必要なレシピを指定するように書いておけば、どの環境にどのバージョンの何が入っているのかが一目瞭然になります。
- target: dev-el2
itamae:
- cookbooks/redis_elasticsearch.rb
- node_json: nodes/redis_elasticsearch.json
- log_level: info
- sudo: true
- target: dev-el4
itamae:
- recipes/redis/redis.rb
- node_json: nodes/redis.json
- log_level: info
- sudo: true
---
dev-el2:
host: 127.0.0.1
ssh_opts:
port: 2200
user: vagrant
key: /usr/local/project/itamae_recipe/.vagrant/machines/el4/virtualbox/private_key
dev-el4:
host: 127.0.0.1
ssh_opts:
port: 2222
user: vagrant
key: /usr/local/project/itamae_recipe/.vagrant/machines/el2/virtualbox/private_key
---
まだレシピの書き方やフォルダ構成など見直す点が多々あると思っていますが、他の方々の何かの役に立つ事が出来たら幸いです。