【翻訳】CI/CDベストプラクティス

原著者[Ankit Jain](https://medium.com/@ankitjain28may)氏の許諾を得て翻訳・公開しています。
記事: [CI/CD Best Practices](https://blog.bitsrc.io/ci-cd-best-practices-bca0ef665677)
原文公開日: 2020年9月25日

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406773/9e44c99b-9459-56b6-392c-6ba2da2d0cec.png)

# イントロダクション
継続的インテグレーションや継続的デプロイメントは、多くの組織で使われているアジャイル手法です。その手法は組織のソフトウェアを効率的かつ安全にシップすることを支援しています。

[GitLab 2020 DevSecOps survey](https://about.gitlab.com/developer-survey/)によれば、83%の開発者がコードをより速く頻繁にリリースしていると答えています。59%の企業がほぼ1日に複数回リリースしていると答えています。これはDevOps方法論が採用されているためであり、主に継続的インテグレーション、自動化されたテスト、継続的デプロイを行っているためです。

すべての組織は、最終的にその完璧なバランスを見つけて、私達が一般的に**ベストプラクティス**と呼んでいるCI/CDパイプラインをセットアップしながら、独自の方法論を含むようにしようとしています。効果的で安全なCI/CDパイプラインを実現するための基本的な原則をいくつか読んでいきましょう。

# Reliability
ソフトウェア開発のライフサイクル上でCI/CDパイプラインツールを持っておくことは、組織にアプリケーションのビルドやデリバリーの高速化をもたらします。それと同時に、ビジネスの組織の成長ペースに合わせてスケーリングでき、どんなエラーもなく正確に動作するよう、正しいCI/CDツールを選んでおくことが重要です。また、複数のユースケースやソフトウェアデリバリーの要件を考えて、十分に柔軟に運用できるようにしておく必要があります。

# CIパイプラインは速くあるべき
継続的インテグレーションやデプロイメントパイプラインをできる限り高速に保つことは常に重要です。すべての自動テストはCIパイプラインで実行され、開発サーバーにデプロイされ、最終的に本番環境にデプロイされます。そのため、すべてのエッジケースや致命的な故障の可能性をカバーすることが重要であると同時に、これらすべての変更がコード上で予測不可能なエラーを発生させないことを確認する必要があります。したがって、パイプラインをシンプルに、速く、安全に保つことはとても大切です。

マイクロサービスアーキテクチャの大規模な採用に伴い、CIパイプラインはモノリシックアーキテクチャとは異なり、素直でシンプルなものになります。しかし重いパイプラインがある場合、大きな影響を与えないテストを省き、トレードオフをドキュメントとして残すのは常に良いことです。テストスイートでのテストも優先順位をつけておくべきです。高速に実行されるテストは最初に実行するべきです。例えば、関数/コンポーネントベース、かつ素早いユニットテストは最初に実行され、機能テストや統合テストの後に実行されるべきです。そうすることで、早期にエラーを発見でき、時間を節約できます。開発者はコードをプッシュする前にローカル環境でテストを実行するべきです。そうすれば、早くエラーを発見できます。

# 隔離された環境でのRunとBuild
隔離された環境でCI/CDパイプラインを実行することは、セキュリティの観点や、テスト結果が正確になものになるよう本番環境とステージング環境を似せておくこと観点からも、常に重要です。

テストスイートを実行するためにDockerや他のコンテナ化ツールを使用したり、アプリケーション用のDockerコンテナ内に追加の依存関係をインストールしたりすることができます。このようにして、テストは完全に隔離された環境で実行されていることを確認することができ、ホストに影響を与えていないことを確認することができます。また、ほとんどの組織では、CI/CDプラットフォームがコードリポジトリに完全にアクセスできるため、より安全性を保つために、CI/CDツールを独自のクラウドインフラストラクチャへデプロイするために使用しています。

多くの組織はテストやUIコンポーネントのレンダリングを隔離して行うことで、これをさらに一歩進めています。このプロセスは、それらが実際に独立しているか検証する方法であり、独立したビルディングブロックで、1つ以上のプロジェクトへデリバリーされ統合される前に行われます。（これは通常[Bit](https://bit.dev/)([GitHub](https://github.com/teambit/bit))を使用して行われます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406773/46c5c0e1-6994-cee8-0b98-9c573717c12b.png "Bitなどのツールを使用し、他のプロジェクトと統合前にコンポーネントを分離してテストする")

# ステージング環境と本番環境の等価性
テスト実行中に予期しないエラーが発生して本番環境のダウンタイムが発生する可能性を少しでも回避するために、ステージング環境と本番環境を常に同等にしておくことをおすすめします。私達のCI/CDパイプラインは、テストの実行とステージング環境へのデプロイの段階を経ています。テスト実行後、アプリケーションは本番環境に自動的に昇格するか、または手動でデプロイされます。

テストや開発のために本番環境を完全にミラーリングすることはとても難しいですが、必要なときにはできるだけ似た状態を維持し、トレードオフを理解した上で決定を下すことができます。ほとんどの組織は **"Blue-Green"** 、**"Canary"** デプロイ戦略を使用しています。この戦略では、アプリケーションを本番環境の1%のライブトラフィックにデプロイし、その後100%のトラフィックで本番環境に導入したり、もしくは前回のリリースに簡単にロールバックできるようモニタリングしています。

# まとめ
全てのCI/CDツールは異なっており、すべての組織は可能な限りもっとも効率的で便利なCI/CDを活用していますが、これらは後の問題を避けるために誰もが注意し、従う必要のあるいくつかのベストプラクティスです。すべての組織は、コードの品質と組織のコーディング標準を改善するために、CI/CDパイプラインを通じてのみソフトウェアのリリースを義務付けるべきです。

お気軽にコメントや質問をしてください。[Twitter](https://twitter.com/ankitjain28may)や[Medium](https://medium.com/@ankitjain28may)で私のフォローをお願いします。読んでくれてありがとうございます。

# 翻訳を終えて
ステージング環境と本番環境はなるべく同じが良いかと思いますが、データベースをそのまま持ってくるのは難しそうですね。本番環境でしか存在しないレコードの組み合わせや想定外の値があった場合、ステージング環境でのCIパイプラインでは発見することが難しいと思うので、どのように対応したらいいのか気になりました。

誤訳等ありましたらご指摘をお願いします。