Ruby
Go
MySQL
chef
CentOS6

Chefのコマンド一発でサービスを作れる状態へ(CentOS6.6)

More than 1 year has passed since last update.

この投稿は私がCentOS6.6の環境を構築する時に色々調べたりしたことをまとめたものです。
(2015年6月17日現在)

Chefを使って環境を整えたい、VPS契約したけど初期設定めんどくさいという人が対象です。
読者が30分以内ですぐに開発に取り掛かれるようになることがゴールです。

やること

  • セキュリティ関連のセットアップ(開発ユーザー作成、sudo権限付与、rootログインできないようにする、パスワードログインできないようにする、iptablesを設定)
  • nginxを入れる(バージョン:1.9.2)
  • DB(MySQL)を入れる(5.6)
  • Ruby(rbenv:2.2.2), Go(1.4)を入れる

せっかちな方のために

Gitで公開しているので、cloneしたら後はコマンド一発です。
https://github.com/Islands5/vps_settings.git

最低限やることは
site-cookbooks/site-user/recipes/default.rb
の公開鍵を編集

nodes/192.168.33.200.json
のmysqlのパスワードを編集

任意:sshのポートを変更する(触った場合ファイアーウォールの設定もしてね)
等を行う必要があります。

Chefのセットアップ

Chefをまだ入れてないよという人はここでセットアップしてください。
Knife-soloも入れます。

http://qiita.com/hamichamp/items/d3ca7c365353285a564b

VPS環境を整える

chefリポジトリを作成します。

$ chef exec knife solo init chef-repo
$ cd chef-repo
#以下ここを作業のホームディレクトリにします

Berksfileの一行目
site :opscode

source "https://supermarket.chef.io"
に変更

開発を行うユーザー(dev01)を追加

Berksfileを編集します。
cookbook 'user'
を追加してください

次に
site-cookbooks以下にsite-userというクックブックを作ります。

$ chef exec knife cookbook create site-user -o site-cookbooks/

レシピを編集します。

site-cookbooks/site-user/recipes/default.rb
user_account 'dev01' do
  action :create
  ssh_keys ['ssh-rsa ...']   #=> cat ~/.ssh/id_rsa.pubを実行して出てくる文字列
end

次にサーバーに適用するレシピを選択します。
jsonを開きます。

nodes/192.168.33.200.json
{
    "run_list":[
        "recipe[user]",
        "recipe[site-user]"
    ]
}

sudo権限を追加する

dev01にsudo権限をつけます。

Berksfileを編集します。
cookbook 'sudo'
を追加してください

このクックブックは追加のレシピが必要ないので
アトリビュートを設定します。
jsonを開きます。

nodes/192.168.33.200.json
{
    "run_list":[
        "recipe[user]",
        "recipe[site-user]",
        "recipe[sudo]"
    ],
    "authorization": {
        "sudo": {
            "users": ["dev01"],
            "passwordless": "true"
        }
    }
}

rootログイン、パスワードログインを禁止に

Berksfileを編集します。
cookbook 'openssh'
を追加してください

jsonを編集します。

nodes/192.168.33.200.json
{
    "run_list":[
        "recipe[user]",
        "recipe[site-user]",
        "recipe[sudo]",
        "recipe[openssh]"
    ],
    "authorization": {
        "sudo": {
            "users": ["dev01"],
            "passwordless": "true"
        }
    },
    "openssh": {
        "server": {
            "permit_root_login": "no",
            "password_authentication": "no"
        }
    }
}

iptablesを設定する

自作のiptables設定を使います。
クックブックを作ります。

$ chef exec knife cookbook create site-iptables -o site-cookbooks/

レシピを編集します。

site-cookbooks/site-iptables/recipes/default.rb
template "/etc/sysconfig/iptables" do
  source "iptables.erb"
  owner "root"
  group "root"
  mode 0644
end

service "iptables" do
  action [ :enable, :start ]
  supports :status => true, :restart => true
end

source部分にiptables.erbという記述があります。
テンプレートを使用します。

site-cookbooks/site-iptables/templates/default/iptables.erb
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:SERVICES -    [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT
-A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p tcp -m state --state NEW -j SERVICES
-A INPUT -p udp --sport 53 -j ACCEPT
-A INPUT -p udp --sport 123 --dport 123 -j ACCEPT
-A SERVICES -p tcp --dport 22 -j ACCEPT
-A SERVICES -p tcp --dport 80 -j ACCEPT
-A SERVICES -p tcp --dport 443 -j ACCEPT
-A SERVICES -p tcp --dport 3306 -j ACCEPT
COMMIT

この設定は
http://dotinstall.com/lessons/basic_sakura_vps/8010
から引用しました。

run_listにrecipe[site-iptables]を追加します。

nodes/192.168.33.200.json
{
    "run_list":[
        "recipe[user]",
        "recipe[site-user]",
        "recipe[sudo]",
        "recipe[openssh]",
        "recipe[site-iptables]"
    ],
    "authorization": {
        "sudo": {
            "users": ["dev01"],
            "passwordless": "true"
        }
    },
    "openssh": {
        "server": {
            "permit_root_login": "no",
            "password_authentication": "no"
        }
    }
}

nginx(1.9)を入れる

クックブックを作成します。
普通に入れると古いnginxが入るので...

site-cookbooks/nginx/recipes/default.rb
template "nginx.repo" do
  path '/etc/yum.repos.d/nginx.repo'
  source "nginx.repo.erb"
  mode 0644
  owner 'root'
  group 'root'
end

yum_package "nginx" do
  action :install
  flush_cache [:before]
end

service "nginx" do
  action [:enable, :start]
  supports :status => true, :restart => true, :reload => true
end

レシピを適用するためにjsonを編集します。

nodes/192.168.33.200.json
{
    "run_list":[
        "recipe[user]",
        "recipe[site-user]",
        "recipe[sudo]",
        "recipe[openssh]",
        "recipe[site-iptables]",
        "recipe[nginx]"
    ],
    "authorization": {
        "sudo": {
            "users": ["dev01"],
            "passwordless": "true"
        }
    },
    "openssh": {
        "server": {
            "permit_root_login": "no",
            "password_authentication": "no"
        }
    }
}

MySQL(5.6)を入れる

Berksfileを編集します
cookbook 'mysql', '~> 5.3.6'
を追加します

アトリビュートを設定します。
jsonに直接指定する方式をとります。
注)mysql::serverというレシピもrun_listに追加しています。
目立たないですが、忘れないで下さいw

nodes/192.168.33.200.json
{
    "run_list":[
        "recipe[user]",
        "recipe[site-user]",
        "recipe[sudo]",
        "recipe[openssh]",
        "recipe[site-iptables]",
        "recipe[nginx]",
        "recipe[mysql::server]"
    ],
    "authorization": {
        "sudo": {
            "users": ["dev01"],
            "passwordless": "true"
        }
    },
    "openssh": {
        "server": {
            "permit_root_login": "no",
            "password_authentication": "no"
        }
    },
    "mysql":{
        "server_name": "default",
        "version": "5.6",
        "port": "3306",
        "server_root_password": "password",
        "remove_anonymous_users": true,
        "remove_test_database":true
    }
}

Ruby環境(rbenv)を入れる

ほとんどChef実践入門(pp157-162)からの引用です。
しかし、そのままだとエラーが出るので一部追加 + ruby2.2系を入れます。

クックブックを作成します。
sh
$ chef exec knife cookbook create ruby-env -o site-cookbooks/

site-cookbooks/ruby-env/recipes/default.rb
%w{gcc git openssl-devel sqlite-devel}.each do |pkg|
    package pkg do
        action :install
    end
end

git "/home/#{node['ruby-env']['user']}/.rbenv" do
    repository node["ruby-env"]["rbenv_uri"]
    action :sync
    user node['ruby-env']['user']
    group node['ruby-env']['group']
end

template ".bash_profile" do
    source ".bash_profile.erb"
    path "/home/#{node['ruby-env']['user']}/.bash_profile"
    mode 0644
    owner node['ruby-env']['user']
    group node['ruby-env']['group']
    not_if "grep rbenv ~/.bash_profile", :environment => { :'HOME' => "/home/#{node['ruby-env']['user']}" }
end

directory "/home/#{node['ruby-env']['user']}/.rbenv/plugins" do
    owner node['ruby-env']['user']
    group node['ruby-env']['group']
    mode 0755
    action :create
end

git "/home/#{node['ruby-env']['user']}/.rbenv/plugins/ruby-build" do
    repository node["ruby-env"]["ruby-build_uri"]
    action :sync
    user node['ruby-env']['user']
    group node['ruby-env']['group']
end

execute "rbenv install #{node['ruby-env']['version']}" do
    command "/home/#{node['ruby-env']['user']}/.rbenv/bin/rbenv install #{node['ruby-env']['version']}"
    user node['ruby-env']['user']
    group node['ruby-env']['group']
    environment 'HOME' => "/home/#{node['ruby-env']['user']}"
    not_if { File.exists?("/home/#{node['ruby-env']['user']}/.rbenv/versions/#{node['ruby-env']['version']}") }
