Azure DevOpsで実現するCI/CDパイプライン最適化

23分で読めます
エンハンスド技術チーム
Azure DevOpsCI/CDパイプライン自動化DevOps
Azure DevOpsを使った効率的なCI/CDパイプラインの構築と最適化テクニックを解説します。

Azure DevOps CI/CD:金曜日のデプロイが怖くなくなった日

はじめに:「また週末が台無しか...」

「金曜日のデプロイはやめとこう」 「でも月曜まで待つと、変更が溜まりすぎて余計危険じゃない?」 「じゃあ、祈りながらやるか...」

こんな会話、聞き覚えありませんか?私たちのチームでは毎週金曜日の定番でした。

デプロイに4時間。その後のエラー対応で深夜まで。土曜日も出社して対応...こんな生活を3年も続けていました。

そんな私たちがAzure DevOpsと出会って、今では「金曜の夕方?全然OK!」とケロッとしています。

何が変わったのか、恥ずかしい失敗談も含めて全部お話しします。

YAMLパイプライン:「この呪文、何語?」から始まった物語

最初は本当に意味不明だった

正直に告白します。初めてazure-pipelines.ymlを見た時、画面を閉じました。

「trigger? pool? steps? 何これ...」 「スペースが2個じゃなくて3個だとエラー?意味わからん」

でも、先輩エンジニアが教えてくれたんです。 「これ、実はレシピみたいなもんだよ」

その一言で目から鱗が落ちました。

料理のレシピと同じ。材料(リソース)を用意して、手順(ステップ)通りに進めるだけ。しかも、このレシピはGitで管理できて、みんなでレビューできる!

「Hello World」から始めた私たちの挑戦

最初の一歩は本当に小さかった。

月曜日の朝、チーム全員で画面を囲んで「えいっ」とコミット。 5秒後...「Build succeeded」の緑色のマークが!

「おお!動いた!」

たった「Hello, World!」を表示するだけのパイプライン。でも、この小さな成功体験が全ての始まりでした。

それから毎日少しずつ機能を追加:

  • 火曜日:「ビルドも自動化してみよう」
  • 水曜日:「テストも追加できるんじゃない?」
  • 木曜日:「成果物の保存もできた!」
  • 金曜日:「来週はデプロイも自動化だ!」

3ヶ月後、気づいたら本格的なCI/CDパイプラインが動いていました。まるで、積み木を一つずつ積み上げるような感覚でした。 displayName: 'Run unit tests' inputs: command: 'test' projects: '**/*Tests.csproj' arguments: '--configuration $(BuildConfiguration) --no-build --collect:"XPlat Code Coverage" --logger trx --results-directory $(Agent.TempDirectory)' publishTestResults: true

- task: PublishCodeCoverageResults@1
  displayName: 'Publish code coverage'
  inputs:
    codeCoverageTool: 'Cobertura'
    summaryFileLocation: '$(Agent.TempDirectory)/**/coverage.cobertura.xml'

- task: SonarCloudAnalyze@1
  displayName: 'Run SonarCloud analysis'

- task: SonarCloudPublish@1
  displayName: 'Publish SonarCloud results'
  inputs:
    pollingTimeoutSec: '300'

- task: DotNetCoreCLI@2
  displayName: 'Publish application'
  inputs:
    command: 'publish'
    publishWebProjects: true
    arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory) --no-build'
    zipAfterPublish: true

- task: PublishBuildArtifacts@1
  displayName: 'Publish artifacts'
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'
  • stage: SecurityScan displayName: 'Security Scanning' dependsOn: Build condition: succeeded() jobs:
    • job: SecurityScanJob

恥ずかしい失敗の数々(でも今は笑い話)

「なんでビルドが止まるの?」事件

金曜日の夕方、ビルドが30分で突然停止。 「バグ?」「設定ミス?」「Azure側の問題?」

3時間調査して分かった原因:タイムアウトのデフォルト設定... 「最初に言ってよ!」とドキュメントに八つ当たり(笑)

「パスワード流出」危機一髪

コードレビューで先輩が青ざめた顔で... 「これ、本番のパスワード丸見えだけど」

慌ててGitの履歴から削除。Variable Groups使えばよかった... 今では笑い話ですが、当時は本当に焦りました。

「高速化のつもりが逆効果」の罠

「並列実行すれば速くなる!」と意気込んで全部並列に。 結果:エージェント不足で順番待ち地獄。

