実行環境を効率的に管理・運用するための「IaC」という考え方

2024年3月8日(金)
田中 智明
第14回の今回は、Ops側の運用・管理作業を効率化するための「IaC」(Infrastructure as Code)という考え方について解説します。

はじめに

本連載では、前回までDevOpsで開発効率を向上すげるためのツールや考え方について解説してきました。

これまでに解説してきたCI/CDやGit、IDEなどは、どちらかと言うとDevの作業を加速させるためのツールでした。今回からはOps側の作業を加速させるツールについて考えみましょう。Opsがメインに行っている作業は環境構築や運用です。これらを効率的に管理する「IaC」について解説します。

IaCとは

「IaC」は「Infrastructure as Code」の略で、コードを活用してインフラストラクチャの運用・構築を自動化することを指します。ここで挙げているコードとは「構成管理ツールが解釈できるコード」です。IaCは構築の自動化を目指した手法を意味し、IaCを実現するには構成管理ツールを使用します。

構成管理とは

「構成管理」はハードウェア、ソフトウェア、ネットワークなどのシステムを構成している要素を把握し管理することを指しますす。構成管理を行うことでシステムに多くの変更を加えても、状態を把握できていれば期待通りに動作させることができます。

例えば、構成管理を行わずに構築しっぱなしの環境を想像してみてください。構成要素が分からないため同じ構成のシステムは構築できません。メンテナンスが必要になった場合にも、どの要素が依存関係にあるのか分からないため、恐ろしくてそのシステムに手を入れることができなくなるでしょう。そういった意味でも構成管理は重要です。

構成管理ツールとは

「構成管理ツール」は、名前のとおり構成管理を行うためのツールです。RubyやPythonなどのプログラミング言語、YAMLフォーマットのテキストファイルなどを用いて構成管理を行います。具体的には構成に必要な要素や構築手順などをコードとして記述し、構成管理ツールがそれを実行します。コードはテキストファイルであるためバージョン管理ツールで管理できます。バージョン管理ツールを使うことで変更の追跡や構成のレビューを効率的に行えます。

コードの種類

構成管理ツールのコードには「手続き型」と「宣言型」と呼ばれる2つの記述方法があります。この2つの記述方法にはどのような違いがあるか解説します。

・手続き型
システムの構成が“あるべき状態”となるように手順をコードとして記述していきます。構成管理ツールは対象のシステム内でこの手順を積み重ねることで、あるべき状態へ向かっていきます。

例えば、サーバーを2台起動するとしましょう。コードには「現在のサーバー台数」を取得し、足りなければ追加、超過していれば削除するような処理を記述します。これは構築手順書をコード化したようなものなので、手作業による構築に慣れ親しんだ方であれば簡単に理解できるでしょう。普段からこのような作業をしている方なら手続き型は学習コストが低いと言えます。

手続き型の欠点は「あるべき状態」がコードとして記述されていない点です。先の例ではサーバーを2台起動するために2台未満か超過かで条件分岐をしています。簡単な構成であるため結果として2台に収束するというのは分かりますが、コードには「2台必要」とは記述されていません。複雑な構成であればどうでしょうか。コードを実行するまでどのような状態になるのかが不明である可能性があります。

手続き型の主なツールはChef、Ansibleなどが存在します。構成管理ツールとは少し毛色が違いますが、手順を重ねていくという点でシェルスクリプトも手続き型と言えるでしょう。

・宣言型
システム構成のあるべき状態を記述します。手続き型ではあるべき状態へ向かうための手順を記述しましたが、宣言型ではあるべき状態のみを記述し、構築作業は構成管理ツールに任せます。

手続き型と同様に、2台のサーバーを起動するとしましょう。手続き型では構築手順を記述したのに対し、宣言型は「サーバーを2台起動」と宣言するのみです。あるべき状態を宣言しているため最終的にどのような構成になるのかをコードから読み取りやすくなります。

宣言型の欠点は、ツールのバージョンにシビアである点です。宣言型の構成管理ツールはツールが構築を担当するため、そのバージョンごとに実行される手順が異なっていたり、APIのエンドポイントが変更されていたりする可能性があります。そのため、宣言型のツールを使用する場合は構成管理ツールのバージョンを固定し、ツールのアップデートは慎重に行う必要があります。

宣言型の主なツールとして、Terraform、Puppetなどが存在します。

なぜIaCが必要なのか

IaCを導入することで属人化を解消し、冪等性を担保できるようになります。しかし、IaCの導入を検討したとき真っ先に思い浮かぶのはコード化のコストではないでしょうか。コードを書くコストが増えただけで完成するものが同じでは、なかなか手が出しづらいのも理解できます。そこでIaCを導入するメリットについて考えてみます。

属人化の解消

構築手順書を見ながら手作業をする場合、構成への理解やインフラに関する深い知識が要求されます。プロダクト内のOpsチームが皆一定の知識を保有していれば良いのですが、なかなかそうもいきません。結果的にインフラに明るい方や問題解決能力の高い方に依存してしまいます。

IaCはコードを実行するだけで望む構成を構築できます。つまり、インフラの構築に明るくない方でも、コードの実行方法が分かれば同じ構成を構築できます。構築に必要な要素はコードとしてチーム内で共有されるため、誰でも一定の知識を有することが可能です。また、コードが共有されていればインフラに明るい方や問題解決能力の高い方にコードレビューや構成の問題点を確認できるようになるため、どのプロダクトでも一定の品質が保証できます。

人的ミスの解消

手動で構築をしていると手順のミスや環境の取り違えなどが発生します。そのときの体調や作業する環境など、人的ミスが発生する要因は様々です。よくダブルチェックという言葉を耳にしますが、複数名で指差し確認をしていても、その担当者両名が見落としている可能性すら否定できません。人間とは必ずミスをするものなのです。

