

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# 完全な CI/CD プロセスの違い
<a name="fully-cicd-process-differences"></a>

CI/CD パイプラインは最新の*トランクベースのワークフロー*を使用します。このワークフローでは、開発者は小規模かつ頻繁な更新をメインブランチ (または*トランク*) にマージし、そのブランチが CI/CD パイプラインの CD 部分を通じてビルドおよびテストされます。このワークフローは、開発ブランチとリリースブランチがリリーススケジュールによって分離されている *Gitflow ワークフロー*に取って代わりました。多くの組織では、Gitflow は依然としてバージョン管理およびデプロイの一般的な方法です。しかし、これは現在ではレガシーと見なされており、CI/CD パイプラインに統合するのは困難な場合があります。

多くの組織では、Gitflow ワークフローからトランクベースのワークフローへの移行は不完全であり、その結果、途中のどこかで行き詰まって CI/CD への完全な移行を実現できずにいます。どういうわけか、これらのパイプラインはレガシーワークフローの一部の名残にしがみつき、過去と現在の間の移行状態で行き詰まってしまいます。Git ワークフローにおける違いを確認し、そのうえで、レガシーワークフローを使用することが以下にどのような影響を与えるかを説明します。
+ [環境整合性](environment-integrity.md)
+ [リリース](releases.md)
+ [セキュリティ](security.md)

