Hatena::ブログ(Diary)

naoyaのはてなダイアリー

December 15, 2013

Infrastructure as Code

今年の3月に 入門Chef Solo - Infrastructure as Code という本を書いた。

その名の通り Chef の入門書なのだけど、このサブタイトルは "Configuration Management Tool (構成管理ツール)" でもなく "Provisioning Framework (プロビジョニングフレームワーク)" でもなく、はたまた "Automated Infrastructure (自動化されたインフラ)" でもなく、"Infrastructure as Code" にした。

この一年で Chef や Puppet にはずいぶんと注目が集まった。おそらく、AWS をはじめとするクラウドサービスがより広いユーザーに浸透したことで仮想化環境が前提になって、以前よりも頻繁にサーバーを構築し直したりする機会が増えたとかその辺がひとつ理由として挙げられると思う。頻繁にインスタンスを作りなおしても、その作業が再生可能になっていれば気に病む必要はない。Chef で手作業だったサーバー構成を自動化できた、良かった・・・という声を良く耳にするようにもなった。

確かに自動化されてハッピー。ただ、自分としては Chef / Puppet などの道具を使ったときにもっと重要なことがあると常々思っている。それを "Infrastructure as Code" というサブタイトルに込めたつもりだった。ん、どういうこと?

そこのアナタ、Infrastructure as Code ですよ!!

この Github の Pull Request をみると、すぐ伝わる。伝わることを期待する。

f:id:naoya:20131215145006p:image:w640

これは dstat というソフトをサーバーにインストールするための Pull Request である。サーバーにソフトを入れましょう、という話なのに github の上でやりとりが行われているではないですか。

作業手順が全部コードになる

Chef や Puppet などの構成管理ツールを使うと、サーバーの構成変更にまつわるあらゆる作業はプログラムコードになる。まあ、コードになるといっても

package "nginx" do
  action :install
end

service "nginx" do
  action [ :enable, :start ]
end

こんな程度で、設定ファイルを書く程度のものでそんな大袈裟なものではない。

さて、今まで手作業でやってたことが全部がコードになった。だったら git に入れてバージョン管理すればいいじゃない。git に入れたなら、github を使えばいいじゃない。github を使うなら Pull Request ベースでコードを構成すればいいじゃない。あれ、気づけばインフラも Social Coding できてしまった。

あれあれ、これってワークフローの変革ではなくって?

インフラもコードレビュー

次のスクリーンショットも見てみよう。

これは先日 最近のWebサービス開発現場では Github やなんやを使って開発しているよ、というエントリ の中でも紹介した株式会社じげんでの、実際の現場の Github の様子。

じげんでは数ヶ月前からサーバーの構成管理に Chef を使うようになった。そして、コード化されたものはすべて Github に突っ込んで、Pull Request ベースでその変更を回すようにしている。

f:id:naoya:20131215144824p:image:w640

「あのサービスの nginx の設定をこんな感じで変えましょう。」「コードできたし push しました。この変更で大丈夫か。レビューお願いします」「大丈夫だ、問題ない。マージして反映します」・・・的な流れ。作業の履歴はすべてバージョン管理され、レビュー結果は Pull Request の中に残る。

次の方がもっと生々しくて面白いかも知れない。インフラチームに配属になったばかりの新人が、構成変更手続きを先輩にソースレビューしてもらって、指摘事項を徐々に修正しながら進めていっている様子。

f:id:naoya:20131215150446p:image:w640

昨今、コードレビューは、品質の保証だけが目的ではない。pull request を利用した開発ワークフロー // Speaker Deck このスライドから引用する。

f:id:naoya:20131215151414p:image:w640

チームに配属されたばかりの新人が、Pull Request によるインフラ構成変更作業に伴うレビュー通じてその会社でのやり方、基準を共有される。

従来のサーバーの構成変更といえば、インフラ担当みたいな人が依頼を受けて手作業でやっているというのが普通だった。ちゃんとしているところは作業記録をドキュメントに残したり、それを共有することでその後のオペレーションミスが発生しないようにと注意してると思う。でも、世の中の8割方、多くの場合そんなにきちっとしていなくって、担当が書き換えてそのまま、何がどういう設定になっているかは作業した本人も数週間後には忘れていて実際のサーバーみないと分からないとかそんなもんだと思う。

それじゃあ流石に拙いよね。でも、人手で頑張ってドキュメント残して気合いと根性でカバーする・・・というのじゃあ流行らない。

仮想化されてハードウェアもソフトウェアみたいになったんだし、だったら作業手順も全部コードにしちゃえば、そういう問題も解消されるんじゃないかというのを突き詰めたらここまで来た。