構築を自動化することで人的ミスを極力解消できます。人間が行う作業は「コードを書く」「それを実行する」の2つとなるため、この作業以外で人的ミスが起こることがありません。もちろんコードにバグを埋め込んでしまう可能性もありますが、属人化の解消で説明した通り、知識のある方にレビューをしてもらうことで、この手の問題を減らすことが可能です。

冪等性の担保

手動で構築した環境が「他の環境と全く同じか」はどのように保証すれば良いのでしょうか。簡単な方法としては、チェック表を作ってチェックしながら構築する方法が思いつきます。しかしこのチェック表が最新の環境に追従しているのかは分かりませんし、項目も多数になるため間違えてチェックを付けてしまうこともあるでしょう。この方法では「他の環境と全く同じか」というのはなかなか保証できません。

IaCでコード化しているとどうでしょうか。コードを使用して自動構築をしている場合、コードに変更がなければ何度でも同じ構成を構築可能です。冪等性を担保する上でIaCは重要です。

管理の効率化

IaCを使用しない場合、サーバーの管理はエクエルやドキュメントベースで管理することになります。何かを変更する度にドキュメントを修正し、手順を精査することになるでしょう。なぜ変更したのかエビデンスを残す必要もあります。IaCを使用せず実際の構成とドキュメントに差が出てしまい、構成管理が破綻している環境をよく目にします。

IaCを使用することで効率的に構成管理できます。コードを実行し構築された環境ではコードと環境がイコールの状態となります。ドキュメントのように更新漏れがあればその変更は環境に反映されません。構築手順のようなドキュメントを作成する必要もなくなります。ドキュメントにはコードの実行に必要な情報のみを記載すれば良くなり、ドキュメントの更新頻度はグッと下がります。

コードはテキストファイルであるため、バージョン管理システムで管理するのが良いでしょう。なぜ変更したのかエビデンスを残すことができ、変更の追跡も容易になります。また、コードレビューや問題の追跡にも役立ちます。

どこまでコード化するか

よく「IaCはどこまでコード化すると良いのか」という議論が発生します。「どこまで」というのは変更頻度が少ない作業までコード化するのかという意味です。これは関わるプロダクトの方針によるところもあるためどちらがベストとは言いづらい部分ではありますが、私個人としては全てコード化しておく方がベストだと考えます。

例えば、もう二度とやらないような作業があったとしましょう。二度とやらない想定なのでコード化するのはコストパフォーマンスが悪く感じますが、一度でもやった作業については「なぜそうしたのか」というエビデンスを残す必要があります。環境構築に必要な作業の一部がコード化されていないことで、コードから構成を読み解くことが難しくなります。

また、もし同じ作業が発生した場合には、その手順だけ手作業が必要となります。本来ならコードを実行するだけで良かったはずの作業が、思わぬ手作業となって降りかかります。一部の手作業が原因で冪等性を担保できなくなってしまうため、多少のコストには目を瞑ってコード化しておくのがベストだと考えます。

IaCを導入したら気をつけること

IaCで環境を構築したら手作業で修正するのは御法度です。常にコードが正であり、コードと環境はイコールであるべきだからです。コードを使って構成管理をしているので、ここに差分があれば構成管理が破綻します。

例えば、コードから自動構築した環境に手作業で何らかのプラグインを追加したとしましょう。このプラグインはコードで管理されていないため構成管理外のツールとなります。構成管理ツールでこの環境を破棄しようとしたときに、未知のプラグインを検出し破棄できなくなる可能性が考えられます。

破棄できないだけならまだ良いでしょう。ただのアップデート作業をしたつもりが構成管理ツールが思わぬ動作をしてしまい、環境の作り直しが発生してしまう可能性もあります。構成管理ツールには作成したリソースを独自に管理するものもあるため、IaCを導入したらIaCの作法に従って作業をするのが必須となります。

おわりに

複数の環境を使用して高速に開発サイクルを回すためには、誰でも繰り返し構築を可能にするための仕組みが必要になります。複数の環境を運用するには運用チームが管理の手間を削減し、効率的に作業をこなせなくてはいけません。複数の環境を運用するにはそれだけ時間と労力が必要だからです。

これを実現するためには属人化を解消し、冪等性を担保して管理コストを削減できるIaCが最適だと考えます。構築済みの環境にIaCを導入するのはあまりおすすめできません。すでに作成されているリソースをコードに落とし込むのは大変難しいからです。これから導入を考えている方は新しいプロダクトでIaCを導入し、慣れていくのが良いでしょう。

日本仮想化技術株式会社
ソーシャルゲーム業界で10年間インフラエンジニアとして活動し、現在は日本仮想化技術でOpsエンジニアを担当。DevOps支援サービス「かんたんDevOps」では仕組み作りや導入支援、技術調査などを行っている。

連載バックナンバー

設計/手法/テスト技術解説
第25回

AWSの監視サービス「CloudWatch」でサーバー監視を試してみよう

2024/8/9
本連載も今回で最終回となります。今回は、AWSの監視サービス「CloudWatch」を使って、簡単なサーバー監視を試してみましょう。
設計/手法/テスト技術解説
第24回

CI環境を構築して「ESLint」で静的解析を実行してみよう

2024/7/26
実践編第8回の今回は、「Dev Containers」でCI環境を構築し、静的解析ツール「ESLint」で静的解析を実行するまでの流れを解説します。
設計/手法/テスト技術解説
第23回

テストコードを書いて「GitHub Actions」でCIを実行してみよう

2024/7/12
実践編第7回の今回は、Webフロントエンド開発を例に、テストコードを書いて「GitHub Actions」でCIを実行するまでの流れを解説します。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています