in AWS, Server

誤ったrm -rf / / drop database / truncateから本番データを守る方法を考えてみた


すろっくさんです。

こんなニュースがあがってました。(追記;書籍執筆のためのネタだったそうです)

これはちょっと本番にログインできる権限をもつものとしては反応しなきゃでしょ!

てことで、本番データをもし誤って消してしまう場合に備え、ちょっと対応策を考えてみました。まあ完璧ってわけにはいかないですけど、参考程度に。

はじめに

本番データっていうのはこの場合サーバのディスク上にある実データ、そしてDBにあるデータになります。となると消す手段としてはLinux / Unixコマンドのrm -rf、DBだとdrop database / truncateとかですかね。最近はAWSのインスタンスを消すなどもその中の一つですね。

本番データを消す、というのは怖いです。サービスの重要性、このデータを消したら損害がでかいとか、そういうことを考えると本番上でこういった類のコマンドを発行するのはいつになってもヒヤヒヤものです。僕はLinuxを仕事で使い出して10年をすぎましたが、それでもいつでもハラハラドキドキです。

僕は仕事でAWSを使わせてもらってるんですが、AWSとLinuxの小技を含めて誤った削除から本番データを守る、もしくは消してもすぐ復旧できる手段を考えてみました。

ちなみに僕が勤めてるBASE株式会社ではこんな求人を出してますのでもし興味あればご飯いきましょう。宜しくお願いします。

前置きおわり。では行きますー。

本番データの入ったインスタンスの削除

すごい身も蓋もないんですが、AWSのEC2 / ECSなどのクラウドのインスタンスやコンテナを運用するときは「サーバをいつでも削除してもいいようにしておく」つまり削除してもすぐ復旧できるようにしておくっていうのがいいと思います。構成だけの問題ならamiを取得してイメージを取っておくのがいいと思いますし、ログの保全が、というのであればログは常にS3などの耐久性 / 可用性の高い外部ストレージにアップする体制がベターです。(自分でデータを吹っ飛ばす可能性が99.999999999%ないならさておき)

重要なデータは外部ストレージに、というのが定番かな。サーバは壊してもすぐ復旧できるように作り治せるようにしておくと精神的に楽です。

amiを作ってないのであれば、構成はChef / Puppet / Ansibleなどで常に自動構築しておく体制にしておくといいです。こちらはRubyやYamlなどで設定を記述することでその通りにサーバを構築してくれるツール群です。Gitに登録しておけば変更履歴も終えますし、インスタンス立ててすぐにサーバを作れる体制にしておくのが良いと思います。

またAmazon EC2にはインスタンス作成時に「誤った削除から防ぐ」というオプションがあるので、どうしても消したくないインスタンスはそのオプションを有効にしておくといいです。コンソールから間違ってterminateしてしまったときなどに有効です。

設定関連の削除 / 変更

これは僕も以前は割とやらかしてたんですが、設定関連の削除 / 変更してもとにもどせないあばあばばばってなるんですが、最近は構成管理ツール経由でしか設定の変更や削除は行わなくなりました。結構楽です。

ここで一番怖いのは作業履歴が残らないことです。例えば/etc/nginx/nginx.confのバーチャルホストをサーバ上で変更しても、ログアウトしてしまえば誰が作業したかは残りませんし、前どんな形だったかというのを作業した本人も忘れることもあります。

なので設定関連は構成管理ツールで書き、Gitに構成管理のレシピやマニフェストを登録しておくのが一番です。そうすることで誤った変更がサーバにはしることを防ぐことができます。冪等性の維持はすろっくさんはサーバをいじるときはとても大事にしています。

Linux / Unixの削除コマンド実行

これは僕が昔上司から教わったんですが「rm -rf」を「mv .~/Trash」といったフォルダにものを移すmvコマンドに変更するってやり方ですね。どうしてもクリティカルなコマンドはこうしておくと慰めになるかもしれませんがなんかホッとします。

その前にサーバにデータをバックアップする、設定関連は定期的にS3などの信頼性のある外部ストレージにあげるといったことをやっておくといいと思いますけども。

