はじめに
CI/CDという概念は日本にも広く知れ渡っており、多くの会社で導入されていることかと思います。
一方で、その導入の仕方には差が見られ、特にCDにおける継続的デリバリーの実践手法には多くの差があるように感じています。
この記事では、そんなCI / CDのうち CD (Continuous Delivery)における基本原則の一つ Build Once について、および関連する概念としてDeploy Anywhereについて触れていきます。
Build Once, Deploy Anywhere とは?
Build Once とは、その言葉の通り「ビルド/パッケージングを一度だけ実行すること」という意味です。
RedHatの記事Build Once, Deploy Anywhere !では
One of the fundamental principles of Continuous Delivery is Build Binaries Only Once
(日本語訳) 継続的デリバリーの基本原則のひとつは、バイナリを一度だけビルドすることである
と記述があり、またAWSのドキュメントにも
When continuous delivery is properly implemented, developers always have a deployment-ready build artifact that has passed through a standardized test process.
(日本語訳) 継続的デリバリーが正しく実装されている場合、開発者は常に、標準化されたテストプロセスを通過したデプロイ可能なビルド成果物を持っている。
とあるように、Build Once は CD における基本概念の一つとして考えられています。
Build Once, Deploy Anywhere は、上記のような1度だけビルドした成果物を、環境ごとに差異を持たせず、どの環境にも同じアーティファクトをそのまま展開できるようにする、という意味です。
この言葉は、先ほども紹介したRedHatの記事Build Once, Deploy Anywhere !のタイトルから引用させていただいています。
Build Once, Deploy Anywhereを実現する場合、開発者は検証環境で使用したビルド成果物をそのまま使用して本番環境にデプロイを行い、環境変数などの値を外部から注入することによって環境ごとの動作の違いを制御します。
環境ごとにビルドすることに比べて何がよくなるのか?
従来のやり方として、環境ごとにビルド成果物を作成するやり方が存在しますが、この従来手法に比べてBuild Once, Deploy Anywhereは確かな利点を有しています。
下記でそのメリットを紹介します。
再現性・信頼性の向上
同一のアーティファクトを使うことで、環境ごとの差異による問題を削減することができます。
例えば、Dockerコンテナを使用していてbaseイメージのバージョンを指定し忘れていた場合、デプロイのたびにビルドしていた場合は検証環境と本番環境でDockerのベースイメージのバージョンが異なってしまう可能性があります。この場合、検証環境でのテストが成功していても本番環境ではアプリケーションの実行に失敗してしまうかもしれません。
一方、同一のビルド成果物を利用すればこの問題は発生しません。
また、サプライチェーン攻撃のリスクを減らすことにも繋がります。
運用・デリバリーの効率化
環境ごとにビルドする手間がなくなるため、下記のようなメリットが得られます
- デプロイフローにかかる時間の短縮
- ビルド費用の節約
- CI/CDパイプラインがシンプルになる
構成の柔軟性
環境差異はデプロイ時に外部注入することができ、ビルド時に固定する必要はありません。
例えば、ECSではContainer Definitionsからデプロイ時に渡す環境変数を定義することができます。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/taskdef-envfiles.html
シークレットも同様です。
表で表すと
| 観点 | ビルドとデプロイを分ける場合 (Build Once, Deploy Anywhere) |
ビルドとデプロイを分けない場合 (環境ごとにビルド) |
|---|---|---|
| 再現性・信頼性 | 同一のビルド成果物(アーティファクト)をすべての環境で使用するため、環境間の差異が発生しない。 → テスト済みのものをそのまま本番へ展開でき、信頼性が高い。 |
環境ごとにビルドを行うため、依存関係やバージョン差異が発生しやすい。 → 検証環境で動作しても、本番では動かないリスクあり。 |
| セキュリティ(サプライチェーンリスク) | ビルド回数が少ないため、外部依存の更新などによる不確実性を最小化。 → サプライチェーン攻撃のリスク低減。 |
ビルドのたびに外部リソースへアクセスするため、未知の変更が取り込まれる可能性あり。 → 攻撃リスクが高まる。 |
| 運用コスト・効率 | 一度ビルドすればどの環境にも展開可能。 → CI/CDパイプラインがシンプル化し、ビルド時間・費用を削減できる。 |
環境ごとにビルド工程が必要。 → ビルド時間やコストが増加し、CI/CDも複雑化。 |
| デプロイ速度 | ビルド済み成果物を使うため、デプロイが高速。 | 毎回ビルドが必要なため、デプロイに時間がかかる。 |
| 構成の柔軟性 | 環境差異はデプロイ時に外部から注入(例:環境変数・シークレット)可能。 → 構成を柔軟に切り替えられる。 |
環境ごとの差異をビルド時に埋め込む必要があるため、柔軟性が低い。 |
実践時の注意
技術的制約上、すべての環境で実現可能なわけではない
Build Once, Deploy Anywhere はすべての条件下で実現可能なわけではありません。
例えば、CやC++などの言語を扱う場合、想定した動作プラットフォームごとのビルドが必要です。
また、Web開発で広く使われているDockerも一部の環境では同様の問題が見られます。例えばNVIDIA/CUDAを扱う場合はNVIDIA/CUDAに対応したGPUを搭載したOS上でDockerを動作させる必要があり、macOSで動作させるのは現状困難です。
設計の考慮が必要
複数の環境にデプロイできるようにするためには、環境ごとの設定(接続先、環境変数、Secretsなど)を外部から注入可能な設計にする必要があります。
これはTwelve-Factor Appにおいても言及されています。
https://12factor.net/ja/config
既存のアプリケーションがそうなっていない場合、構成変更が必要です。
まとめ
Build Once, Deploy Anywhere は、再現性・効率性・セキュリティの観点から、モダンなCDの基盤となる考え方です。
まだ導入していない方は、ぜひ導入を検討してみてください!