「インフラをコードで構成する」と聞くとまず第一には自動化される・・・ということがやっぱり思い浮かぶかも知れない。でも、そのうま味がもし自動化だけだったら、サーバーが1台2台しかないような環境にはまったく魅力的に映らない。作業手順がコードになるということは、それが(再生可能な形で)ちゃんと形に残るということである。形に残っているから、git や github で管理できる。いちいちサーバーに見に行かなくても、github 上で何がどうなっているか見ることができる。アプリケーション開発の世界で日常的に行われつつているワークフローを、インフラチームも取り入れることができる、というわけである。

インフラの継続的インテグレーション

おっと大事なことを言い忘れていた! (わざとらしい)

先の Pull Request のここに注目いただきたい。

f:id:naoya:20131215151800p:image:w800

"Your test passed on CircleCI" で緑色。これは、この Pull Request により変更されるであろう箇所にテストを適用した結果だ。テストと言ってもこれはもちろん人手ではなく、serverspec を使って Rspec で書いたものが、Jenkins や CircleCI のような継続的インテグレーションの仕組みによって自動的に行われる。

インフラに何か変更を加えたい、というのを Pull Request すると、その Pull Request を感知して CI サーバーが自動でその内容をテストする。テストは Vagrant によって新規の仮想サーバーが立ち上がり、その Pull Request 変更の内容含めすべてのサーバー構成コードを実行した上で、試験される。サーバーに変更がある度、新しいサーバーを一度作ってすべてのテストを流す・・・インテグレーションテストが行われる。これらのテストの起動や報告は CI サーバーと Github が連携して自動で行われる。開発者はいつものレポジトリにテストとコードを git push するだけ。何か問題があったら当然、Pull Request は赤色になり、そのままマージすると問題が起こることがわかる。

設定ファイル一行書き換える度にサーバー作り直してテスト、なんてことは人手でやってたのでは絶対無理だった。

この界隈の第一人者であろう @ryuzee のネタを借りると、テストをせずに本番環境に変更を加えることは、エイヤっと清水の舞台から飛び降りるようなものだ。インフラの世界ではまあそういうことが日常的に行われているような現場も多く、みんなびくびくしながら清水の舞台からジャンプしていた。で、たまに事故ってお客さんのデータを全部消去してしまいましたバックアップもありませんでした・・・みたいな悲劇が起こったりしている。

そうではなく石橋を叩いて渡りましょう。でも、石橋を叩いた結果、牛歩で歩かないといけないのは嫌だ。だったら超高速に石橋を叩けばいい・・・ そこでインフラの継続的インテグレーション。

これもインフラがコードになったからできる芸当である。

先の、じげんでは Jenkins + Github pull request builder + Chef + serverspec でこのワークフローを実現している。

改めて Infrastructure as Code とは

"Infrastructure as Code" というのはこういうことで、単にサーバー構成変更を自動化しましょうという話ではなく、インフラをすべてソフトウェアとして、コードで扱うことでアプリケーション開発で行われてきたいろいろな "ワークフロー" をインフラ作業の世界にも導入しましょうねと、そういうことであります。

f:id:naoya:20131215155545p:image:w640

なので、せっかく Chef や Puppet を使っても、ただ自動化するだけのために使うのではその御利益の20%も享受できないし、Chef や Puppet をただの自動化ツールとして見て「オーバースペックだし要らない」とするのも、ちょっと待った! というものである。Infrastructure as Code、という部分まで含めてみてなお自分のプロジェクトにはオーバースペックだと思ったら、それはまあ必要ないでいいのだけど。

蛇足: Immutable Infrastructure との関係

この話、Immutable Infrastructure/Disposable Infrastructure の文脈での話にもちょっと関係してくる。

最近「Immutable Infrastructure になったら冪等性とかもう大袈裟だし Chef / Puppet みたいなのは要らないよね」みたいな声を聴くことがあるけど、Configuration Management Tool の本質的なところはここまで述べたようにワークフローに変革をもたらしたことであって、その部分を無視して必要/必要ないという話をするのは早計。

「冪等性とかオーバースペックな部分は必要ないけど、Infrastrcture as Code なワークフローは維持したい」というのが良い問いで、その際、新しい Configuration Management Tool の登場を期待するのか、Chef/Pupplet をそのまま使うのか、(あるいは Docker 前提なら Dockerfile だけで十分なのか) とかそういう風に見ていくべきではないか、と思います。

それにしても、Infrastructure as Code って口に出したとき噛む頻度は異常。