はじめに
Infrastructure as Codeとか言われますが、まぁそんな簡単にいかないです。
今から新規サーバを構築するのであれば良いですが、大体のところはすでに稼動しているサーバがあって、そのサーバは数年前に構築されたもので、その数円前はInfrastructure as Codeとかまだ流行ってなくて、地味な構築手順書が存在しててるが、更新されてるか微妙でちょっと調べてみたら案の定更新されてなくて、、、みたいなパターンがあると思います。
その場合、基本的にdiffをとって正解を定義して・・・一つ一つ正解をcode化して・・・という感じで地道にやっていくのですが、その際に知っておくと便利情報をまとめておきます。
下記で出てくるローカル(作業マシーン)は
- mac os x El Capitan
- バージョン10.11.3
コマンドで頑張る系
比較するファイルが単体で片方がローカル片方がリモートの場合
書き方1
ssh hostname cat /path/to/file | diff /path/to/file -
- diffに
-
オプションをつけるとファイルの代わりに標準入力を読むという意味 -
ssh hostname
でサーバにログインできる前提
書き方2
diff <(ssh hostname cat /path/to/file) /path/to/file
- hostnameにsshログイン後に
cat /path/to/file
を実行します
注意
- localにしかないファイルがある場合は気づけない
比較するファイルが複数で両方ともリモートサーバにある場合
for p in `ssh hostname01 'find /path/to/dir/ -name "*" -type f -print'`; do echo "---checkfile is ${p}---"; diff -q <(ssh hostname01 "cat ${p}") <(ssh hostname02 "cat ${p}"); done
-
hostname01
の/path/to/dir/
以下にあるファイルをhostname02
の/path/to/dir/
以下のファイルと比較する -
-prune
オプションを使って除外するファイルのパターンを設定するのもよし
比較するファイルが複数で片方ローカル片方リモートサーバにある場合
for p in `find /path/to/dir -type f -print`; do echo "---checkfile is ${p}---"; ssh hostname "cat /path/to/dir/${p}" | diff -c - ${p}; done
注意
- 都度sshしまくるのでサーバによってはDenyHostsにひっかり途中で止まる
- DenyHostsは簡単にいうとブルートフォースアタック(そうアタック攻撃)から守るもの
-
hosts.allow
、hosts.deny
の設定で特定のIPを除外する設定がある
-
比較するファイルが複数で両方ともローカルに置いている場合
diff -qr /path/to/dirA /path/to/dirB
-
q
は差分があった際はファイル名だけを出力、r
はディレクトリ配下を再帰的にdiffする - 手間だけど一番現実的
注意
- どちらか一方にしかないファイルも検出できる
ツールを使う
Ajimiを使う
- 同じような課題をCrowdWorksさんが持っていてblogで発信されてたのを発見しました
- ruby製
- 詳しい説明は上記のblogとgithubで
- chefで作られたものを味見するっていいですね。
注意
-
自分の環境(ruby 2.3.0)では下記のエラー?warning?が出力された
.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/net-ssh-2.9.4/lib/net/ssh/transport/session.rb:84:in `initialize':
Object#timeout is deprecated, use Timeout.timeout instead
* gemの`net-ssh-2.9.4`が原因のようでこれを3系にあげれば大丈夫っぽい
* 自分のmac(作業マシン)から`source:remote serverA`と`target:remote serverB`という環境で試した。
* remote serverのOSのバージョンとかの原因だと思うけど`sudo: sorry, you must have a tty to run sudo`的なエラーが発生してした
* `/etc/sudoers`の`Defaults requiretty`のコメントアウトをすれば行けた
# まとめ?感想的なもの
* やっぱり現場レベルでは同じような課題を持ってる人がいたんだなーっと
* まぁともあれAjimiを使えば良いと思う
* いろんな状況で運用しているサーバはたくさんあり、そのサーバ達を以下にモダンな仕組みへ変えていくかのノウハウ、Tipsは超現場感でてて大切っすね