Fire Engine

消防士→ITエンジニア→研究者

Terraformでインスタンスの停止ができない理由を考えたらInfrastructure as Codeへの理解が深まった話

こんにちは、筋肉系インフラエンジニア見習いのつるべーです。
私は今、GMOペパボ株式会社でペパボカレッジという第二新卒エンジニア向け研修を受けている真っ最中です!
今回のエントリーは、私が研修中に感じた素朴な疑問を会社のコミュニケーションツールに書いたら、そこから議論が広まって、最終的にはInfrastructure as Codeという重要な概念への理解を深めることができたよ、という話です。

Infrastructure as Codeって?

Infrastructure as Codeを一言で表すと「コードによりインフラの管理をすること」です。
コードで管理することのメリットとしては、

  • コードのバージョン管理ができる
  • 設定変更の適用前にプルリクエストベースで確認が行える
  • 設定の共有・再利用が容易である
  • オペレーションミスが防げる
  • インフラ構築の属人化が防げる

などが挙げられます。
現在、Infrastructure as Codeを実現するためのツールは、Terraform、Puppet、Ansibleなど数多く存在し、それぞれがコード管理をしたい対象のレイヤーが異なっていたりして、非常に複雑なため、その点については下記のブログが大変参考になります。

インフラ系技術の流れ - Gosuke Miyashita

サーバのプロビジョニングを「Orchestration・Configuration・Bootstrapping」という3つのレイヤーで分けて説明されている点がとても参考になりました。

問題提起

今回はタイトルにもあるようにTerraformというツールについての話です。(ツールに固執した話ではなく単に考えるきっかけがTerraformだった)
TerraformはHashiCorpが開発している「インフラの構築・変更を効率的に行うためのオーケストレーションツール」です。AWSにおけるCloudFormationのような存在です。

www.terraform.io

Terraform独自のテンプレートにインフラ構築に必要な各種リソース(インスタンスやネットワークなど)を定義し、適用のコマンドを実行すると、定義したインフラの「あるべき姿」を再現してくれます。私は、Terraformを使って実際のWebサービスを想定したインフラを構築する研修を受けていました。
Terraformでは、定義ファイルを書いてterraform applyとコマンドを叩くと定義した全インスタンスが立ち上がって、terraform destroyとコマンドを叩くと立ち上げた全インスタンスが削除されます。
ここで一つ疑問が湧きました。インスタンスの起動・削除はできるけど、インスタンスの停止は??
terraformコマンドのオプションを見てみると、(一部省略)

$ terraform --help
Common commands:
    apply              Builds or changes infrastructure
    console            Interactive console for Terraform interpolations
    destroy            Destroy Terraform-managed infrastructure
    env                Workspace management
    fmt                Rewrites config files to canonical format
    get                Download and install modules for the configuration
    graph              Create a visual graph of Terraform resources
    import             Import existing infrastructure into Terraform
    init               Initialize a Terraform working directory
    output             Read an output from a state file
    plan               Generate and show an execution plan
    providers          Prints a tree of the providers used in the configuration
    push               Upload this Terraform module to Atlas to run
    refresh            Update local state file against real resources
    show               Inspect Terraform state or plan
    taint              Manually mark a resource for recreation
    untaint            Manually unmark a resource as tainted
    validate           Validates the Terraform files
    version            Prints the Terraform version
    workspace          Workspace management

stopやpauseがないんですね。起動や削除はできるのに停止ができないのはなんでやねん!!ってなったわけです。
そこで社内のコミュニケーションツールで質問してみました。

つる「TerraformのCLIからインスタンスの停止ってできないんですか?」

すると・・・ペパボのハイパーエキセントリックボウイな先輩方が

「Terraformの役割をちゃんと説明できますか?」

インスタンスを停止したい理由がなぜかを考えてみては?」

「サーバのライフサイクルの観点から考えてみては?」

オライリーの『Infrastructure as Code』を読んだ方が・・」

「上のようなことがわかるとなぜTerraformで「インスタンスを停止する」操作をしないかが自分の言葉で言えるようになるかも」

などとありがたいコメントをいっぱいくれたわけです。これをきっかけに、私なりに色々考えた結果が今日のメインの話です。(素朴な疑問にこれだけ反応してくれる環境って最高ですよね?)

注意点

  • Terraform以外の他のツールがインスタンスの停止ができるのか?というところは知りません。したがって、議論のきっかけは汎用性に欠けるかもしれませんが、そこから得られる議論や考察には一定の汎用性があると思っています。

  • 後述の話はあくまで私の考察です。実際にTerraformが何かしらの信念をもって敢えて「インスタンスの停止を実装していない」のか、そこまで深い意味がないのかどうかは知りません。ただ、色々考えると、停止って別になくてもいいよねってなりました。(インスタンス停止が絶対ダメ!という話ではない)

  • 今回のサーバとインスタンスはほぼ同じ意味で使っています。

自分なりの考え

解釈が間違っていたり、他にも考えをお持ちの方はビシバシ指摘してください!

Terraformの役割は何か?

Terraformはインフラストラクチャの定義をコードで管理するオーケストレーションツールです。ここでいうインフラストラクチャは通常、相互に関連し合う様々なスタックから構成され、Terraformはこれらの複数のスタック構成を「ある状態」に収束させるためのツールであるともいえます。
つまり、Terraformの役割は、単体のサーバの管理ではなく、サーバーの集合体(クラスタ)を管理する役割です。これは「オーケストレーション」という言葉のそもそもの意味からも言えそうです。

オーケストレーションとは複雑なコンピュータシステム/ミドルウェア/サービスの配備/設定/管理の自動化を指す用語。(Wikipediaより)

とあるように「複雑な」システムの管理等が目的であるため、単体のリソースに着目するものではないと言えます。
このことから、Terraformでは「ひとつだけのサーバを停止する」ような操作を用意していないのかもしれません。じゃあ全台一気に停止するようなコマンドはあってもいいのでは?

サーバを停止したいのはなぜか?

「サーバを停止したいのはなぜか?」を考えると、それは「サーバの構成/設定を変更したいから」です。
Infrastructure as Codeの意義はインフラストラクチャの定義をコードで管理することで、「統一的な」管理ができる点にあります。そこに対して、サーバを停止して手作業で設定変更を行うなどといった管理されていない変更を許すと、統一的な管理が失われ、構成ドリフトやスノーフレークを招く恐れがあります。そのため、オートメーションの外からサーバに変更を加えることを認めてはなりません。これがTerraformからインスタンスの停止ができない理由の一つだと考えます。

サーバの変更管理モデルについて

ただし、インスタンスの停止ができないからといってオートメーションの外からの管理されていない変更を完全に排除することにはなりません。ここで、サーバの変更管理モデルにまで話を深めていくと、「Immutable Infrastructure」という考え方があります。これは、サーバの構成/設定を変更する際に、既に動いているサーバに対して変更を加えるのではなく、変更が加えられた全く新しいサーバを構築する手法です。これにより、オートメーションの外から加えられた変更を打ち消すことができ、構成ドリフトなどを防ぐことに非常に有効です。
このように昨今のインフラ、特に仮想化技術やクラウド技術が使われたインフラにおいては、「サーバのライフサイクルを短く保つこと」が求められています。こういった背景も、Terraformでインスタンスdestroyはできるがstopができない理由の一つかもしれないと考えました。

さいごに

今回のことを考えているうちにInfrastructure as Codeって本当におもしろいなーって思いました!ここに昨今のコンテナ化技術の議論が入っているとさらに奥が深くなりおもしろそうですね。私は今回の一連の議論からInfrastructure as Codeに非常に興味を持ったので、これからも勉強していきたいと思います。
あと、Twitterにも書いたのですが、

こんな成長できる環境に身を置けることが心から幸せです。以上、最後まで読んでいただきありがとうございました!

参考

Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス

Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス