BFT名古屋 TECH BLOG

日々の業務で得た知識を所属するエンジニアたちがアウトプットしていきます。

【自動化】IaC (Infrastructure as Code) が合うもの、合わないもの

こんにちは! BFT名古屋支店の佐野です。
例年と比べて一際寒い今冬。冷え込んだ空気に震える毎日で、山側では既に雪が降り積もっているとの報も聞こえてきています。
暖冬から一変したと感じると同時に、スノーボードが趣味の私としては久々のふかふか積雪にわくわくもしています。
もう間もなく、2022年も終わりです。

さて色々波乱があった1年でしたが、その1年の中で私が特に増えたなと感じたのが「自動化」に関わるお話です。
これまで私の記事では構成管理ツールのAnsibleを使った仮想マシン構築や、AWSでEC2やRDSを定刻に自動起動・自動停止するといった、簡単な自動化に関する話を紹介してきました。
しかしそれらは既にある環境での一部の処理を自動化するまでの限られた領域の話に留まっています。
対して今回テーマとして挙げたIaCは「環境そのものの構築を自動化する」システム構築の根本から関係するものです。
環境構築を自動化するIaCをした場合どうなるのか、本当に必要なのかも含めてお話していきます。


はじめに:そもそもIaC (Infrastructure as Code)って?

まずIaC (Infrastructure as Code)とは、サーバやネットワークを始めとしたシステムインフラの構築と管理をコードを用いて行なうことです。
コード化したインフラの構成を構成管理ツールを使って実行すると、その内容に従って自動で環境が構築されます。
構築自体をすべてコードによるものとして自動化することで、手動による構築で発生しがちなソフトウェアのインストールや各種設定時の手順誤りや設定間違いを避けられるのです。

これだけだと構築作業を単純に自動化したように見えますが、この構築という作業にはバージョン管理やリソース追加、更新といった運用の要素や、テストの要素も入っています。
コード自体を変更して再実行すれば、追加や更新の部分だけがが反映されますし、テスト用のコードを書けば動作確認などのテストも構成管理テストツールによって自動化可能です。

IaCは今まで手動で行なうしかなかった構築作業の大部分を自動化できるため、一度コードを書いてさえしまえばその後の構築と管理の工数を削減できます。
また人の手が入る余地が少なくなるため、その分人為的でチープなミスを大幅に減らせるのです。

ただ「コードを書いてさえしまえば」と簡単に言えるものの、実際にはその工数や学習コストによって頓挫してしまうケースもあり、また投入したコストに対して十分な見返りを得られないような場合にはIaCではなく手動の構築を選択した方がよいケースもままあります。


IaCが有用になるシーン

ではIaCの効果が発揮され、有用となるシチュエーションはどういったものがあるのか。
主に利用するとよいシーンの具体例は以下が挙げられます。
(それらのシーンで手動での作業を行なう場合にどうなるかも併記します)

  • 初期構築の時に構築するサーバの台数が数十~100台以上ある場合
    最初に数多くのサーバを構築・展開する必要のあるシチュエーションは、自動化の利点が最も分かりやすく発揮されるポピュラーなケースです。
    これを手動で行なうなら全台をひとつずつ作るか、あるいは大本となるサーバ1台を作り、それを元にクローンを展開しつつ差分があるところは手作業で設定するといった作業が必要です。
    当然ですが作業量と工数はとても多くなり、現実的とすら言えなくなるかもしれません。
    IaCによる構築ならば、コードに作成するサーバのOS設定やネットワーク設定を記載して実行すれば、その通りに全台の作成を行なえます。
    大半の設定が一致しない、ほぼ完全に異なるサーバを多数作る場合はコードの記述も大変になりますが、そうでない場合はコピー&ペーストなどの手段で大幅な時短を図れます。
    またコードの通り作成されたサーバは、手動で作成した場合と違って間違いなくコードに設定されたパラメータ通りに作成されます。
    当然ではありますが、それによって人の手で繰り返し作業を行なっていると起きがちな無意識のチープミスは起きないと言えるため、構築したサーバの確かさの証明がしやすくなります。

  • 単体テストの項目が数千項目ある場合
    構築したサーバが設計した通りに構築できているか、想定通りの機能を動かせるかといった単体テストは、初期構築の中でも多くの時間を要するシーンのひとつです。
    手動で構築したサーバに対して単体テストを行なうならば、手動で構築した全台がすべて設計通り・想定通りであるかをひとつひとつ確認しなければいけません。
    人の手で構築している以上、無意識のチープミスを疑わなければならないからです。さらにはテストを確かに行ったことを証明するエビデンスの取得も必要です。
    そしてテストの項目が数千もあるとなれば、すべてのサーバに対するテストの時間はこれまた気が遠くなる程となってしまいます。
    しかしIaCによって自動構築したサーバであれば、ひとつのサーバに対して設定されている値は他のサーバでも同じと言えます。自動で構築している以上、人の手で発生する“ゆらぎ”は無いからです。
    加えてIaCであれば、この単体テストも自動化できます。テストケースをコード化したものを構成管理テストツールで実行すれば、テスト対象の各設定が問題ないかどうかを自動でチェックできます。
    台数と項目数、そのふたつの軸の両方から時短が図れるのは、IaCで環境構築を自動化する大きな利点と言えるでしょう。

  • 構築途中で仕様変更や設計ミス、考慮漏れによって構築したサーバ全台に設定変更や追加が必要となった場合
    構築の段階でミス無く作業ができていたとしても、その前の段階である設計から変わってしまった場合、その変更内容を構築したすべてのサーバに適用しなければなりません。
    手動で環境を構築していたのであれば、ひとつの変更を手作業で適用するだけでも大変な労力がかかりますし、その上で再度単体テストが必要です。
    IaCで構築した環境であっても同様ですが、IaCの場合は変更対象となる部分のコードだけを変更し、再実行するだけで構築した全台への変更反映が行われます。
    IaCによる自動構築は冪等性(べきとうせい、同じ操作を何度繰り返しても、同じ結果が得られるという性質)を持たせるのが前提であり、同じコードを何度実行しても構築は変わりません。
    二重に実行したとしても余計なサーバが作られるといったことはないのです。
    そしてコードが変更された場合、その変更された箇所だけ変更され、他はそのまま変更されないという結果となるのです。
    そして単体テストも、構築作業で作成したテストケースのコードを必要あれば変更し、再度実行すればそれで単体テストのやり直しも完了できます。
    このためIaCによる構築は急な変更に対しても、規模を問わず強いと言えます。

  • 一部のサーバで設定ミスや設定漏れが発見され、サーバ全台に同じ誤りがないかの確認が必要となった場合
    手作業でサーバを構築した場合によくありがちな「ひとつの設定ミスから全台の設定が正当である確かさの担保が取れなくなり、全台の再確認が必要となる」シーンがこれです。
    経験がある方なら、これがどれだけ悲しいことであるか、そして手作業による作業ではいかに避けにくいかがよく分かるかと思います。
    ただIaCでもこれは起き得ることであり、コードによる構築で起きた場合は1台や2台ではなくコードで構築したサーバすべてに設定ミスや漏れが発生していることになります。
    IaCと手動の違いは、IaCの方はコードさえ正して再実行すれば解決する上に、確認自体もテストケースのコードを実行すれば簡単に行える点です。
    手動で構築した場合はそのミスがそこだけなのか、いつどこで発生しているのかが分かりません。しかしIaCであればコードを確認すれば簡単に特定が可能なのです。

  • 構築した環境を流用し、別の環境を作りたい場合
    既に構築済の環境とまったく同じ環境を作りたい。それがすべて手動で構築した環境なのか、IaCで構築した環境なのかでその言葉に対する反応は変わるでしょう。
    手動で構築した環境を、また手動で同じように作り上げる。初めて作った時よりと比べれば減るでしょうが、一度構築したことがあるからこそ構築にかかる時間が想像できてしまうと思います。
    そして実際には、まったく同じではなく用途に合わせた微細な変更を入れなければならないでしょう。複製すると言いつつ、実際にはイチから新たに作るのと変わらなくなるパターンです。
    しかしIaCで構築した環境の場合は話が違ってきます。環境を作るためのコードは既に用意されており、それを新しい環境で実行するための変更を加えて、また実行するだけで複製が簡単にできます。
    主に変更するのはホスト名やIPなどですが、それらをコード上で変更する手間は手動で作りよりも格段に少ないでしょう。
    手動で構築した環境でも、複製するのを良い機会としてIaC化してしまうのも一考できます。それくらいIaCは構築を流用したいケースに向いているのです。


IaCの必要性が薄いシーン

ここまででIaCによる構築の有利点と有効に働くシーンを挙げてきましたが、逆にIaCに向いていない、あるいは必要性の薄いシーンはどういったものか。

冒頭でも挙げましたがIaCの一番のデメリットは、コードを書いて構築する都合上、コードや仕組みの理解のための時間と労力、つまりは学習コストが多くかかってしまうことです。
単純な勉学も大変ですが、構築時だけでなく運用時にもその知識が求められるため、一人や二人だけが覚えておけばよいものでもありません。
IaCで構築した環境の運用は、それに携わる多くの人間がIaCについて一定量理解している必要があります。
加えてIaCで構築した環境は手動で構築した環境と機能的には何ら違いがありません。新しいことを覚えず、慣れ親しんだ手動の方がよいとする声は必ず上がるでしょう。
目に見える効果をすぐに得られるわけではないのに、いざ始める時に覚えることが多いIaCの導入ハードルは高いと言わざるを得ません。

なのでその学習コストを惜しむくらい、IaCのメリットを受けられないほどの小規模なシステムであれば、IaCである必要は薄くなるでしょう。

とはいえ、もしもその小規模なシステムでも開発のために同じ環境を作る必要があるといった場合は、複製のしやすさを考慮してIaCによる構築をした方がよくなります。
3~4回以上複製する見込みが既に立っているのであれば、当初からIaC構築とした方が後々のコストが違ってきます。


主に用いられるIaCツールとその特徴

IaCはインフラの構成をコード化し、それを実行することで環境を自動構築するものです。
そして「はじめに」で挙げた通り、コードによる環境の構築には構成管理ツールが必要です。
一概に構成管理ツールと言っても現在は多種多様なツールが開発・公開されています。
その中でも主流として使われているツールとその特徴をいくつか挙げて紹介します。

  • AWS CloudFormation
    AWS CloudFormationはAWSで使用できる構成管理ツールです。
    AWSのサービスのひとつとして提供されており、AWSらしくWeb UI上で操作ができるため見やすく動かしやすいのが特徴です。
    またAWSのサービスですので、認証情報や実行権限をコードに入れ込む必要がありません。
    権限を持ったアカウント(IAMユーザ)でマネジメントコンソールにログインし、CloudFormationテンプレートファイルをアップロードして実行するだけで環境構築が行えます。
    AWSサービスの殆どがこのCloudFormationで構築可能であり、加えて構築の失敗時には実行直前の状態へのロールバックが自動で行われます。
    このためAWS環境だけに限って言えば優れた利便性を持っていると言えます。
    コードにはJSONまたはYAMLが利用できます。

  • Cloud Deployment Manager
    Cloud Deployment ManagerはGoogleクラウドサービスであるGCP(Google Cloud Platform)で使用できる構成管理ツールです。
    GCPにおけるCloudFormationに相当するツールであり、GCPのサービスとして提供されている点もCloudFormationと同じと言えます。
    一方でCloudFormationとは異なる点もあります。特にテンプレートファイルを分割できる点や、構築失敗時にはロールバックされずに途中で止まる点が主な差異点として挙げられます。
    コードにはYAMLまたはPython、Janja2が利用できます。

  • Terraform
    TerraformはAWSGCP、Azureといったクラウドサービスにマルチに対応している構成管理ツールです。
    CloudFormationやCloud Deployment Managerといった提供元が自らのサービス下に限定し、特化して提供しているツールと違い、対応しているクラウドサービスにならIaCを行なえます。
    通常のツールと同じように作業用のマシンにインストールすることで利用でき、マルチクラウド対応なので一度コードさえ作ってしまえば異なるクラウドサービス間で流用できるのが特徴です。
    もちろんクラウドサービス同士の差異がある場合はそこを埋める必要こそありますが、AWSGCPをどちらも使っているという環境ではとても便利なツールになります。 コードはHCLという独自の言語で記述します。JSONYAMLに慣れていると敷居高く感じるかもしれませんが、構文自体はシンプルな言語なので、学習コストはそれほど高くないと言われています。

  • Ansible
    Ansibleは筆者も何度か紹介しているエージェントレス型の構成管理ツールです。
    今まではオンプレミス上の仮想マシンに対する構成管理を主題として紹介してきましたが、オンプレミスと同様にクラウドサービス上の仮想マシンの構成管理も行なえます。
    とはいえ単純にインフラの構築では以上3つの構成管理ツールの方が優れていると言えます。
    Ansibleがこれまでに紹介してきたツールと違う点は、OSレイヤーでの構成管理に優れる点です。
    OS内の設定やアプリケーションのインストールなどはTerraformでも可能ではあるものの、複雑なシェルを定義する必要があります。
    対してAnsibleは豊富なモジュールによって柔軟に対応できます。
    このためインフラ全体の構築はTerraformやクラウドサービス提供の構成管理ツールを使い、構築した仮想マシンへの設定はAnsibleを使うといった形で併用されるケースもあります。

  • Serverspec
    Serverspecはこれまでに紹介した構成管理ツールとは違い、構築の自動化を行なうツールではありません。
    構築した環境に対するテストを自動化するための、いわば構成管理テストツールとも言うべきツールです。 「IaCが有用になるシーン」で挙げたテストの段階で活躍するものであり、Rubyで記述したテストコードを実行することで、コードで定義した内容が適切に環境に反映されているかどうかを自動的に確認できます。
    例えば一定のパッケージがインストールされているか、一定のサービスが起動しているかなどが確認できます。
    Serverspecですべてのテストを自動化できるわけではありませんが、値の確認やアプリケーションの動作確認など決まりきったテストを自動化すれば、効率性の向上と人的ミスの軽減が図れます。


さいごに

クラウドサービスを利用したシステム構築の文化が広まり、その規模もどんどんと大きくなりつつある昨今。
IaCによる構築の効率化や確実化は避けて通れないと言っても過言でないくらい重要となってきていると感じています。
2023年はIaCを含めた自動化のノウハウについてじっくりお伝えしたいところです。

というわけで、今回、そして今年はここまで。
2023年の、次の記事でお会いしましょう!