Slide 1

Slide 1 text

CI/CD ⽣産性向上チーム 宮⽥ 淳平 1

Slide 2

Slide 2 text

この講義の⽬的 ▌CI/CD の基本的なところを⼀通り知ってもらう ▌キーワードを把握して今後の学習の取っ掛かりとしてもらう 2

Slide 3

Slide 3 text

CI/CD がない開発の例 3

Slide 4

Slide 4 text

各⾃の環境で開発 4

Slide 5

Slide 5 text

リリース前に各⾃の変更を結合して試験 5

Slide 6

Slide 6 text

不具合だらけ 6

Slide 7

Slide 7 text

修正を依頼しても原因特定が難しい 7

Slide 8

Slide 8 text

修正しても新たな不具合を埋め込んで以下繰り返し 8

Slide 9

Slide 9 text

終わりが⾒えなくて⾟い 9

Slide 10

Slide 10 text

問題 ▌結合のタイミングでまとめて⼤きな差分が発⽣する l 壊れやすい、原因究明が困難 ▌変更してから問題が⾒つかるまでのタイムラグが⼤きい l 学習が遅れるのでその間にも類似不具合が埋め込まれる 可能性が⾼い ▌リスク(不確実性)が⾼い l 結合後の対応がどれぐらいになるか予測しづらい 10

Slide 11

Slide 11 text

CI (Continuous Integration) 11

Slide 12

Slide 12 text

CI とは︖ ▌開発プラクティス ▌⼀⽇に何回もバージョン管理システムに変更をマージする ▌毎回テストなどを含む⾃動ビルドが実⾏される 12

Slide 13

Slide 13 text

CI がある開発の例 13

Slide 14

Slide 14 text

開発者がメインラインからタスクブランチを作成する 14

Slide 15

Slide 15 text

ローカルでコードを変更する 15

Slide 16

Slide 16 text

タスクブランチにプッシュして PR(プルリクエスト) を作成する 16

Slide 17

Slide 17 text

CI ツールがタスクブランチのコードでビルドを実⾏する 18

Slide 18

Slide 18 text

ビルドが失敗したら通るまで修正 & CI 再実⾏ 19

Slide 19

Slide 19 text

ビルドが成功したらメインラインにマージする 20

Slide 20

Slide 20 text

CI ツールがメインラインのコードでビルドを実⾏する 21

Slide 21

Slide 21 text

ビルドが失敗したら通るまで修正する 22

Slide 22

Slide 22 text

メインラインでビルドが成功したら完了 23

Slide 23

Slide 23 text

CI の利点 ▌⾼速なフィードバック l 問題の早期発⾒ l ⾼速な学習 ▌頻繁に変更がマージされるようになれば差分が⼤きくならない l 問題発⾒時の調査が簡単になる l リスク(不確実性)が減る ▌Success/Fail の可視化によるコミュニケーション促進 ▌毎回の変更が⾃動テストで保証される安⼼感 24

Slide 24

Slide 24 text

CD (Continuous Delivery) 25

Slide 25

Slide 25 text

CD とは︖ ▌CI の発展型 l コードの変更がトリガーとなって実⾏されることは同じ ▌コード変更からリリースまでに必要な検証を⾏う l 常に信頼できるリリースができる状態を保つ ▌デプロイパイプラインという形で⾃動化する l 部分的に⼿動作業が⼊ることもある 26

Slide 26

Slide 26 text

デプロイパイプラインの例 チェックイン トリガー ビルド& 単体テスト トリガー 結合テスト トリガー リリース 28

Slide 27

Slide 27 text

CD の利点 ▌リリースのコストやリスクを抑えられる l いつでもリリースできる ▌コード変更からリリースまでのフローが可視化される l どこで問題が起きてるか、どこがボトルネックか、 などがすぐにわかる 29

Slide 28

Slide 28 text

CI/CD 内で実⾏すること 30

Slide 29

Slide 29 text

静的解析 ▌構⽂チェック l 構⽂エラーを防ぐ ▌コードスタイルチェック l 可読性を⾼める、本質的でない議論を防ぐ ▌コードパターンチェック l エラーが発⽣しやすいパターンを防ぐ 31

Slide 30

Slide 30 text

⾃動テスト ▌ 単体テスト l ⼩さい単位のコードが役割通り動作するかチェックする ▌ 結合テスト l 複数のコードを組み合わせた機能が正しく動作するかチェックする ▌ 受け⼊れテスト(E2E テスト) l ビジネス要求を満たしてるかチェックする ▌ 上記以外にもいろいろ l テストの種類ごとの呼び⽅や⽬的はチームによって異なるので、 認識を揃えることが⼤事 32

Slide 31

Slide 31 text

⾮機能要件のテスト ▌性能検証、脆弱性検証など ▌CI/CD にどのように組み込むかは時と場合による l 毎回実⾏するには⻑時間になりがち l 組み込めるなら組み込んだほうがいい 33

Slide 32

Slide 32 text

アーカイブ作成 ▌デプロイ・リリース時に使⽤するアーカイブ ▌結合テスト、E2E テスト、⾮機能要件のテストでも使⽤する l テストに通ったアーカイブをリリースする 34

Slide 33

Slide 33 text

デプロイ・リリース ▌ メインラインにマージされたときだけ実⾏されることが多い l タスクブランチでも動作確認⽤環境にデプロイとかはある ▌ ステージング環境 l 本番環境によく似せたステージング環境でまずデプロイする ▌ 本番環境へのリリース戦略 l 万⼀の問題発⽣に備えることが重要 l ⼀部の環境から広げていく、ロールバック、無停⽌ l カナリアリリース、ブルーグリーンデプロイ、フィーチャーフラグ など 35

Slide 34

Slide 34 text

その他いろいろ ▌コード変更からリリースまでに必要なことはなんでも ▌デプロイパイプライン作成後もどんどん変化していく 36

Slide 35

Slide 35 text

CI/CD ツール 37

Slide 36

Slide 36 text

Jenkins ▌OSS ▌オンプレ構築できる ▌コミュニティが⼤きいのでプラグインが豊富 ▌柔軟でやろうと思えばなんでもできる 38

Slide 37

Slide 37 text

CircleCI ▌クラウドサービス l オンプレ版の CircleCI Server もサイボウズで利⽤してます ▌シンプル、導⼊しやすい ▌認証とか権限とか GitHub と連携してるので導⼊が楽 40

Slide 38

Slide 38 text

GitHub Actions ▌GitHub が提供する CI/CD サービス ▌パブリックリポジトリでは完全無料 ▌CI/CD に限らず GitHub の様々なイベントにフックできる 42

Slide 39

Slide 39 text

その他の CI/CD ツール ▌AWS Code シリーズ l CodeBuild, CodeDeploy, CodePipeline, ... l AWS と権限周りを統合しやすい ▌Kubernetes ⽤ CD ツール l Argo CD など l GitOps と呼ばれる⼿法がよく使われる l https://www.weave.works/technologies/gitops/ 43

Slide 40

Slide 40 text

CI/CD 導⼊ 44

Slide 41

Slide 41 text

新規開発への導⼊ ▌最初から CI/CD を導⼊するのがおすすめ ▌後回しにすると⾃動化しづらい作りになってしまいがち 45

Slide 42

Slide 42 text

既存開発への途中からの導⼊ ▌レガシーな部分が原因で難易度が上がりがち ▌⼿を付けやすく効果の⾼そうなところから始めるのがおすすめ l ビジネス的に重要な部分の正常系テストとか ▌いきなり⻑時間かかるジョブを構築するのはおすすめしない 46

Slide 43

Slide 43 text

CI/CD は⼀⽇にしてならず ▌すべてを⼀気に導⼊する必要はない l コスパのよさそうなところから徐々に ▌決まった型はない l ソフトウェアやチームの性質による ▌チームで認識を合わせることも⼤事 ▌プロダクトと同じで CI/CD も継続的に改善していく 47

Slide 44

Slide 44 text

⾃動化する時間がない︖ ▌⾃動化しないから時間がないのです 48

Slide 45

Slide 45 text

うまく回らないとき ▌チームで振り返る ▌他のチームの運⽤を参考にする ▌詳しそうな⼈に相談する 49

Slide 46

Slide 46 text

アンチパターンとベストプラクティス 50

Slide 47

Slide 47 text

ローカルで⻑時間開発しすぎる ▌変更差分が⼤きくなる l 他の開発者の変更と衝突しやすい l 壊れやすい l 原因究明が困難 ▌変更してから問題が⾒つかるまでのタイムラグが⼤きくなる l 問題に気づくのが遅れるほど対応コストは⼤きくなる 51

Slide 48

Slide 48 text

頻繁に変更をバージョン管理システムにコミットする ▌⽬安的には全員が 1 ⽇ 1 回以上 ▌コミットが⼤きくなりすぎないように意味単位で分割する l 問題発⾒やレビューが簡単になる ▌タスクも粒度が⼩さくなるように分割したほうが不確実性が減る 52

Slide 49

Slide 49 text

ビルドの実⾏頻度が低い ▌⼀⽇に⼀回とかしか実⾏されないケース ▌ビルド失敗時にどの変更が原因かわかりにくい ▌変更してから問題が⾒つかるまでのタイムラグが⼤きくなる l 問題に気づくのが遅れるほど(ry 53

Slide 50

Slide 50 text

すべてのコミットでビルドを実⾏する ▌ビルドが失敗したときは直前のコミットが原因の可能性が⾼い l 調査しやすい ▌フィードバックが早い l 対応コストが⼩さくなる 54

Slide 51

Slide 51 text

ビルドが失敗しても放置される ▌属⼈的になりがち ▌誰も対応しなくなると CI/CD の利点がすべて失われる 55

Slide 52

Slide 52 text

ビルドが失敗したらチームは最優先で復旧する ▌ビルド失敗=リリースできない問題が存在する ▌⽬安は 10 分以内 l 直前の変更をリバートするのが⼀番楽 ▌ビルド失敗はチームメンバー全員が⾒てるところに通知する l 状態が可視化され、コミュニケーションが円滑になる 56

Slide 53

Slide 53 text

https://blog.cybozu.io/entry/2386 57

Slide 54

Slide 54 text

CI/CD のビルド時間が⻑すぎる ▌結合テストや受け⼊れテストを厚くしすぎるとなりがち ▌1 時間以上とかになってくると厳しい l 失敗時に再実⾏することとかを考えると⾟い 58

Slide 55

Slide 55 text

CI/CD を⾼速に保つ ▌可能な限り並列実⾏する ▌⾃動テストの役割を継続的に⾒直す l テストピラミッドを意識する 59

Slide 56

Slide 56 text

テストピラミッド GUI Test API Test Unit Test

Slide 57

Slide 57 text

テストピラミッドのポイント ▌いろいろな粒度のテストを組み合わせる ▌粒度が⼤きくなるほど実⾏時間やメンテナンスコストが⾼くなる ▌より⼩さい粒度のテストで防げるものは防ぐ 61

Slide 58

Slide 58 text

不安定なビルド ▌不具合ではないのにビルドが失敗する l CI/CD の信頼性が下がる ▌原因はいろいろ l 本番コードではないので書かれる⼿抜きスクリプト l E2E テストの微妙なタイミングのズレ l 不安定な環境 l 構築⼿順が微妙に異なる、前のビルドのゴミが残ってる、など 62

Slide 59

Slide 59 text

ビルドを継続的に改善して品質を⾼める ▌ビルドで実⾏されるタスクは製品コードレベルの品質を⽬指す l 特にメンテナンス性を⾼めることが⼤事 ▌ビルド結果を計測する l ビルドの失敗頻度やその原因を振り返れるようにしておくと あとから改善しやすい ▌防ぎづらいレアケースもあるので⾃動リトライも⼀つの⼿段 ▌環境は仮想化して毎回クリーンにする l Docker コンテナ内でビルドするのが最近は⼀般的 63

Slide 60

Slide 60 text

まとめ 64

Slide 61

Slide 61 text

意識してほしいこと ▌⾼速なフィードバックループは不確実性を下げ、学びを最⼤化する l 顧客へ提供する価値の最⼤化につながる l 例えば Amazon では毎秒なにかしら本番環境にデプロイしてる ▌ボトルネックを意識してバランス感覚を持って⾃動化する ▌リリースしてようやく顧客に価値を提供できる l コードを変更して終わりではない l チーム全体でリリースやその後のフィードバックまで責任を持つ 65

Slide 62

Slide 62 text

参考⽂献 ▌『継続的インテグレーション⼊⾨』 ▌『継続的デリバリー』 69