最新の設定においてレガシー Git ワークフローの名残を特定しやすくするために、[Gitflow](#gitflow-approach) を最新の[トランクベース](#trunk-based-approach)のアプローチと比較してみましょう。

## Gitflow アプローチ
<a name="gitflow-approach"></a>

次の図は、Gitflow ワークフローを示しています。Gitflow のアプローチでは、複数のブランチを使用して複数の異なるバージョンのコードを同時に追跡します。開発者が現在のバージョンのコードに対して作業を続けている間に、将来のある時点でのアプリケーションの更新のリリースをスケジュールします。トランクベースのリポジトリでは機能フラグを使用することでこれを実現できますが、Gitflow にはデフォルトで組み込まれています。



![\[機能、開発、リリース、およびホットフィックスの各ブランチを含む Gitflow ワークフロー\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/strategy-cicd-litmus/images/gitflow-workflow.png)


Gitflow アプローチの結果の 1 つとして、アプリケーション環境が通常は同期していない状態になります。標準的な Gitflow の実装では、開発環境はコードの現在の状態を反映する一方で、本番前環境および本番環境は、最新のリリース時点のコードベースの状態で固定されたままになります。

これにより、本番環境で欠陥が発生した場合に事態が複雑になります。なぜなら、開発者が作業しているコードベースには未リリースの機能が含まれており、それを公開せずに本番環境にマージすることはできないからです。Gitflow がこの状況に対処する方法は、ホットフィックスを使用することです。ホットフィックスブランチはリリースブランチから作成され、その後、上位環境に直接デプロイされます。その後、コードを最新の状態に保つために、ホットフィックスブランチは開発ブランチにマージされます。

## トランクベースのアプローチ
<a name="trunk-based-approach"></a>

次の図は、トランクベースのワークフローを示しています。トランクベースのワークフローでは、開発者は機能ブランチでローカルに機能をビルドおよびテストし、それらの変更をメインブランチにマージします。メインブランチはその後、開発環境、本番前環境、本番環境に合わせて順次構築されます。各環境間では、ユニットテストと統合テストが実行されます。



![\[機能ブランチとメインブランチを含むトランクベースのワークフロー。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/strategy-cicd-litmus/images/trunk-based-workflow.png)


このワークフローを使用すると、すべての環境が同じコードベースで動作します。未リリースの機能を公開することなくメインブランチで変更を実装できるため、上位環境向けにホットフィックスブランチを作成する必要はありません。メインブランチは常に、安定しており、欠陥がなく、リリース可能な状態であると想定されます。これにより、メインブランチを CI/CD パイプラインのソースとして統合することができ、パイプライン内のすべての環境を通じてコードベースを自動的にテストおよびデプロイできます。

# トランクベースのアプローチによる環境整合性の利点
<a name="environment-integrity"></a>

多くの開発者が知っているように、コードの 1 つの変更が[バタフライ効果](https://www.americanscientist.org/article/understanding-the-butterfly-effect) (American Scientist の記事) を引き起こすことがあります。これは、一見無関係に見える小さな逸脱が連鎖反応を誘発し、予期しない結果を引き起こす現象です。その場合、開発者は根本原因を見つけるために徹底的な調査を行う必要があります。

科学者が実験を行う場合、被験体を実験群と対照群の 2 つのグループに分けます。この実験群と対照群は、実験でテストされる対象以外は完全に同一にすることが意図されます。実験群で発生したことが対照群では発生しない場合、その原因として考えられるのは、テストされている対象だけです。

デプロイにおける変更を実験群として、各環境を個別の対照群として考えてみてください。下位環境でのテスト結果が信頼できるのは、その対照が上位環境と同じである場合のみです。環境の逸脱が大きくなるほど、上位環境で欠陥が発見される可能性が高くなります。言い換えれば、コードの変更が本番環境で失敗する可能性がある場合、その変更が本番環境に到達しないように、先にベータ環境で失敗してくれたほうがはるかに望ましいということです。これが、最も下位のテスト環境から本番環境自体に至るまで、各環境が同期した状態を維持するためにあらゆる努力をする必要がある理由です。これを*環境整合性*と呼びます。

すべての完全な CI/CD プロセスは、できるだけ早く問題を発見することを目標としています。トランクベースのアプローチを使用して環境整合性を維持することで、実質的にホットフィックスの必要性を排除できます。トランクベースのワークフローでは、問題が最初に本番環境で出現することはまれです。

Gitflow アプローチでは、ホットフィックスは上位環境に直接デプロイされた後、開発ブランチに追加されます。これにより、将来のリリースに向けてその修正が保持されます。しかし、そのホットフィックスは、アプリケーションの現在の状態から直接開発およびテストされたものです。ホットフィックスが本番環境で完全に機能している場合でも、開発ブランチの新しい機能と相互作用する際に問題が発生する可能性があります。通常、ホットフィックスのためのホットフィックスをデプロイすることは望ましくないため、開発者はホットフィックスを開発環境に後付けで適合させようとして、余分な時間を費やすことになります。多くの場合、これは重大な技術的負債につながり、開発環境の全体的な安定性を低下させる可能性があります。

環境で障害が発生した場合は、すべての変更がロールバックされ、環境は以前の状態に戻されます。コードベースに何らかの変更を加えた場合は、最初のステージからパイプラインを再度開始する必要があります。本番環境で問題が発生した場合は、その修正も同様にパイプライン全体を通過する必要があります。下位環境を通過するのに追加でかかる時間は、通常、このアプローチを使用することで回避できる問題と比較するとごくわずかです。下位環境の全体的な目的は、本番環境に到達する前に問題を捕捉することにあるため、Gitflow アプローチによってこれらの環境をバイパスすることは、非効率かつ不要なリスクです。

# トランクベースのアプローチによるリリース上の利点
<a name="releases"></a>

ホットフィックスが頻繁に必要になる理由の 1 つは、レガシーワークフローでは、開発者が作業しているアプリケーションの状態に、まだ本番環境で稼働していないいくつかの未リリースの機能が含まれている場合があることです。本番環境と開発環境は、スケジュールされたリリースが行われたときにのみ同期状態になり、その後、次のスケジュールされたリリースまで再びすぐに乖離し始めます。

スケジュールされたリリースを行うことは、完全な CI/CD プロセス内でも可能です。機能フラグを使用することで、本番環境へのコードのリリースを遅らせることができます。しかし、完全な CI/CD プロセスでは、スケジュールされたリリースが不要になるため、さらに柔軟性が向上します。結局のところ、CI/CD における重要なキーワードは*継続的*であり、これは変更が準備できた時点でリリースされることを示しています。下位のテスト環境と同期状態になることがほとんどないような、独立したリリース環境を維持することは避けてください。

パイプラインが完全な CI/CD になっていない場合、通常、上位環境と下位環境の乖離はブランチレベルで発生します。開発者は開発ブランチで作業し、スケジュールされたリリースのタイミングになったときにのみ更新される、個別のリリースブランチを維持します。リリースブランチと開発ブランチが乖離するにつれて、他の複雑さが発生する可能性があります。

環境が同期していないことに加えて、開発者が開発ブランチで作業し、本番環境よりもはるかに先行したアプリケーションの状態に慣れてしまうと、本番環境で問題が発生するたびに、開発者は本番環境の状態に再適応する必要があります。開発ブランチの状態は、本番環境よりも多くの機能がある分、先行していることがあります。開発者が毎日そのブランチで作業していると、本番環境に何がリリースされていて何がリリースされていないかを覚えておくことは困難です。これにより、他のバグを修正する際に新しいバグが導入されるリスクが高まります。この結果、永遠に続くかのような修正のサイクルが発生し、タイムラインが延び、機能のリリースが数週間、数か月、あるいは数年も遅れることになります。

# トランクベースのアプローチによるセキュリティ上の利点
<a name="security"></a>

完全な CI/CD プロセスは、完全に自動化された、デプロイに対する唯一の信頼できるソースのアプローチを提供します。パイプラインには単一のエントリポイントがあります。ソフトウェアの更新は最初の段階でパイプラインに入り、そのまま次の環境へと順に渡されていきます。パイプラインのいずれかのステージで問題が見つかった場合、その問題を修正するコード変更も同じプロセスを通過し、最初のステージから開始される必要があります。パイプラインにおけるエントリポイントを削減すると、脆弱性がパイプラインに導入される可能性のある経路も削減されます。

さらに、エントリポイントは本番環境から最も遠い場所に配置されるため、脆弱性が本番環境に到達する可能性が大幅に削減されます。完全な CI/CD パイプラインに手動承認プロセスを導入した場合でも、変更を次の環境へ昇格させるかどうかについて、実行可否の意思決定を引き続き行えるようにすることは可能です。意思決定者は、必ずしも変更をデプロイする人と同一であるわけではありません。これにより、コード変更のデプロイ担当者とそれらの変更の承認者の責任が分離されます。また、技術的な知識がそれほど豊富ではない組織のリーダーが承認者の役割を果たすことがより実現可能になります。

最後に、エントリポイントが 1 つのみになることで、本番環境のユーザーインターフェース (UI) コンソールへの書き込みアクセスを、ごく少数 (場合によってはゼロ人) のユーザーに制限することができます。コンソールで手動による変更を行えるユーザー数を減らすことで、セキュリティイベントのリスクを低減できます。本番環境のコンソールを手動で管理する機能は、CI/CD の自動アプローチよりも、レガシーワークフローにおいてはるかに必要です。これらの手動による変更は、追跡、レビュー、およびテストするのがより困難です。これらは通常、時間を節約するために実行されますが、長期的にはプロジェクトに重大な技術的負債を追加することになります。

コンソールのセキュリティ問題は、必ずしも悪意のある人物によって引き起こされるわけではありません。コンソールで発生する問題の多くは偶発的なものです。偶発的なセキュリティ露出は非常に一般的であり、それがゼロトラストセキュリティモデルの台頭につながっています。このモデルでは、その一部において、内部スタッフであっても可能な限り小さいアクセス権しか持たない (*最小特権*とも呼ばれる) ようにすることで、セキュリティ上の事故が起こりにくくなるということを提唱しています。すべてのプロセスを自動化されたパイプラインに制限して本番環境の整合性を維持することにより、コンソール関連のセキュリティ問題のリスクを実質的に排除できます。