Azure Pipelinesの使い方|YAMLでCI/CDを組む手順と無料枠・権限設定
Azure Pipelinesは、Azure DevOpsに含まれるビルド・テスト・デプロイの自動化サービスです。GitHubやAzure Reposのリポジトリにazure-pipelines.ymlを1本置けば、プッシュのたびにビルドとテストが走り、承認を挟んで本番へ配布するところまで動く。ただし最初に足を取られるのは構文ではありません。無料の並列ジョブが「有効化しないと付与されない」点と、サービス接続の権限設計です。ここでは公式仕様(Microsoft Learn 2026年6月更新版)を基準に、最初のパイプライン作成から料金・権限・承認までの手順を通しで整理します。
まとめ
- Microsoftホステッドの無料枠(1回60分・月1,800分・並列1)は自動では付かない。組織にAzureサブスクリプションをリンクして課金設定を済ませて初めて、プライベートプロジェクトへ適用される。
- 並列ジョブを1本購入しても同時実行数は1のまま。1本目の購入で外れるのは「月1,800分」と「1ジョブ60分」の制限だけ(有料は1ジョブ360分・月間上限なし)。同時に2本流すには2本の購入が必要になる。
- 使い方はYAML(azure-pipelines.yml)を軸に覚える。Microsoftはクラシックパイプラインの新規作成禁止を2023年3月以降に作成された組織で既定にする方針を公表しており、今から新規で選ぶ理由がない。
- Azureへのデプロイはワークロード ID フェデレーションのサービス接続にする。ただし現行のAzure DevOps issuerは2027年7月1日に廃止予定で、Microsoft Entra issuerへの変換が別途必要。
- 承認待ちのステージは並列ジョブを消費しない。承認ゲートをステージ間に置いてもビルド枠は空くため、無料枠のままでも段階デプロイは成立する。
Azure Pipelinesの守備範囲とDevOpsパイプラインの構成
DevOpsパイプラインは、コード変更を本番に届けるまでの工程を自動化した流れを指します。一般には「ソース取得 → ビルド → テスト → 成果物(アーティファクト)の保存 → 各環境へのデプロイ」という段階に分かれ、前半のビルドとテストがCI、後半の配布がCDにあたる。Azure Pipelinesはこの全段階を1つのYAMLで記述でき、途中でJenkinsや別のデプロイツールへ橋渡しする必要がありません。
Azure PipelinesはAzure DevOpsを構成するサービスの一つです。リポジトリ(Azure Repos)、作業項目管理(Azure Boards)、パッケージ管理(Azure Artifacts)と同じ組織・プロジェクト単位の権限で動きます。Azure DevOps全体でどのサービスがどこを担うかはAzure DevOpsとは何か?マイクロソフトが提供する統合開発環境の全体像で整理しています。
YAMLとクラシックエディタの選択基準
Azure Pipelinesには、YAMLファイルで定義する方式と、画面上でタスクを積み上げるクラシックエディタの2方式があります。今から使い方を覚えるならYAML一択です。理由は好みではなく提供状況にある。Microsoftはクラシックパイプラインの新規作成を禁止するトグルを用意し、Azure DevOps Blogで「2023年3月以降に作成された組織では既定でオンにする方針」を公表しました(既存組織で自動的にオンにする予定はない、とも明記されています)。新規組織はYAML前提で設計しておくのが安全です。
YAML側の実利は3つあります。パイプライン定義がリポジトリに入るのでプルリクエストでレビューできること、ブランチごとに定義を分岐できること、リソースへのアクセス許可をパイプライン単位で管理できることです。クラシックからの移行は、既存のリリース定義を段階的にstagesへ書き写す形になります。
無料枠の有効化条件と並列ジョブの料金
「azure pipelines 使い方」で調べてYAMLを書き終えたあと、最初に詰まるのがここです。実行を押しても「キューに登録」のまま進まないケースの大半は、構文ではなく無料枠が有効化されていないことが原因になります。
無料枠の付与条件(自動では付かない)
Azure Pipelinesの並列ジョブには、Microsoftホステッド(Microsoftが用意する実行環境)とセルフホステッド(自前のマシンにエージェントを入れる方式)の2種類があり、それぞれに無料レベルがあります。公式ドキュメントが明記しているとおり、セルフホステッドの無料レベルは自動で付与されますが、Microsoftホステッドの無料レベルは有効化が必要です。条件は、Azure DevOps組織を有効なAzureサブスクリプションにリンクし、組織の課金を設定すること。課金を構成すると、無料付与がプライベートプロジェクトへ自動的に適用されます。
| レベル | 並列ジョブ | 1ジョブの実行時間上限 | 月間の実行時間 |
|---|---|---|---|
| 無料(Microsoftホステッド) | 1 | 60分 | 1,800分(30時間) |
| 有料(Microsoftホステッド) | 購入した本数 | 360分 | 上限なし |
| 無料(セルフホステッド) | 1+VS Enterpriseサブスクライバー数 | なし | なし |
新しい組織では、Microsoftホステッドの並列ジョブは最大25本までに制限されます。それ以上が必要ならサポートへの引き上げ申請が要ります。
1本目の購入で外れるものと外れないもの
課金設計で最も誤解が多い点です。Microsoftホステッドの並列ジョブを1本購入しても、組織の同時実行数は1のまま変わりません。1本目の購入で消えるのは「月1,800分」の上限と「1ジョブ60分」の制限だけ。2本のパイプラインを同時に流したいなら、無料レベルから始める組織は2本購入する必要があります。ビルドが詰まっているのか、単に長時間ジョブが打ち切られているのかを取り違えると、買っても待ち行列は解消しません。
必要本数の目安として、公式は「組織の4〜5人につき1本」という経験則を示しています。実測で判断するなら、エージェントプールの「分析」タブにあるプール消費レポートを見る。過去30日の実行中ジョブとキュー待ちジョブの推移が出るので、キューが積み上がったまま実行中ジョブが上限に張り付いていれば購入、そうでなければ長時間ジョブの分割が先です。
パブリックプロジェクト無料枠の廃止(2027年)
OSSリポジトリ向けに10本の無料並列ジョブが付くパブリックプロジェクトを前提にした解説が今も多く残っていますが、この前提はすでに崩れました。Azure DevOpsのパブリックプロジェクトは廃止が決まり、新しいパブリックプロジェクトは作成できません。既存のパブリックプロジェクトは現在の無料並列付与を保持したまま2027年にプライベートへ変換され、変換後はプライベートと同じ割り当て(1並列・月1,800分)になります。公開リポジトリのCIをAzure Pipelinesの無料枠に寄せる設計は、今から新規に組むべきではありません。
最初のパイプラインを作る手順
ここからが実際の使い方です。Azure DevOpsの組織とプロジェクトが作成済みで、課金設定が済んでいる前提で進めます。
リポジトリ接続からYAML生成までの操作
プロジェクトの左メニューから「Pipelines」を開き、「New pipeline」を選ぶ。ソースの選択でGitHub、Azure Repos Git、Bitbucket Cloudなどを指定すると、リポジトリ内容から言語が推定され、テンプレート候補が提示されます。テンプレートを選ぶとazure-pipelines.ymlの雛形が生成され、「Save and run」でリポジトリのルートにコミットされる。この時点でmainブランチへのプッシュをトリガーとしたCIが動き始めます。
GitHubをソースにする場合は、Azure Pipelinesアプリのインストール許可が求められます。組織のリポジトリを対象にするならGitHub側の管理者権限が必要です。
YAML最小構成(trigger・pool・steps)とコード例
Azure PipelinesのYAMLは、いつ動かすか(trigger)、どこで動かすか(pool)、何をするか(steps)の3要素が骨格になります。Node.jsアプリの例を挙げます。
trigger:
branches:
include:
- main
pool:
vmImage: 'ubuntu-24.04'
steps:
- task: NodeTool@0
inputs:
versionSpec: '24.x'
displayName: 'Node.js のセットアップ(LTSを固定)'
- script: |
npm ci
npm run build
npm test
displayName: 'ビルドとテスト'
- publish: '$(System.DefaultWorkingDirectory)/dist'
artifact: 'drop'
displayName: '成果物の発行'
stepsには2種類あります。scriptはシェルコマンドをそのまま実行し、taskはAzure Pipelinesが提供する定型処理(SDKのセットアップ、Azureへのデプロイなど)を呼び出す。NodeTool@0の末尾の数字はタスクのメジャーバージョンで、固定しておくと後方互換の壊れる更新を避けられます。成果物の発行は、古い記事に多いPublishBuildArtifacts@1ではなくpublish(PublishPipelineArtifactの短縮構文)を使ってください。Azure DevOps Servicesでは公式がこちらを推奨しており、転送も速くなります。$(System.DefaultWorkingDirectory)のような定義済み変数は、パスを環境に依存させないために使います。
エージェントイメージの指定とイメージ更新への追従
vmImageに指定するMicrosoftホステッドのイメージは更新され、古いイメージは削除されます。ここをubuntu-latestのようなエイリアスで書いていると、ある日ビルド環境が入れ替わって落ちる。実際、ubuntu-latestの実体はUbuntu 22.04から24.04へ切り替わり、24.04で削除されたツールに依存していたパイプラインが影響を受けました。Windows側では、Windows Server 2019のホステッドエージェントイメージが2025年12月31日に廃止済みです。windows-latestの実体はWindows Server 2025(Visual Studio 2022搭載)で、Visual Studio 2026を載せたwindows-2025-vs2026が2026年3月9日からパブリックプレビューとして提供されています。
依存が厳しいプロジェクトでは、上のコード例のようにvmImage: 'ubuntu-24.04'とバージョンを固定し、提供終了アナウンスに合わせて計画的に上げるほうが事故が少ない。エイリアス指定は「常に最新でよい」と割り切れる場合に限ります。なおpoolを書かなかったYAMLパイプラインの既定イメージはubuntu-latestです。
ステージ分割と環境ごとの承認
単一ジョブのCIが動いたら、次はデプロイまでの流れをステージに分けます。YAMLの構造はstages → jobs → stepsの3階層で、ステージ単位で実行順と承認を制御する。
stagesとdeploymentジョブの記述
stages:
- stage: Build
jobs:
- job: BuildApp
pool:
vmImage: 'ubuntu-24.04'
steps:
- script: npm ci && npm run build
displayName: 'ビルド'
- stage: DeployProd
dependsOn: Build
condition: succeeded()
jobs:
- deployment: DeployWeb
environment: 'production'
pool:
vmImage: 'ubuntu-24.04'
strategy:
runOnce:
deploy:
steps:
- task: AzureWebApp@1
inputs:
azureSubscription: 'prod-workload-identity'
appName: 'my-web-app'
condition: succeeded()はdependsOnを指定したときの既定値なので省略できます。明示すると意図が読み取りやすくなるだけです。deploymentジョブは通常のjobと違い、environmentに紐づく。環境(Environments)にはデプロイ履歴が残り、どのコミットがいつ本番へ入ったかを追跡できます。承認を挟むには、Azure DevOpsの「Environments」画面で対象環境を開き、Approvals and checksに承認者を登録します。YAML側の記述は変えません。承認は環境側の設定として効きます。
承認待ち中の並列ジョブ消費
段階デプロイをためらう理由として「承認待ちの間もビルド枠を占有するのでは」という懸念が挙がりますが、これは起きません。公式仕様として、承認待ちや手動介入待ちの状態にある実行は並列ジョブを消費しない。並列ジョブが消費されるのは、エージェント上で実際にジョブが動いている間だけです。無料枠(並列1)のままでも、本番デプロイに承認ゲートを置いたうえで、その間に別ブランチのCIを走らせられます。
認証とシークレットの扱い
「セキュアdevopsパイプライン」で流入があるとおり、権限設計は使い方とセットで問われます。Azure Pipelinesで守る対象は、Azureリソースへの認証情報と、アプリ側の機密値の2つに分かれます。
サービス接続のシークレットレス化と2027年の期限
Azureへデプロイするには、Azure Resource Manager(ARM)サービス接続が必要です。従来はサービスプリンシパルのクライアントシークレットを登録する方式でしたが、現在推奨されるのはワークロード ID フェデレーションです。Azure DevOpsとAzureの間の認証に永続的なシークレットを使わず、パイプラインジョブが実行中に短命なトークンを受け取る。保存されたシークレットが存在しないため、タスクからの流出も、期限切れによる突然のデプロイ失敗も起きません。
新規作成では、サービス接続の作成画面で「App registration (automatic)」を選び、資格情報として「Workload identity federation」を指定します。既存のシークレット方式の接続は、接続の詳細画面にある「変換」から移行できますが、変換ツールには条件があります。Azure DevOpsが自動作成した接続であること(手動作成した接続は変換できない)、単一プロジェクトのみが使用していること(複数プロジェクトで共有している接続は不可)の2点です。変換後のリバートは7日以内に限られます。
もう一つ、期限が最も近い運用事実があります。ワークロード ID フェデレーションのサービス接続で使われているAzure DevOps issuerは、2027年7月1日に廃止される予定です。既存のワークロード ID フェデレーション接続も、Microsoft Entra issuerへ変換する必要があります。「シークレットレスにしたから当面は安泰」ではなく、issuerの移行が別タスクとして残る点を運用計画に入れてください。
機密値の置き場所とログ露出の境界
アプリ側の機密値(APIキー、接続文字列など)は、YAMLに直書きせずパイプライン変数か変数グループに置きます。変数はUI上で「Keep this value secret」を指定するとログにマスクされ、後から画面でも読めなくなる。共有したい値はライブラリの変数グループにまとめ、Azure Key Vaultとリンクすれば、値の実体はKey Vaultに残したままパイプラインから参照できます。
注意すべきは、シークレット変数が自動では環境変数に展開されない点です。スクリプトから使うならenv:で明示的に渡す必要があります。この一手間を省こうとして平文変数へ落とすと、ログに値が出ます。
steps:
- script: ./deploy.sh
env:
API_KEY: $(apiKey)
displayName: 'デプロイ(シークレットを明示的に渡す)'
パイプライン内でコンテナイメージをビルドしているなら、脆弱性スキャンをステップとして挟む価値があります。どの層で何を検出できるかはCI/CDパイプラインにおけるDocker脆弱性スキャンの重要性とその必要性で扱っています。
Azure Pipelinesを選ぶべきでない場面
Azure Pipelinesは万能ではありません。導入前に切り分けたほうがよい条件があります。
コードがGitHubにあり、デプロイ先もAzure以外(AWS、GCP、あるいはVercelのようなPaaS)で完結するなら、GitHub Actionsのほうが構成は短くなります。Azure Pipelinesを使うとリポジトリはGitHub、実行基盤はAzure DevOpsという二重管理になり、権限も両方で設計することになる。Actionsはリポジトリと同じ画面・同じ権限で完結します。リポジトリ基盤ごとCI/CDを選び直す段階なら、GitHubとGitLabのCI機能・セキュリティ機能の差はGitHubとGitLabの違いを比較|CI/CD・セキュリティで選ぶ判断基準に判断軸を整理しています。
逆にAzure Pipelinesが優位なのは、Azure Repos・Azure Boardsを含めてAzure DevOps上で作業項目からデプロイまで追跡する運用と、Azureリソースへの権限をワークロード ID フェデレーションで一体管理したい場合です。複数リポジトリの成果物を集約する構成もAzure Artifactsと組み合わせやすくなります。デプロイ先がAzure側の静的ホスティングなら、Azure Static Web Appsとは何か?その概要と基本情報で扱うサービスが選択肢に入ります。
もう一つ、無料枠だけで長時間のE2Eテストを回そうとする設計は破綻します。無料レベルは1ジョブ60分・月1,800分。ブラウザテストを含むパイプラインは1回で30分を超えることがあり、月に数十回のプッシュで枠を使い切ります。有料の並列ジョブを買うか、セルフホステッドエージェント(実行時間の上限なし)を1台立てるかを、導入時点で決めておくべきです。実行時間や失敗率の傾向を継続的に見るなら、CI Visibilityとは何か? 仕組みとメリットから見るCI/CDパイプライン可視化の基本概念で扱う計測の考え方が使えます。
よくある質問
Azure Pipelinesは無料で使えますか。
プライベートプロジェクトなら、Microsoftホステッドで並列1・1回60分・月1,800分まで無料です。ただし自動では付与されません。組織にAzureサブスクリプションをリンクして課金を設定すると適用されます。セルフホステッドの無料枠(並列1・時間制限なし)は自動で付きます。
並列ジョブを1本買えば2本同時に流せますか。
流せません。1本目の購入で外れるのは月1,800分と1ジョブ60分の制限だけで、同時実行数は1のままです。2本同時に実行するには、無料レベルの組織なら2本の購入が必要になります。
クラシックパイプラインとYAMLはどちらを使うべきですか。
新規はYAMLです。Microsoftはクラシックパイプラインの新規作成を禁止するトグルを既定でオンにする方針を、2023年3月以降に作成された組織について公表しています。既存のクラシック定義は動作しますが、レビュー可能な定義とブランチ単位の分岐を得るためにも、YAMLへ寄せる前提で設計するのが妥当です。
Azure PipelinesとGitHub Actionsの違いは何ですか。
実行モデル(YAMLでジョブとステップを書く)は近く、決定的な差は運用の置き場所にあります。Azure PipelinesはAzure DevOps組織の権限・課金の下で動き、Azure Boardsの作業項目やAzure Reposと同じ単位で追跡できる。GitHub Actionsはリポジトリと同じ権限で完結します。リポジトリがGitHubのみでデプロイ先もAzure以外なら、Actionsのほうが管理対象は減ります。
YAMLを修正したのにパイプラインが動きません。
まずtriggerの対象ブランチを確認してください。既定ではリポジトリの全ブランチが対象ですが、triggerを明示した時点で、そこに書いたブランチ以外は自動実行されなくなります。プルリクエストでの実行はprで別に定義します。次に並列ジョブの空きを確認します。実行が「キューに登録」のまま進まないなら、構文ではなく無料枠の未有効化か並列ジョブの枯渇が原因です。