朝日ネット 技術者ブログ

朝日ネットのエンジニアによるリレーブログ。今、自分が一番気になるテーマで書きます。

継続的デリバリーのすゝめ

朝日ネットで開発の業務を担当している tommy です。

皆さんは、「継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化」という本をご存じでしょうか? 2012年発行(原著は2010年)で有名な本なので知っている方も多数いらっしゃると思います。 え?もう全部読んだことがある?...それなら私からお伝えすることはもうないです。ブラウザバックするか、よろしければこのブログの別の記事を読んでいってください。

この本はソフトウェアを安全に提供するために、基本的だけどとても重要なことがしっかりと書かれています。 ざっくりと内容をキーワードにまとめてしまうと、「自動化」と「テスト」です。 弊社内でもこれらの重要さは十分広まってきたのですが、それでも人によってそのモチベーションについては様々です。

私のように、テストを書かないと不安で夜も眠れないような人間もいれば、 テストを書けと言われているからただ書いている人、 また、忙しさにかまけてテストをあまり書いてくれないような人も残念ながら存在します。

今回はすべての(開発者に限らず)ソフトウェア提供に携わる人に自動化・テストの意義を今一度認識してもらいたくて、この記事を書こうと思いました。 本の中で、私が特に伝えたい点を4つピックアップして紹介します。このほかにもこの本には気を付けるべき重要なことがたくさん書かれています。

共感できる点がありましたら、ぜひ本を手に取ってみてください。

手作業を根絶せよ

f:id:a-tommy:20211004100801p:plain:h400

仕事をしていると、よく作られた手順書が発掘されることがたまにあります。そのたびに、よくできた手順書ですごいなぁと思う反面、その時間をスクリプト作成に使って欲しいな…と強く思います。

OpenAPI Specification の記事 でも似たような主張を書いたのですが、自然言語 でドキュメントを書いておくと、解釈違いやドキュメントの更新漏れなどが頻繁に起こってしまいます。
また、本から印象的だった文章を引用させてもらうと、

「確かにこのように何かをやりました」と書いた紙切れがあったところで、本当にそれをその通りに実行したという保証は一切得られない。
出典元:引用 – 継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

というように、手順書(もしくは作業ログ)自体が間違っているという可能性すらあります。手順の途中でうまく動かなくてちょっと手順を変えて問題解決された結果、その作業が原因で事故が起こるなんてことがあります。 しかも、そういった作業は記録すら残っていないことがあるため大変です。自動化されていれば実際に何をしたかは明確ですし、作業全体をログに残すことも容易です。

ですので、作業の自動化は 作業時間の削減 というだけにとどまらず、あらゆる面で重要なのです。
とはいえ、1度しか行わない作業などまですべてスクリプト化して作業するのは大変ですしスクリプトのメンテナンスコストもかかります。

どういったときに自動化すべきかについては、この本がとても分かりやすい原則を提示してくれています。

最もシンプルな答えはこうだ。「同じことを2回やる事になったとき。」何らかを3回目に行うときには、自動プロセスを使わなければならない。
出典元:引用 – 継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

1度目はその手順がいろいろな状況にも当てはめることができる一般的なものかが判別がつかない可能性があります。 しかし、全く同じことを2度やる場面がでてきた場合、それは特殊な作業ではなく自動化すべき一般的な作業だということがわかります。

自動受入テストを作成せよ

f:id:a-tommy:20211004104128p:plain:h400

ユニットテストだけでは、アプリケーションをリリースできるという自信を高いレベルで持てるようにはならない。受入テストの目的は、顧客が意図したことをアプリケーションが実行しているということを証明することである。
出典元:引用 – 継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

まず大前提として、テストを書くことが非常に重要です。しかし、ユニットテストがしっかり書かれていて個々の機能が正しく動くことが保証されていたとしても、組み合わせた際にうまく動かないということが多々あります。 ですので、個々の機能やDBなどを組み合わせた結合テスト(インテグレーションテスト)、さらにお客様の要望を満たしているかを確認する受入テストを行うことが重要です。 少し過激なことをいれば私はユニットテストより、インテグレーションテストや自動受入テストを書いてほしいと思っています。 もちろんテストはどれも等しく大事です。書く時間があるならばユニットテストも詳細なテストを書くべきです。

プログラムを書くことに集中しているとどうしても「正しく動くもの」を作ることに集中してしまいがちです。そして出来上がったものを自分で動かしてみると、その使いづらさに驚くことがあります。 インテグレーションテスト、受入テストは、よりお客様に近い立場になってテストを書くので、使いやすさなどビジネス的な要件にまで目が行くようになります。

