--- categories: "Chef solo" comments: true date: "2014-05-30T00:00:00+09:00" title: "chefでさくらVPSの初期構築を全部自動化してみた" --- Chefでサーバー構築を全部自動化して、借りているさくらVPSに当ててみた。意地でも手作業はまったく入れない完全自動構築設定。これはよい。毎回手作業やらずに済むというのは、抜け漏れをなくすという点でも、構築時間を短縮するという面でも本当に楽。 ## 前提 今回構築するサーバーの前提は次の通り。 * CentOS 6.4環境で試行 * vagrantを使って試験後、さくらVPSに対して適用 * 基本の設定として以下を実施 * 構築用のユーザーを作成 * 構築用ユーザーにsudo権限を付与 * 構築用ユーザーを秘密鍵認証でsshログイン許可 * rootによるsshログインを禁止 * パスワード認証によるログインを禁止 * sshのポート番号を変更 * ssh, http以外のアクセスをiptablesでシャットアウト * nginxを導入 * 将来的にunicornを入れるための設定を準備 * 極力サードパーティクックブックは使わない(ブラックボックス化が嫌) ## レシピ まず「どんなサーバーだろうとまず実行するだろうセキュリティ上の設定」はdefault_tasksというレシピにまとめた。 ### default_tasks ``` # sshdサービスの有効化 service "sshd" do supports :status => true, :restart => true, :reload => true action [ :enable, :start ] end # sshd_configの配置 template "sshd_config" do path "/etc/ssh/sshd_config" source "sshd_config.erb" owner "root" group "root" mode 0600 notifies :restart, "service[sshd]" end # iptablesの設定 iptables_rule "iptables" ``` sshdの有効化と、templateを使ったsshd_configの配置、そしてiptablesの設定。このうちiptablesについてはサードパーティ・クックブックを使っている。 [opscode-cookbooks/iptables](https://github.com/opscode-cookbooks/iptables) iptablesに挿入したい内容をtemplateで用意し、`iptables_rule "template name"`の形でレシピ内に書き込んでおくと、templateの内容がそのままiptablesに追加されるというシンプルなレシピ。まぁ、これぐらいはサードパーティ使ってもよいかな、と。iptablesを丸ごとtemplate化してアップロードするという手もあるにはあるのだが。 sshd_configはCentOSから引っ張ってきたものをそのまま流用し、Attributesを使っていろいろと書き換えられるように仕込んだ。長いので割愛するけど、設定可能なAttributesはこんな感じ。 ``` "sshd" : { "Port" : 22, "MaxStartups" : 10, "PermitRootLogin" : "yes", "RSAAuthentication" : "yes", "PubkeyAuthentication" : "yes", "AuthorizedKeysFile" : ".ssh/authorized_keys", "PasswordAuthentication" : "yes" }, ``` よく編集する箇所を中心にAttributesとしてみた。他に設定したい項目が増えたら随時足していけば良いかなと。 ### users ユーザーの作成は別のレシピに切り分け。 ``` # wheelグループの作成 group "wheel" do gid 10 action :create end # data bagsよりユーザーを作成 data_ids = data_bag('users') data_ids.each do |id| # ユーザー作成 u = data_bag_item('users', id) user u['username'] do password u['password'] supports :manage_home => true, :non_unique => false group u['group'] action [:create] end # ssh公開鍵配置用のディレクトリ作成 directory "/home/#{id}/.ssh" do owner u["id"] group u["id"] mode 0700 action :create end # ssh公開鍵の配置 file "/home/#{id}/.ssh/authorized_keys" do owner u["id"] mode 0600 content u["key"] action :create_if_missing end end ``` sudoを許可するユーザーをwheelグループに入れるという定番設定。wheelを実際にsudo許可するのはまた別のレシピの仕事で、ここではグループとユーザーの作成のみ。 ユーザー作成にはdata_bagを使った。[こちら](http://girigiribauer.com/archives/1066)を参考として作っている。ポイントとしては公開鍵まで登録させていること。fileリソースを使って実にシンプルな配置の仕方だけど、非常に楽ではある。 あまり詳しくは知らないのだが、data_bagについては暗号化する方法があるみたいなので、公開鍵を生でべろっと貼っとくのが気になる場合はそのへんも仕掛けておくと良さそう。 ### nginx 一番苦労した気がするし、あまり美しくない。。。 ``` # nginxインストール package "nginx" do action :install end # nginx有効化 service "nginx" do supports :status => true, :restart => true, :reload => true action [ :enable, :start ] end # templateからnginx.confを配置 template "nginx" do path "/etc/nginx/nginx.conf" source "nginx.conf.erb" owner "root" group "root" mode 0644 notifies :reload, "service[nginx]" end # ディレクトリ作成 directories = ["/etc/nginx/sites-available","/etc/nginx/sites-enabled","/var/www","/var/www/#{node['nginx']['root']}","/var/www/#{node['unicorn']['root']}"] directories.each do |directory_name| directory "#{directory_name}" do owner "root" group "root" mode 0644 action :create end end # sites設定をtemplateごとに実行 node['nginx']['nginx_sites'].each do |site| # templateからsites-available配下に設定ファイルを配置 template "nginx_sites_available" do path "/etc/nginx/sites-available/#{site}" source "nginx/#{site}.erb" owner "root" group "root" mode 0644 end # sites-enabled配下へシンボリックリンクを配置 link "/etc/nginx/sites-enabled/#{site}" do to "/etc/nginx/sites-available/#{site}" link_type :symbolic action :create notifies :reload, "service[nginx]" end end ``` インストール、サービス有効化、templateからのnginx.confアップロードまでは良いとして。ディレクトリ作成がなんか。。。汚い。。。 /var/wwwを掘って、その中にウェブサイトのルートを置いたり、バーチャルホストの設定でsites-availableとかその辺を使っているもんで、ディレクトリ作成の量が多くなってしまった。いずれも設定は同じなので配列でやるのがベターだとは思うのだが、どうにも汚い。なんとかしたいとこではある。 あとはsites-availableにtemplateから設定ファイルを配置して、linkリソースでsites-enabledにシンボリックリンクを貼って終了。nginxの使い方はsites-availableを使うパターンだけではないので、もう少しスッキリさせることはできそう。 ## サードパーティ・クックブック サードパーティとして導入したのはさっきのiptablesと、sudoの2つ。 [opscode-cookbooks/sudo](https://github.com/opscode-cookbooks/sudo) sudoはvisudoを`execute`で走らせるってのも怖いし、その後ファイル編集をどうやったらいいのかよくわからんなってのと、sudoresファイルをtemplateで上げるってのもちょっと怖いという感覚的な問題からサードパーティ採用とした。 使い方としては簡単なもので、変数でsudoを許可するユーザーやグループを指定して、passwordlessとするかどうかを設定するぐらいで終わり。 ``` "authorization" : { "sudo" : { "groups" : ["wheel"], "passwordless" : "true" } }, ``` 冒頭でも書いた通り、なるべくサードパーティを使わない方針で行きたいんだけど、自力でレシピを書けないor書く自信がないところは已むなく実績のあるサードパーティを使ったという感じ。まぁサードパーティと言っても結局は人の手で書かれたレシピなので、自分でchef力上げれば相応なレシピは自力で書けるはず。このあたりは結局「どこまでchef力の向上に時間を割くか」という部分とトレードオフになるのかと。 ## 今後やりたいこと 最終的にこのサーバーではRails動かしたいので、Rubyやpostgresqlのインストールを今後実装したい。あと「取りあえず動けばいいや」路線で一度作ってしまったので、もう少しメンテナンス性の高いもの、読みやすいレシピには育てたいところ。 汎用的に誰でもどんな用途でも使えるって感じではないと思うが、とりあえずGitHubには上げてみた。秘伝のタレのようにこれをじわじわ育てていくというのは良いなぁ。Linuxの勉強をするごとにきっと強靭なレシピとなっていくのだろう。まさに「レシピ」だな、これは。 まずは静的なページをってことで、近日中にプロフィールでも置いて公開する予定。 [https://github.com/chroju/chef_web_server](https://github.com/chroju/chef_web_server) ## 参考 * [さくらVPSの初期設定をChef Soloでやってみた〜サードパーティcookbookの使い方〜 | tsuchikazu blog](http://tsuchikazu.net/vps_chef_solo/) * [Chef Soloと Knife Soloでの ニコニコサーバー構築 (4) ~コツ編~:dwango エンジニア ブロマガ:ドワンゴ研究開発チャンネル(ドワンゴグループのエンジニア) - ニコニコチャンネル:生活](http://ch.nicovideo.jp/dwango-engineer/blomaga/ar334285) * [入門Chef-Soloを片手にRailsアプリを動作させるところまでやってみた - プログラミングノート](http://d.hatena.ne.jp/ntaku/20130324/1364132658) * [単純な環境構築を知る -Chefでiptables書き換え- - 技術いろいろ勉強メモ](http://m-tkg.hatenadiary.jp/entry/2013/12/12/151254)