end

execute "rbenv global #{node['ruby-env']['version']}" do
    command "/home/#{node['ruby-env']['user']}/.rbenv/bin/rbenv global #{node['ruby-env']['version']}"
    user node['ruby-env']['user']
    group node['ruby-env']['group']
    environment 'HOME' => "/home/#{node['ruby-env']['user']}"
end

%w{rbenv-rehash bundler}.each do |gem|
    execute "gem install #{gem}" do
        command "/home/#{node['ruby-env']['user']}/.rbenv/shims/gem install #{gem}"
        user node['ruby-env']['user']
        group node['ruby-env']['group']
        environment 'HOME' => "/home/#{node['ruby-env']['user']}"
        not_if "/home/#{node['ruby-env']['user']}/.rbenv/shims/gem list | grep #{gem}"
    end
end

やはりしっかり作りこまれているので、柔軟性が高いです。
見習いたい...^^;
アトリビュートによってバージョン等をコントロールできます。

site-cookbooks/ruby-env/attributes/default.rb
default['ruby-env']['user'] = "dev01"
default['ruby-env']['group'] = "dev01"
default['ruby-env']['version'] = "2.2.2"
default['ruby-env']['rbenv_uri'] = "https://github.com/sstephenson/rbenv"
default['ruby-env']['ruby-build_uri'] = "https://github.com/sstephenson/ruby-build"

クックブックを適用します。

nodes/192.168.33.200.json
{
    "run_list":[
        "recipe[user]",
        "recipe[site-user]",
        "recipe[sudo]",
        "recipe[openssh]",
        "recipe[site-iptables]",
        "recipe[nginx]",
        "recipe[mysql::server]",
        "recipe[ruby-env]"
    ],
    "authorization": {
        "sudo": {
            "users": ["dev01"],
            "passwordless": "true"
        }
    },
    "openssh": {
        "server": {
            "permit_root_login": "no",
            "password_authentication": "no"
        }
    },
    "mysql":{
        "server_name": "default",
        "version": "5.6",
        "port": "3306",
        "server_root_password": "password",
        "remove_anonymous_users": true,
        "remove_test_database":true
    }
}

Go(1.4)言語環境を入れる

Berksfileを編集します。
cookbook "golang", git: "https://github.com/NOX73/chef-golang", branch: "master"
を追加します。

run_listにrecipe[golang]を追加します。

nodes/192.168.33.200.json
{
    "run_list":[
        "recipe[user]",
        "recipe[site-user]",
        "recipe[sudo]",
        "recipe[openssh]",
        "recipe[site-iptables]",
        "recipe[nginx]",
        "recipe[mysql::server]",
        "recipe[ruby-env]",
        "recipe[golang]"
    ],
    "authorization": {
        "sudo": {
            "users": ["dev01"],
            "passwordless": "true"
        }
    },
    "openssh": {
        "server": {
            "permit_root_login": "no",
            "password_authentication": "no"
        }
    },
    "mysql":{
        "server_name": "default",
        "version": "5.6",
        "port": "3306",
        "server_root_password": "password",
        "remove_anonymous_users": true,
        "remove_test_database":true
    }
}

クックブックの準備は以上です

締め

散々書き込んだBerksfileですが、まだクックブックのダウンロードを行っていないので、やります

$ chef exec berks vendor cookbooks/

サーバーにchefを適用します。

$ chef exec knife solo bootstrap root@192.168.33.200

でエラーがでなければ完了

まとめ

さんざん書きましたが結局

やっていることは

  • セキュリティ関連のセットアップ(開発ユーザー作成、sudo権限付与、rootログインできないようにする、パスワードログインできないようにする、iptablesを設定)
  • Webサーバーとしてnginxを入れる
  • DB(MySQL)を入れる
  • Ruby(rbenv), Goを入れる

です。

実際に使う時は
site-cookbooks/site-user/recipes/default.rb
の公開鍵を編集

nodes/192.168.33.200.json
のmysqlのパスワードを編集

任意:sshのポートを変更する(ファイアーウォールの設定もしてね)

等を行う必要があります。

2015/06/19時点でインストールされたバージョン

ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
nginx version: nginx/1.9.2
mysql Ver 14.14 Distrib 5.6.25, for Linux (x86_64) using EditLine wrapper
go version go1.4 linux/amd64

参考

Chef実践入門
さくらVPSの初期設定をChefsoloでやってみた
ドットインストール