単純に並列化すればいいってもんじゃないんですね...

ステージとジョブ:「パイプラインを積み木みたいに」

「ステージって必要?」から「ステージなしでは生きられない」へ

最初は正直、面倒だと思ってました。 「全部一気に実行すればいいじゃん」

でも、ある日の失敗で考えが変わりました。

本番デプロイ中にテストが失敗。でも、もう遅い。本番は半分だけ新バージョンという最悪の状態に...

「あー、ステージ分けてれば止められたのに」

そこから真剣にステージ設計を考えるように。今では:

朝9時:コードをプッシュ 9時05分:ビルド完了、テスト開始 9時15分:開発環境にデプロイ 9時25分:統合テスト完了 9時30分:「本番行きますか?」の通知 (ここでコーヒーブレイク) 9時45分:承認ボタンをポチッ 9時48分:本番デプロイ完了!

以前の4時間が30分に。しかも、どの段階でも止められる安心感付き。

再利用可能なテンプレート:DRYの極み

「コピペ地獄」からの解放

最初は各環境用に同じようなYAMLを3つも4つも書いてました。 「開発環境のデプロイ手順変えたから、ステージングも本番も全部書き換えて...」

疲れました。そして気づいたんです、テンプレート機能の素晴らしさに!

テンプレート化して良かったこと:

  • 修正が1箇所で済む(神!)
  • パラメータで環境ごとの違いを吸収
  • チーム全員が同じ手順でデプロイ
  • ミスが激減(コピペミスがなくなった)

実際に使ってるテンプレート構成

# シンプルなデプロイテンプレートの例
parameters:
- name: environment
  type: string

steps:
- script: echo "Deploying to ${{ parameters.environment }}"
- task: AzureWebApp@1
  inputs:
    appName: 'myapp-${{ parameters.environment }}'

たったこれだけで、全環境で使い回せる!

つまずきポイント: パラメータの型を間違えて30分悩んだ。stringobjectの違いは重要...

Blue-Greenデプロイ:「魔法みたい!」と叫んだ日

「ユーザーに気づかれずにデプロイ」の衝撃

忘れもしない、火曜日の午後2時。 一番アクセスが多い時間帯に、あえてデプロイしてみました。

社内チャット: 「今からデプロイします」 「え?今?ユーザー使ってるよ?」 「大丈夫です、見ててください」

3分後...

「デプロイ完了しました」 「嘘でしょ?エラー出てない?」 「ユーザーからクレームは?」 「何も起きてません」

本当に魔法を使った気分でした。ユーザーは何も気づかずにサービスを使い続けている。その裏で、こっそり新バージョンに切り替わっている。

仕組みを理解した今でも「これ、すごくない?」って思います。

実際にやってみて分かったこと

メリット:

  • ダウンタイムゼロ(本当にゼロ!)
  • ロールバックが一瞬(スロット入れ替えるだけ)
  • 本番と全く同じ環境でテスト可能

デメリット:

  • コストが2倍(2つの環境が必要)
  • データベース移行は要注意
  • 設定が少し複雑

つまずきポイント: 最初、ウォームアップを忘れて、切り替え直後にレスポンスが遅くなった。今は必ずウォームアップしてから切り替えてます。

手動承認:「ストップ!」と言える幸せ

金曜日の午後4時。Teamsに通知が。 「本番デプロイの準備ができました。承認してください」

チームメンバー:「今日は早く帰りたいから月曜にしない?」 私:「了解!」(承認を保留)

以前なら「一度始めたら止められない」デプロイ。今は違います。

ある日のエピソード: ステージング確認中に気づいた。「あれ?このボタンの色、違くない?」 承認を却下して、修正してから再度デプロイ。

もし自動で本番まで行ってたら、お客様から「ボタンが見づらい」ってクレームが来てたかも。

「人間の最終チェック」って、やっぱり大事ですね。

自動ロールバック:保険があるから攻められる

「デプロイ後にエラー率が上がったら自動で戻す」

この仕組みを入れてから、デプロイのプレッシャーが激減しました。

実際に自動ロールバックが発動した事例:

  • データベース接続文字列の設定ミス(5分で自動復旧)
  • 外部APIのURL変更忘れ(3分で検知、自動復旧)
  • パフォーマンス劣化(レスポンス2秒超えで自動復旧)

全部、お客様が気づく前に復旧できました!

