📚

コンテナCI/CDについて考えてみた

2023/12/18に公開

はじめに

本記事はプロもくチャット Adevent Calendar2023の15日目です

https://qiita.com/advent-calendar/2023/puromoku

この記事の目的

ちょうど仕事でGutHub ActionsでCI/CDを構築しているので、その勉強のためにCI/CDとはをまとめ、理想のCICDパイプラインを考察してみます
誰かの参考になれば幸いです!

CI/CDってなんぞいや?

そもそもCI/CDってどういった目的を持って利用されるのかを確認してみましょう!

CIとは継続的インテグレーション、CDは継続的デリバリー/デプロイの略です。
CDが継続的デリバリーとデプロイの2つ書いているのは、一応意味が異なるからです

  • 継続的デリバリー:本番環境のデプロイまでは行わず、直前まで準備します
  • 継続的デプロイ:本番環境へのデプロイまで自動で行う意味があります

細かいことを言ってしまいましたが、CI/CDの大きな目的は プロダクトの変更をなるべく早く市場に届ける ことだと私は考えています!!!!

開発はなんのために行うかというと、プロダクトをより良くするためですよね?
プロダクトを良くすることで利益を増やしたり、他者よりも早く新機能を提供することで差別化を行い利益を増やしたりすることが会社としての目的のはずです!
(社会貢献という観点もありますが、売上と利益がなければ事業が続かないのでいったんはおいておきます)

また、実際に市場に出してみたら顧客が求めていたものとは違っていた場合、高速でプロダクトの変更ができれば方向修正もやりやすいですよね!

CI/CDの目的はなんとなくわかったわい!というところだと思いますが、ソフトウェア開発においてCI/CDが出てくる場面が曖昧な人がいるかもしれません
なので、ソフトウェア開発の流れをおさらいします!

ソフトウェア開発の流れ

ソフトウェア開発はどういった流れなのかを確認してます!
この記事ではSier的な納品する形ではなく、WEB系企業のように社内で開発から運用まで行っていることを前提とします

すると、大枠は以下のような流れになると思います!(ツッコミ待ってます!

  1. 要件を決める
  2. 実際にどう実現するか設計する
  3. プログラムを実装する
  4. 動作に問題がないかテストする
  5. デプロイする

上記のなかれ、要件を決めたり設計をしたりという部分は人がいろいろ考えないといけない部分です。
実装する部分も、GitHub Copilotなどがありつつもまだ人がいろいろ手を動かさないといけない部分ですね。

ただ、テストはテストコードを書いてしまえば自動で何度もできますし、デプロイもそうそう手順が変わるものではないので自動化できます。
つまりCIとCDが出てくる場面です!

ソフトウェア開発プロセスにおけるCI/CD

CIとCDについて寄り詳細に見ていきつつ、どういった要素を実現する必要があるか見てみます!

Continuous Integration(継続的インテグレーション)とは?

どういったことをCIでしていくと良いかですが、私は デプロイする前にできることは全部する ことができればいいと思っています!

具体的には、以下のような要素が必要と考えています

  • 必須
    • コンテナイメージのビルド
      • ビルドはデプロイ前に必須ですね!
    • テストの実行と結果レポート
      • 新機能のテスト
      • 既存機能に影響がないかリグレッションテスト
  • あると良さそう
    • 静的コード解析
      • コードの品質や信頼性、セキュリティ検証
    • コンテナのセキュリティスキャン
      • DockleやTribyでDockerベストプラクティスに沿っているか、脆弱性を含むパッケージがないかスキャン
    • コードカバレッジの計測
    • Formatter実行
      • コードスタイルを統一して、可動性を上げる

実際にデプロイする前に問題を見つけることができれば、早く修正できて手戻りが少なくて済みます
また、CIとして自動で実行されるようにしておけば、「あっ!実行し忘れたまま本番環境までデプロイしちゃった💦」ということを防ぐことができます!

仕組み化で、意識しなくても良くした方が楽そうです

Continuous Deployment/Delivery(継続的デプロイメント/デリバリー)とは?

CDでは、文字通りデプロイするorデプロイができる状態にすることをが目的です。
CDとして仕組み化することで、デプロイ手順は毎回同じ品質で実行されるようになるため、ミスが減ります!

コンテナかつAWSであればecspressoや、CodeDeployなどで実現できます!

CI/CDの大変なところ

CI/CDで実現できる良い点について色々書いてきました。
CI/CDはどんどんやっていこうと思うかもしれませんが、大変な点もいくつか存在します
それは、CI/CDの維持と改善 です。

何か仕組みを用意するということは、維持する活動をしなければ形骸化したり動作しなくなったりすることは目に見えています。
ちゃんと維持していくなら、必要な知識を持った人を用意して、継続的に運用できる体制にしておく必要があります!

また、チームがアプリケーションとインフラで分かれていると責任分界点が生じやすく、どちらでもない領域が発生してやりづらさが出てくることもあります(私は実際に経験しています

意外と大事なブランチ戦略

CI/CDについて書いて来たのですが、実は意外と考慮しないといけないものとしてブランチ戦略があります

体表的なブランチ戦略としては、GitフローGitHubフローGitLabフローなどがあります

ブランチ戦略によって、このブランチではCIを実行する、このブランチでは開発環境へデプロイする、このブランチではステージング環境にデプロイしてE2Eテストと負荷試験を実施するなど色々考慮する必要ができます!
なので、ブランチ戦略とCI/CDは密接に結びついてきます!

具体的にGitHubフローで考えてみます。
GitHubフローでは基本的にmainfeatureブランチが存在しますが、環境がdevelopment/staging/qa/productionと存在する場合、いつデプロイを実行するかをちゃんと決めないとごちゃつきます。
featureブランチでは開発環境、mainブランチでは本番環境にデプロイすると決めれば運用はできますね。
ただ、本番環境相当のデータ量とリソースサイズで試験をしたいけど、開発環境ではできないから環境を用意してくれという要望が出てきた場合、どうすればいいかは悩みどころです...

どういった環境を用意して、それぞれにどういった役割を持たせるかは各開発組織しだいなのかなと思います。
小さいプロダクトであれば本番環境相当のデータ量の環境はいらないかもしれませんし、大きくなってきてから考えるという整理もできます

また、Featureやフラグ・カナリアリリースでデプロイタイミングとリリースタイミングを分けるなども考え始めると、もっと色々考えないといkません。
この辺りは自分もまだまだ勉強すべき箇所です

理想のCI/CDとは

成熟したCI/CDまで考えたかったのですが、アドベントカレンダーで時間がないのでキーワードだけ

Four KeysがEliteやHighまで実現できていれば、だいだいはCI/CDも成熟しているのではないかと最近思っております!

どう導入してくんや?

でも、今のプロジェクトではCI/CDをできとらへんわ...という人もいるかもしれません

その時は、現状の把握をして、一番成果が出そうな箇所、例えば複雑なデプロイフローを整理して仕組み化するなどを行い少しづつやっていくのがいいのではないかと私は考えています!

これは何事にもいえることですが、改善するためには現状の把握と計測、改善後の結果確認と振り返りが必須です!
そのための現状把握です!

まとめ

変更しやすい=開発しやすい=生産性向上 だと最近は考えるようになったので、それに必要なCI/CDについてまとめてみました

変更しやすい ということは プロダクトにおける開発の心理的安全性 が担保されているということなのかな?とふと思いました。
自分の気持ちや意見を表明する=ソースコードを変更する という風に捉えれば同じ感じなのかな

GitHubで編集を提案

Discussion