Slide 1

Slide 1 text

持続可能なソフトウェア開発を支える 『GitHub CI/CD実践ガイド』 ノムラトモキ(@tmknom) 1

Slide 2

Slide 2 text

ノムラトモキ(@tmknom) フリーランス/ソフトウェアエンジニア/技術書作家 2

Slide 3

Slide 3 text

GitHub CI/CD実践ガイド 持続可能なソフトウェア開発を支える GitHub Actionsの設計と運用 雰囲気でGitHub Actionsを使っている人 CI/CD未経験の人にオススメ。 Gitでコミットやプッシュが扱えて プルリクエストの利用経験があれば読める。 定価3,740円/電子版アリ 3

Slide 4

Slide 4 text

アジェンダ 1. CI/CDとはなにか 2. GitHub Actionsの基本機能と作法 3. 持続可能性を高める習慣 4. 意図的脅威に対する防衛術 5. おわりに 4

Slide 5

Slide 5 text

CI/CDとはなにか 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

CI(継続的インテグレーション) コードの変更を頻繁にコードベースへ統合し 正しく動作するか繰り返し検証する 10

Slide 11

Slide 11 text

CD(継続的デリバリー) いつでも安全にリリースできる状態を保ち ソフトウェアを繰り返し改善する 11

Slide 12

Slide 12 text

CI/CDの関係 CIとCDは同列の概念ではなく、CIはCDに包含される CIとCDはさまざまなプラクティスの集合 なにをするかはプロジェクトで固有 12

Slide 13

Slide 13 text

ソフトウェア開発の目的(再掲) ソフトウェアをとおして ユーザーに価値を届けること 13

Slide 14

Slide 14 text

CI/CDの目的 ソフトウェア開発の持続可能性を高め 長期に渡る価値提供を実現する 14

Slide 15

Slide 15 text

CI/CDの実装に役立つサービス GitHub Actions 15

Slide 16

Slide 16 text

GitHub Actionsとは GitHubが提供する汎用的なワークフローエンジン ソフトウェア開発にありがちな、多くのタスクを自動化できる 様々なイベントで起動し、各種GitHubサービスとの連携も容易 CI/CDでも大活躍 プルリクエストが作成されたら、ビルドとテストを実行する リリースタグが作成されたら、コンテナイメージをデプロイする YAMLファイルをリポジトリへ追加すれば動く GitHubを使っていれば、すぐに利用できて手軽 16

Slide 17

Slide 17 text

GitHub Actionsの実装 ワークフロー いつ・どこで・なにをするか定義 YAMLの独自構文で実装 GitHub Actionsの管理単位 ワークフローの構成要素 イベント/ランナー/ステップ/ジョブ name: Test # 配置先ディレクトリ on: # .github/workflows workflow_dispatch: pull_request: paths: ['**.go'] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: '1.22' - run: go test 17

Slide 18

Slide 18 text

構成要素:イベントとランナー イベント ワークフロー実行の起点 プルリクエストや手動実行など ランナー GitHub Actionsの実行環境 毎回クリーンな環境で起動 name: Test on: # イベント workflow_dispatch: # 手動実行 pull_request: # プルリクエスト paths: ['**.go'] jobs: test: # WindowsやmacOSも指定可 runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: '1.22' - run: go test 18

Slide 19

Slide 19 text

構成要素:ステップとジョブ ステップ 処理の最小単位 シェルコマンドやアクションを実行 ジョブ ランナーとステップを取りまとめ 複数定義すれば並列実行できる name: Test on: workflow_dispatch: pull_request: paths: ['**.go'] jobs: # ジョブは複数定義可 test: # このコードでは1つだけ定義 runs-on: ubuntu-latest steps: # ステップは処理の最小単位 - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: '1.22' - run: go test 19

Slide 20

Slide 20 text

GitHub Actionsにありがちなこと 場当たり的 構文が直感的なため、見様見真似でもわりと動く 片手間で実装することが多く、動いたら満足してしまう 運用やセキュリティは深く考えず、置き去りにされる 属人化 シニアエンジニアの腕力でなんとかしがち 「動いてるならいいんじゃね?」と雑にレビューが通過 20

Slide 21

Slide 21 text

実は学習しやすいGitHub Actions GitHubアカウントがあれば誰でも使える パブリックリポジトリなら無料で実験し放題 汎用プログラミング言語より仕様がはるかに小さい わりと短時間でキャッチアップ可能 自動化の幅が大きく広がり、使いこなせると絶大な効果 利用者が多く、情報収集しやすい 公式ドキュメントが整備され、利用者による発信も多い なによりも我々には『GitHub CI/CD実践ガイド』がある! 21

Slide 22

Slide 22 text