パフォーマンステスト:「本番で遅い!」の恐怖から解放

あの日の悪夢

月曜日の朝9時。サポートチームから緊急連絡。 「サイトがめちゃくちゃ遅いんですけど!」

確認すると、トップページの表示に15秒... 原因は金曜日にリリースした新機能。データベースのインデックスを張り忘れてました。

朝一番から大騒ぎ。お客様にも迷惑をかけて、本当に申し訳ない気持ちでいっぱいでした。

「もう二度とこんな思いはしたくない」

そこから、パフォーマンステストの自動化に本気で取り組みました。

今では「本番より厳しい条件」でテストしてからリリース。 「遅い」という苦情はゼロになりました。

実際の負荷テストシナリオ

# 最小限の負荷テスト設定
- task: AzureCLI@2
  displayName: 'Run load test'
  inputs:
    inlineScript: |
      # 100ユーザーで5分間アクセス
      artillery quick --count 100 --num 50 https://staging.myapp.com/

シンプルだけど、これだけでも全然違う!

発見した問題の例:

  • N+1問題(100件表示で100回DB アクセス...)
  • キャッシュ未設定(同じデータを何度も取得)
  • 画像最適化忘れ(1枚3MBの画像が...)

本番で見つかってたら大変でした。

自動ロールバック:「守護神」のような存在

ある水曜日の昼下がり。デプロイ完了の通知を見て、ランチに出かけました。

15分後、スマホが震える。 「自動ロールバックを実行しました」

慌てて確認すると、新機能のメモリリークが原因でした。 もし自動ロールバックがなかったら、ランチから戻ってきた時にはサーバーダウンしてたかも...

「ありがとう、自動ロールバック君」

心の中でつぶやきました。

別の日には、外部APIがたまたまメンテナンス中で、それを検知して自動ロールバック。 「そんなことまで守ってくれるの?」と驚きました。

まるで24時間体制の守護神がいるような安心感。これがあるから、積極的に新機能をリリースできるんです。

パフォーマンス監視:「遅くなったら自動で戻す」

レスポンスタイムが20%以上悪化したら自動ロールバック。 シンプルだけど、効果抜群!

実装のコツ:

  • ベースラインは過去24時間の平均値
  • 一時的なスパイクは無視(5分間の平均で判断)
  • 閾値は環境に応じて調整(最初は緩めに)

テストの自動化:「手動テスト地獄」からの解放

昔は全部手動でテストしてた...

「リリース前のテスト、3日かかります」 「えっ、そんなに?」 「全画面、全機能を手動で確認するので...」

今思えば狂気の沙汰でした。

自動テスト導入後:

  • 単体テスト:3分で5000件実行
  • 統合テスト:10分で全API確認
  • E2Eテスト:15分で主要シナリオ完了
  • セキュリティテスト:5分で脆弱性チェック

合計33分!以前の3日が30分になりました。

テストの並列実行で時間短縮

# シンプルな並列実行の例
jobs:
- job: Tests
  strategy:
    parallel: 3  # 3つ同時実行!

これだけで実行時間が1/3に!

つまずきポイント:

  • DB使うテストは並列化注意(データが混ざる)
  • 依存関係があるテストは順番に
  • エージェント数の上限に注意

監視とアラート:「気づいたら落ちてた」を撲滅

Application Insightsで全部見える化

「デプロイの成功率って何%?」 「先月、何回ロールバックした?」 「平均デプロイ時間は?」

以前は答えられませんでした。今は即答できます!

見える化して分かったこと:

  • 金曜日のデプロイ成功率が低い(疲れてる?)
  • 午前中のデプロイが最も安定
  • 特定の開発者のデプロイがよく失敗する(サポートが必要)

アラート設定:寝てても安心

実際に設定してるアラート:

  1. レスポンスタイム監視

    • 平均2秒超えたらWarning
    • 5秒超えたらCritical
    • 夜中でも電話が鳴る(Critical時のみ)
  2. エラー率監視

    • 5%超えたらWarning
    • 10%超えたら自動ロールバック
  3. デプロイ監視

    • 30分以上かかったらアラート
    • 失敗したら即通知

つまずきポイント: 最初、閾値を厳しくしすぎて、アラートの嵐に...今は現実的な値に調整してます。

ダッシュボード:経営陣も納得

今月のデプロイ実績
━━━━━━━━━━━━━━━━━━
成功: 145回 (96.7%)
失敗: 5回 (3.3%)
平均時間: 12分
ロールバック: 2回

これを見せたら、DevOps投資の追加予算が承認されました!

導入効果:「人生変わった」は大げさじゃない

数字が物語る劇的な変化

社内プレゼンで使ったスライドを見返すと、今でも信じられません。

月1回→1日10回のリリース

以前:「来月の定期リリースに間に合わせなきゃ」 今:「午前中に3回リリースしちゃった」

300倍って、もはや別世界です。

4時間→15分のデプロイ時間

金曜日の午後の過ごし方:

  • 以前:会議室に缶詰め、ピザ注文、徹夜覚悟
  • 今:普通に仕事して、定時で帰宅

「金曜日の呪い」から解放されました。

深夜対応がゼロに

妻に言われた一言: 「最近、夜中に電話鳴らなくなったね」

そうなんです。自動ロールバックのおかげで、深夜に起こされることがなくなりました。 家族との時間も増えて、本当に人生変わったなって思います。

「本当に元取れるの?」への明確な答え

経営会議での一幕:

社長:「で、いくらかかるの?」 私:「初期投資200万円です」 社長:「高いなぁ...」 私:「3ヶ月で回収できます」 社長:「本当に?」

そして見せたのがこの数字:

残業代だけで月100万円削減

  • 金曜デプロイの残業:ゼロ
  • 深夜対応の特別手当:ゼロ
  • 休日出勤:ほぼゼロ

見えない効果も含めると...

  • 離職率低下(採用コスト削減)
  • 開発スピード向上(売上増加)
  • 顧客満足度向上(解約率低下)

半年後の経営会議: 社長:「もっと早く導入すべきだった」

にやりと笑ってしまいました。

チームの笑顔が増えた(これが一番の成果)

金曜日の夕方のSlackを見返すと、変化は明らか。

1年前: 「今日もデプロイか...」 「pizza注文する?」 「月曜日まで祈ってます」

今: 「今週もお疲れ様!」 「飲み行く?」 「良い週末を!」

新入社員の感想が印象的でした: 「前職では金曜デプロイ禁止だったんです。ここは金曜日も普通にリリースしてて、最初はビビりました。でも、全然問題ないんですね」

採用面接でよく聞かれること: 「本当に定時で帰れるんですか?」 「はい、CI/CDのおかげで」

この会話ができるようになったのが、地味に嬉しいです。

まとめ:「もう戻れない」世界へようこそ

先日、3年前の日記を見つけました。

「また金曜の徹夜。いつまでこんな生活続けるんだろう」

今の私がタイムマシンで過去に戻れるなら、真っ先に伝えたい。 「3年後、君は金曜の夕方にデプロイして飲みに行ってるよ」って。

本当に変わったこと:

仕事が「作業」から「創造」に変わりました。

デプロイ作業に使っていた時間で:

  • 新しい技術の勉強会を開催
  • お客様の要望にすぐ対応
  • チームでアイデアを議論
  • そして何より、定時に帰宅

後輩エンジニアに言われた一言:

「先輩、なんでそんなに楽しそうに仕事してるんですか?」

そうか、楽しそうに見えるのか。 確かに、デプロイのストレスがなくなってから、純粋にコードを書くのが楽しくなった。

あなたへのメッセージ:

もし今、金曜日のデプロイを恐れているなら。 深夜対応で疲れ果てているなら。 「これが当たり前」と諦めているなら。

大丈夫、必ず変われます。

私たちも最初は「無理」と思ってました。 でも、小さな一歩から始めて、今ではもう戻れない世界にいます。

最初の一歩は「Hello World」をビルドするだけでいい。 そこから、あなたの「デプロイ天国」が始まります。

エンハンスド株式会社では、その最初の一歩を一緒に踏み出すお手伝いをしています。3年前の私たちと同じ悩みを持つあなたに、「もう戻れない」世界をお見せします。

参考リンク


執筆者: エンハンスド株式会社 DevOpsチーム
公開日: 2025年5月1日
カテゴリ: DevOps, CI/CD, 自動化
タグ: #AzureDevOps #CICD #自動化 #デプロイ自動化 #DevOps #パイプライン

技術的な課題をお持ちですか?

記事でご紹介した技術や実装について、
より詳細なご相談やプロジェクトのサポートを承ります

無料技術相談を申し込む