また、よく作られた自動受入テストはそれ自体が仕様書となりえます。こちらは一つ前の章の話につながるのですが、

仕様というものはほとんどが、アプリケーションが進化するのにあわせて陳腐化していく。しかし、実行可能な仕様であれば、そんなことは起こり得ない。
出典元:引用 – 継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

テストが十分書かれていると、テストが書かれている部分はテストが通る限り、仕様を満たしていると自信を持てるため、大胆な変更も比較的安心して行うことができるようになります。 過去に、DBを MySQL から MariaDB へ変更する必要あったのですが、十分なテストが書かれていたため、さまざまな問題を事前にテストで見つけることができ、大きなトラブルなく移行できた。ということがありました。

テスト環境は可能な限り本番環境と同じにせよ

我々が受け入れテストを実行するときには、期待される本番環境にテスト環境をできる限り近づけるように設計する。値段が高くなりすぎなければ、完全に同じであるべきだ。
出典元:引用 – 継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

よく、ここまでやれば本番環境の要素を十分みたしているからテストとして十分。という言葉を耳にするのですが、私は真逆の立場で、テスト環境は本番環境からの引き算でないといけないと思っています。 どういうことかというと、最初の引用文の通り、テスト環境は本番環境と完全に同じでないといけず、とはいえ(例えば本番のデータを使うわけにもいかないですし)全く同じにはできないので本番環境とどうしても同じにできないところのみを、どうして同じにできないのかを明らかにしたうえで変えるというアプローチをとるべきだと思っています。

以前、別システムとAPI連携をしたときに、APIの仕様書のみを渡され、APIのテスト用環境を用意できないと言われたのですが、無理にお願いして本番運用の前に本番と同じようなテスト環境を用意してもらったことがありました。 そして、実際に連携テストをしてみたら、仕様書に書いていない数多くの制約や多少のバグが見つかり、慌ててその仕様やバグに合わせてプログラムを修正したことがありました。

最初の章で引用した文章をもう一度引用しますが、

「確かにこのように何かをやりました」と書いた紙切れがあったところで、本当にそれをその通りに実行したという保証は一切得られない。
出典元:引用 – 継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

机上だけでいくら大丈夫だと検証しても実際に動かしてみると全く予期しない部分で動かないことがよくあります。CPUのコア数が1つ変わっただけで、メモリ量が数M変わっただけでプログラムが動かなくなってしまうなんてこともあります(実際経験したことがあります...)。

f:id:a-tommy:20211004104517p:plain:h400

ですので、テスト環境は可能な限り本番環境と同じにするべきです。また、テストの際は環境だけでなく、可能ならば人の動きなども本番と同じにしてテストするといったことを1度は実行しておきたいところです。

基盤と環境を管理せよ

すべての変更は、たとえファイアウォールのルール変更であっても主力サービスの新バージョンのデプロイメントと同じ変更管理手順に従わなければならない。
出典元:引用 – 継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

これは最初の章とほぼ同じことなのですが、今や基盤構築でさえほぼ自動化が可能です。本番環境へのミドルウェアのインストール、設定ファイルの配置、果てはOSのインストールまで。 クラウド環境を利用するならば、マシンの調達も自動で行うことができます。

環境の構成を管理することは非常に重要です。最近社内で発行された環境はAnsibleで管理されているのでどのようなソフトウェアがどのような設定で入っているかなどが一目瞭然です。 これによって感じる大きなメリットは、本番と同じような構成の環境を簡単に作ってテストができる。ということです。また、本番に適用された変更が記録に残るので何か問題が起こったときに原因の調査が容易にもなります。

一つの章として取り上げるか迷ったのですが最後に以下の文を引用して終わりたいと思います。

本番環境を直接修正するな
本番環境のダウンタイムのほとんどは、変更が統制されていないことが原因である、本番環境は完全に固めてしまい、デプロイメントパイプライン以外からは何も変更できないようにしておくべきだ。
出典元:引用 – 継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

f:id:a-tommy:20211004111730p:plain:h400

まとめ

今回は、「継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化」を紹介する記事を書かせていただきました。 いくつかトピックをピックアップして紹介させていただきましたが、この本の中にはまだまだ、紹介しきれないソフトウェアを継続的に提供するために重要なこと、がたくさん書かれています。

すべてのソフトウェア提供に携わる人(エンジニアに限らず)に読んでみてほしいと思っている本です。ぜひとも読んだことがない人はお手に取ってざっとでも読んでみてください。

採用情報

朝日ネットでは新卒採用・キャリア採用を行っております。

新卒採用 キャリア採用|株式会社朝日ネット