CI/CDの設計・運用について、ハンズオン形式で学ぶ 中核となるGitHub Actionsは、特に力を入れて解説 22

Slide 23

Slide 23 text

第I部「基礎編」 GitHub Actionsの使い方と継続的インテグレーション 第1章:ソフトウェア開発とGitHub 第2章:GitHub Actionsの基礎概念 第3章:ワークフロー構文の基礎 第4章:継続的インテグレーションの実践 第5章:運用しやすいワークフローの設計 第6章:アクションによるモジュール化 23

Slide 24

Slide 24 text

第II部「実践編」 長期運用で習慣づけたいプラクティスとリリース管理 第7章:クリーンなリポジトリの維持 第8章:Dependabotによる依存関係バージョンアップ 第9章:GitHub Releasesによるリリース自動化 第10章:GitHub Packagesによるパッケージ管理 第11章:OpenID Connectによるセキュアなクラウド連携 第12章:コンテナオーケストレーションのデプロイメント 第13章:アクションのオープンソース化 24

Slide 25

Slide 25 text

第III部「応用編」 セキュリティと持続可能性を考慮した継続的デリバリー 第14章:GitHub Actionsの高度な使い方 第15章:GitHub Actionsのセキュリティ 第16章:セキュリティのシフトレフト 第17章:GitHub Appsトークンによるクロスリポジトリアクセス 第18章:継続的デリバリーの実践 25

Slide 26

Slide 26 text

というわけでここからは 書籍で学べることを具体的に紹介 26

Slide 27

Slide 27 text

GitHub Actionsの 基本機能と作法 27

Slide 28

Slide 28 text

GitHub Actionsの基本機能 28

Slide 29

Slide 29 text

GitHub Actionsの基本機能の例 コンテキスト 29

Slide 30

Slide 30 text

コンテキストとは 複数のプロパティで構成されたオブジェクト GitHub Actionsの独自記法「 ${{ }} 」で参照 - run: echo "${{ github.event.pull_request.title }}" # コンテキストからPRタイトルを取得 利用頻度が非常に高く、さまざまなデータへのアクセスに利用 ブランチ名・イベント名・実行者・PR番号などの実行時情報 ワークフロー手動起動時に指定できる入力パラメータ VariablesやSecretsが保持している値 30

Slide 31

Slide 31 text

コンテキストのアンチパターン シェルコマンドへコンテキストを直接埋め込むのはNG スクリプトインジェクションという攻撃に利用されてしまう - run: echo "${{ github.event.pull_request.title }}" # 脆弱性アリなBad Code! 不正なタイトルでプルリクエストを作成すると… 文字列ではなく、シェルコマンドとして解釈される! 31

Slide 32

Slide 32 text

公式ドキュメントを含む多くのコードに散見 コピペで書いていると、この地雷を踏み抜きやすい 32

Slide 33

Slide 33 text

コンテキストのツラミ 大前提として外部から入ってくる値は信頼してはいけない どの値が「信頼できない」か判別は困難 GitHubが生成する安全な値と、そうでない値が混在 容疑者の数が多いうえ、信頼の有無はドキュメント化されていない ブランチ名やラベルのような、普段意識しない値も信頼できない イベントによってオブジェクトの構造自体が変わる コードレビューなどを実施しても、ほぼ確実に見落とす 33

Slide 34

Slide 34 text

中間環境変数 コンテキストを環境変数へマッピングし、環境変数経由で参照する 環境変数をクォートするのがミソ コマンド実行を抑止し、ただの文字列として扱う - run: echo "${PR_TITLE}" # 環境変数は忘れずにダブルクォーテーションで囲む! env: PR_TITLE: ${{ github.event.pull_request.title }} # 環境変数へマッピング 同じように記述しても、コンテキストの場合はクォートされない - run: echo "${{ github.event.pull_request.title }}" # クォートされない! 34

Slide 35

Slide 35 text

GitHub Actionsの基本機能(再掲) 35

Slide 36

Slide 36 text

GitHub Actionsの作法はいくつもある 熟練者が実践しているグッドプラクティス 知っていれば避けられるアンチパターン フェイルファストを実現するためのポイントはなにか? トラブルシューティングしやすいようにどう実装すべきか? メンテナンス性を考慮したときに、注意すべき機能はなにか? 36

Slide 37

Slide 37 text

早めに知っておくと役立つ作法の例 グッドプラクティス タイムアウトは明示的に指定する(デフォルトだと6時間) パイプエラーが拾えるように、デフォルトシェルを記述する Concurrencyでワークフローを自動キャンセルする ログをグループ化して、ログの読みやすさを向上させる アンチパターン Secretsのログマスクは簡単に回避できるので注意する パーミッションを省略して、過剰な権限を与えないよう注意する 37