あとはサーバ本体の定期的なamiの取得ですね。ただAWSのイメージ取得は「再起動させない」オプションを有効にしてしまうと、時々サーバの中身のファイルが0KBのイメージができてしまうことがあるようです。なにも動いていない状態を作るのが結構難しいので、再起動必須くらいのノリでやっちゃうほうがいい気はします。

どうしてもサーバ上に置いとかないといけなさげな重要なデータについてはcronで定期的にS3に日付のプレフィックスをつけてアップロードしていくといいと思います。もしあまり古すぎるデータはGlacierに移行させてあげると料金的にもいい感じになりそうです。(古すぎデータの復旧にお金かかるので注意ですけども)

設定ファイルは構成管理ツールで管理するのがベストかなーと個人的には思います。自社プロダクトで一番いいのはデプロイも構成管理ツールでやらせて、自動化してしまうと楽だと思います。デプロイと同時にサーバの冪等性が維持されるので、イメージを取得したら最新かつ正しいサーバができあがりますし。

ログや重要データは外部ストレージにバックアップする、を心がけたいですね。

drop database / truncate / drop table

本番データを入ってるデータベースでいらないやつを指定して消そうとしたらこれをやらかすってあるある話な気もします。あとはrake db:migrate:resetみたいな全部消してスキーマだけつくりなおすとかですね。僕は過去にrakeでやらかしました。

ここはバックアップを事前に取ってから削除でしょうね……。DBを削除系するときはメンテナンスをちゃんといれて、バックアップを走らせてからやりましょうね……本番はとくに。

RDSだと何日ごとにバックアップをとるっていう設定があるので、そこを有効にしとくといいです。ただあれスナップショットからは新しいインスタンスを作る以外の選択肢がないので、mysqldumpのノリで触ると辛いです。mysqldumpはdumpで別なサーバでやって、それからダンプしたファイルをS3にあげましょー。

SSHは極力しない

極論これです。SSHはしない / させないを徹底する。設定変更は構成管理ツールから、デプロイも構成管理ツールから、あとはAWSのロードバランサーにぶら下げるなどだけ。みたいな。

トラブルのときにSSHするかもしれないけど、他はなくす。

本番にSSHしなければデータを消すことはありません。あと実際SSHしたいっていう場合もそんな大した理由なかったりします。SSHしたいっていう話があったらちゃんと話を聞いてあげて、問題がないかどうか確認するといいでしょう。

気をつける / 頑張る”だけ”はNG

精神論になるんですが、気をつけるや頑張るだけではNGだと思います。なんていうか、優秀なエンジニアだってポカミスするし、頑張ったところでどうしようもならないものがいっぱいあるからです。

製造業とかだと気をつけないと指が飛んだりすると思うんですが、IT / WEBの良いところは事前に対策をたくさんしておけば可能性は低くできるし、最悪消してしまったとしても以前の状態に復旧することが可能だということです。気をつける以外に選択肢がない場所より全然楽だし、まだまだなんとかできると思います。気をつける、頑張るで思考停止しないで済むのでいいですね。全然健全です。

気をつける / 頑張るって口に出すとそれだけでその先の具体性を考えられなくなる時があって、一種の思考停止に陥りがちなんですよね。その先をちゃんと見据えながら考えながら次の行動を決めていけるととても成長していけるんじゃないかと思います。

そして失敗を恐れてなにもできなくなるより、失敗してもリカバリーは可能という安心感、そしてその安心感からくる前進のための気持ち「失敗を恐れるな」っていう気持ちのほうが僕はだいじかなーと思います。もちろん本番データを消すのは怖いですし、そのための対策をたくさん打った上で、自分にできる最大の注意と努力の上での削除コマンドであってほしいです。

ただ、得てしてそういた対策や改善のための作業はプライオリティが低くなりがちです。そう言ったところを拾っていって、周囲が安心して作業できる環境を作っていくのが僕の、SREの仕事なんじゃないかと思ってます。

終わりに

結構ながくなっちゃったなー。もちろんまだまだ書きたいこととかあるんですけど。

技術的なこととかはそのうちどっかにまとめておくので、そのときにでも。

読んでくれた人のお役に立てれば幸いです!