Infrastructure as Codeにおけるテスト駆動開発実践入門(上)
Infrastructure as Codeにおけるコード開発にテスト駆動開発を導入する具体的な方法を全二回に分けて説明します。(上)ではIaCとは何か、テスト駆動開発とは何かについて概要を説明します。
Infrastructure as Codeにおけるテスト駆動開発実践入門(下)はこちら
はじめに
クラウド/コンテナ技術の登場により、ITインフラは頻繁に作っては捨てられる時代になりました。このような時代において、ITインフラの構成管理を従来通り手動で行うことは不可能です。なぜなら次のような事態が起こるからです。
- 頻繁にITインフラの構成が変わるため、手動で構成管理すると管理コストが膨大になる
- 管理表の反映し忘れにより、管理表に記載されているITインフラの構成と実際のITインフラの構成が乖離する
そこで近年Infrastructure as Code(IaC)という技術が注目を集めています。IaCとはITインフラの構成をコード化する技術の総称です。IaCを用いるとITインフラの構成管理を自動化し、上述の手動による構成管理の課題を解消することができます。
具体的にIaCではAnsible、Chefなどの構成管理ツールやServerspecなどのインフラ自動テストツールを用いて、ITインフラの構成をコード化し、ITインフラの構成管理の自動化を実現します。例えばAnsibleのプレイブックにITインフラの構成を記述しておき、Ansibleを実行すると、ITインフラの構成は自動でプレイブックに記載された構成になります。またServerspecのテストコードにITインフラの構成を記述しておき、Serverspecを実行すると、ITインフラの構成がテストコードに記載された構成と同じなのか違うのか、違うならばどこがどのように違うのか、自動で確認することができます。このようにIaCを用いてITインフラの構成をプレイブックやテストコードなどにコード化しておくと、ITインフラの構成管理を自動化することができるのです。
IaCによるコード化のメリットは構成管理の自動化にとどまりません。IaCでITインフラの構成をコード化しておくと、アプリケーションプログラムと同様にファイルとしてITインフラの構成を扱うことができるようになります。これによりアプリケーション開発の分野で洗練された、コードを管理するための様々なプラクティスをITインフラの構成管理にも適用できるようになります。例えばgitを用いることで、ITインフラの構成を高度にバージョン管理することができるようになります。またJenkinsを用い、プログラムが常に想定通り動作することを保証する継続的インテグレーション(CI: Continuous Integration)を適用して、ITインフラが常に想定通り動作することを保証できるようになります。
以上のようなメリットからIaCは注目され、活用する企業も増えてきています。面倒な構成管理作業の省力化が可能になるため、このような時代の流れはインフラエンジニアにとって喜ばしいことでしょう。しかし一方で、戸惑いを感じている方も多いのではないでしょうか。というのもインフラエンジニアはアプリケーションエンジニアのようなプログラム開発経験が薄いことが多いため、IaCコードをどのように開発したらよいかわからない方が多いのではないかと思うからです。
そこで本記事ではこれからIaCコードを開発する、もしくは開発したいと考えている方のために、公私ともにIaCコードを開発してきた筆者が、IaCコード開発に適していると考えている開発手法とその具体的なやり方について説明いたします。その開発手法とは「テスト駆動開発」です。
テスト駆動開発とは
テスト駆動開発(Test Driven Development: TDD)とはソフトウェア開発手法の一つで、単体テスト・結合テストを行うコードを先に作成し、その後作成したテストを成功させるための最小限のコードを書く、というサイクルを繰り返してソフトウェアを開発する手法です。「サイクルを繰り返して」開発するのが重要です。もしサイクルを繰り返さなければ、はじめに全てのテストコードを作成して、全てのテストを成功させるコードを書くという、ウォータフォール型の開発ということになります。
ここでアプリケーション開発においてもインフラ開発においてもですが、そもそもなぜテストの作成を開発よりも先にする必要があるのか確認しておきましょう。その答えは「テストの作成は設計の一部」だからです。設計ができているならばテストは作成できるはずです。つまり、テストが作成できないならば設計はできていないことになります。設計ができているときに限り開発はできるので、テストが作成できないならば開発はできないことになるのです。整理すると以下の通りになります。
- テストを作成できない ⇒ 設計ができていない ⇒ 開発ができない
従って、テストを先に作成することで開発ができる状態にするのです。当たり前のことかもしれませんが、「テストの作成は設計の一部」であるという考え方はテスト駆動開発において重要な考え方なので、おさえておきましょう。
話をテスト駆動開発に戻します。テスト駆動開発ではテストを行うコードを先に作成し、その後作成したテストを成功させるための最小限のコードを書く、というサイクルを繰り返すのでした。お気づきの方もいるかもしれませんが、「テストの作成は設計の一部」ということを思い出すと、この開発手法は小さな設計をして小さな開発することを繰り返す、アジャイル開発であることがわかります。そうです。テスト駆動開発とはアジャイル開発の一つなのです。
アジャイル開発であるテスト駆動開発がなぜIaCコードの開発に適しているのかというと、「ITインフラ構成の頻繁な変更に追従できるから」と私は考えています。
テスト駆動開発におけるテスト
テスト駆動開発をする上では、テストとは何かということも議論しておかなくてはなりません。なぜならば、勘違いしがちなのですが、テスト駆動開発で行われるテストは品質保証のためのテストではないからです。
テストはその目的に応じて次の三つに分類されます。
-
Developer Testing
開発を前に進める原動力となるテスト。つまり開発者が開発者のために行うテスト。
このテストをすることで実現可能性を検証、またソフトウェアの設計をしつつ開発を進めていくことができます。
単体テスト、結合テストがこれにあたります。 -
Customer Testing
お客様から見て機能がどれくらいできあがっているかを示すテスト。
お客様の求めている機能が確かに実装されているかを確認するテストで、進捗管理にも使用されます。
受け入れテストがこれにあたります。 -
Quality assurance testing
品質管理・品質保証の側面からのテスト。ここでいう品質とは非機能要件、つまりレスポンスがx秒以下といった性能とか、機密性が担保されているかといったセキュリティなどに対する充足度を言います。
このテストに合格しなければ,たとえ機能を満たしていたとしても、その成果物をお客様にお渡しするわけにはいきません。
テスト駆動開発におけるテストは単体テスト、結合テストなので、Devloper Testingになります。お客様の求めている機能が実装されているか確認するテストでもなく、品質を保証するテストでもありません。実現可能性を検証、またソフトウェアの設計をしつつ開発を進めていくためのテストなのです。したがってテスト駆動開発を行ったからといってその後のテストが不要になるわけではなく、Customer TestingやQuality assurance Testingは必要になることに注意しましょう。
Infrastructure as Codeにおけるテスト駆動開発実践入門(下)につづく
(下)ではテスト駆動開発の具体的なやり方やIaCコードの開発への適用方法を見ていきましょう。
Infrastructure as Codeにおけるテスト駆動開発実践入門(下)はこちら