Slide 38

Slide 38 text

基本機能と作法を一緒に学ぼう 基本機能の各要素は難しくない 単に使うだけならすぐ習得できる 難しいのはうまく使うこと うまく使うには本来、ある程度の経験と時間が必要 本書では構文などと一緒に、作法も同時に学べて効率的 急がば回れ 少し時間を割いて、基礎的な知識を積み上げよう 地力をつけておけば、応用力が飛躍的に高まる 38

Slide 39

Slide 39 text

成果をあげる人とあげない人の差は才能ではない。 いくつかの習慣的な姿勢と基礎的な方法を 身につけているかどうかの問題である。 Peter Drucker 39

Slide 40

Slide 40 text

持続可能性を 高める習慣 40

Slide 41

Slide 41 text

CI/CDの目的(再掲) ソフトウェア開発の持続可能性を高め 長期に渡る価値提供を実現する 41

Slide 42

Slide 42 text

持続可能性 ソフトウェアの想定稼働期間中に 依存関係・技術・製品要件における 変化に反応できる 出典: Googleのソフトウェアエンジニアリング 42

Slide 43

Slide 43 text

変化に反応するために習慣づけたいこと 依存関係のバージョンアップ 43

Slide 44

Slide 44 text

唐突ですが、こんな経験はありませんか? なにもしてないのに壊れた 44

Slide 45

Slide 45 text

ほうっておくとソフトウェアは壊れる たとえコードを一行も変えていなくても 我々の事情とは無関係に、取り巻く環境は変化し続ける ソフトウェアは多くのものに依存している ハードウェア・OS・言語・ライブラリ・外部システム 45

Slide 46

Slide 46 text

ソフトウェアに停滞は許されない OSSひとつあたり、平均で年15回バージョンアップが発生する 出典: https://www.sonatype.com/state-of-the-software-supply-chain/open-source-supply-and-demand 46

Slide 47

Slide 47 text

依存関係のバージョンアップは面倒 安全にバージョンアップするには、やることがたくさんある 1. 検知:新しいバージョンがリリースされたことを知る 2. 把握:具体的にどのような変更が行われたか理解する 3. 実装:新しいバージョンを自身のコードへ組み込む 4. テスト:リグレッションテストを実施し、壊れたら対処する 基本的にはやりたくないが、さりとて放置もできない バグや脆弱性を含む依存関係の利用はリスク 放置しすぎると差分が大きすぎて、身動きが取れなくなる 47

Slide 48

Slide 48 text

依存関係のバージョンアップはやるべきだが 数は多いし頻度も高くて大変すぎる どうにかならないか? 48

Slide 49

Slide 49 text

Dependabot version updates 依存関係バージョンアップの検知・把握・実装を自動化できる 新しいバージョンが出ていないか、定期的にチェック 検知時に自動でバージョンアップのプルリクエストを作成 バージョンアップをトリガーに、GitHub Actionsを起動可能 適切な自動テストがあれば、マージまで自動化できる 49

Slide 50

Slide 50 text

Dependabot version updatesの実装 設定ファイルをリポジトリへ追加すれば自動実行される npm・yarn・pip・Maven・Gradle・Bundler・Go modules・ NuGet・Composer・Cargoなど、主要なものはサポート version: 2 updates: - package-ecosystem: github-actions directory: / schedule: interval: daily 50

Slide 51

Slide 51 text

他にもある大事なこと ソフトウェア開発の長期運用に不可欠な習慣 クレデンシャルをソースコードへ平文で保存しない コードベースをクリーンに保つため、レビューやCIを必須にする たまに落ちるテストを放置せず、設計を改善する リリースでは適切なバージョニングとアナウンスを実施する やっている人とやっていない人の落差が激しい 個々人の意思や規律だけで担保するのは難しい 51

Slide 52

Slide 52 text

世の中の大事なことって たいてい面倒くさいんだよ 宮崎駿 52

Slide 53

Slide 53 text

既存ソリューションの力を借りる GitHubがシレッと提供している機能をうまく活用する ルールセット:ブランチやGitタグの保護 CODEOWNERS:オーナーシップの維持と自動レビュー通知 シークレットスキャン:コードに埋まったクレデンシャルの検知 GitHub Releases:ソフトウェアとリリースノートの配信 小さな習慣の積み重ねが持続可能性を高める 本書では良い習慣を身につけるためのヒントがたくさんある 既存の仕組みを活用すれば、無理なく実践できる 53

Slide 54

Slide 54 text

意図的脅威に対する 防衛術 54

Slide 55

Slide 55 text

脅威の種類 環境的脅威 地震・洪水・火災・落雷停電 政治不安・社会的な変動・パンデミック 偶発的脅威 誤操作などのヒューマンエラー コードに含まれるバグや設定ミス 意図的脅威 マルウェア・不正アクセス・DDoS・フィッシング 特権管理者によるインサイダー攻撃 55

Slide 56

Slide 56 text

ソフトウェアサプライチェーン コードを書いてからリリースするまでのプロセス・構成要素 出典: https://slsa.dev/spec/v1.0/threats 56

Slide 57

Slide 57 text

ソフトウェアサプライチェーン攻撃は増加傾向 出典: https://www.sonatype.com/state-of-the-software-supply-chain/open-source-supply-and-demand 57

Slide 58

Slide 58 text

GitHub Actionsに対する意図的脅威の例 第三者が実装したアクション 58

Slide 59

Slide 59 text

アクションとは GitHub Actionsにおけるモジュールの一種 他者が実装したアクションを使えば、実装の手間が省ける - uses: actions/checkout@v4 # コードを取得するアクション 大変便利な仕組みで、GitHub Actionsでは不可欠な要素 誰でも簡単に実装でき、多数のアクションが公開されている アクション公開時に審査などは行われない 一般的なOSSと同様、自己責任で利用する 59

Slide 60

Slide 60 text

アクションに許されている操作は? GitHub Actionsで実行できるあらゆる操作が可能 ソースコードやクレデンシャルの参照 任意のファイルダウンロードと任意のコマンド実行 クレデンシャルを利用した外部システムへのアクセス アクションは便利 = 攻撃にも便利 ひとたび攻撃が成功すると、同時多発的な被害に 60

Slide 61

Slide 61 text

第三者のアクションを利用 = 全権委任 鎖の強度は一番弱い環の強さで決まる アクション提供者のセキュリティレベルが ワークフローのセキュリティレベルの上限になる 61

Slide 62

Slide 62 text

侵害事例:Codecov コードカバレッジの可視化に便利なサービス アクション内で利用していたスクリプトが改ざんされた 多数の企業のクレデンシャルが流出 本番システムへ不正アクセスされた可能性 ローテーションと侵害の調査が各社で行われるハメに プライベートリポジトリで管理していたコードも漏えい 個人情報をコードに含めていた企業では、個人情報の流出も 62

Slide 63

Slide 63 text

アクション提供者を信頼できるか? アクション提供者に裏切られるとどうにもならない アクション提供者が侵害された場合も一蓮托生 「本当に信頼するか」を意識的に決断する 第三者のアクションを利用する前に、一度立ち止まる NDAも結ばず、リポジトリを差し出すに等しいが本当によいか? 場合によっては、車輪の再発明もやむを得ない 63

Slide 64

Slide 64 text

アクションのリスク低減策 Verified Creatorsを信頼の目安にする 絶対ではないが、それなりに安全性は高いと期待できる Gitタグではなく、コミットハッシュで固定する 事実上アクションを不変リソースとして扱う - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 64

Slide 65

Slide 65 text

他にもある脅威への対抗策 GitHub Actionsのセキュリティ向上 リポジトリの適切なアクセス制御 GITHUB_TOKENの明示的なパーミッション定義 OpenID Connectによる一時クレデンシャルの利用 実装しているソフトウェアのセキュリティ向上 依存関係やコンテナイメージの脆弱性スキャン Static Application Security Testing Infrastructure as Codeの設定ミス防止 65

Slide 66

Slide 66 text

脅威に対する防衛は長期戦 ソフトウェアの運用を続ける限りつきまとう 無理せず一気にやろうとしない 少しずつ改善する/継続的に改善する 66

Slide 67

Slide 67 text

おわりに 67

Slide 68

Slide 68 text

執筆中に心がけたこと 「経験をとおして学ぶコト」の言語化に注力 現場で培ったノウハウに基づいて、設計や運用の考え方を紹介 大量の参考文献からエッセンスを抽出し、実践の勘所を解説 「最高の読書体験を提供する」がコンセプト サクサク読めるよう鬼のようにチューニング 68

Slide 69

Slide 69 text

次のステップへ 特定の領域をより深く学ぶのに役立つ書籍たち 69

Slide 70

Slide 70 text

読者の声:SNS 出典: https://x.com/voluntas/status/1824084748437983351 70

Slide 71

Slide 71 text

読者の声:ブログ 出典: https://kakakakakku.hatenablog.com/entry/2024/08/16/151227 71

Slide 72

Slide 72 text

読者の声:Amazon 出典: https://www.amazon.co.jp/gp/customer-reviews/R3KNQVGUZG5FQS/ 72

Slide 73

Slide 73 text

ソフトウェア開発をもっと楽しく! 73

Slide 74

Slide 74 text

ご清聴ありがとうございました 74