はじめに
本ドキュメントは、AzureとAzure DevOpsを利用したインフラの自動化(CI/CD)の全体像をまとめたものです。
1. 全体構成図
AzureとAzure DevOpsを連携した場合のCI/CDパイプラインの構成図です。
2. Azure DevOpsと連携のための構成要素
構成図に登場する各コンポーネントの役割と、図の中での位置付けを解説します。
2-1. Azure DevOps 領域(図の左側)
ソフトウェア開発チームに統合ツールを提供するクラウドベースのプラットフォームです。
これには、作業の計画、コードでの共同作業、アプリケーションのビルド、機能のテスト、運用環境へのデプロイに必要なものがすべて含まれます。
2-1-1. Azure Pipelines(CI/CD Pipeline)
-
役割
- Microsoftが提供するAzure DevOpsに含まれるCI/CD(継続的インテグレーション・継続的デリバリー)機能です。
- コードの検証(ビルド)、テスト、リソースのデプロイを自動化します。
- マネージドサービスのため、スケーリングやセキュリティ等のメンテナンスは不要です。セットアップなしですぐ利用可能です。
-
図での位置付け
- ソースコードをチェックする CI Pipeline と、実際にAzureへデプロイを命令する CD Pipeline に分かれています。
2-1-2. Service Connections(サービス接続)
-
役割
- Azure Pipelinesと、ジョブでタスクを実行するために使用する外部サービスまたはリモートサービス間の認証された接続です。
- 認証タイプはワークロードIDフェデレーションまたはシークレットを使った方法があります。(ワークロードIDフェデレーションが現在の推奨設定です。)
-
図での位置付け
- CD Pipelineの上部にあり、青色の線でAzure側の Service Principal へと接続されています。
引用:サービス接続の管理
:Azure Resource Manager サービス接続を使用して Azure に接続する
2-2. Azure 認証・管理領域(図の中央・右側)
2-2-1. Service Principal (サービスプリンシパル)
-
役割
- Azure DevOpsがAzureのリソース (Azure Resource Manager) を操作する際に使う 「システムアカウント」 です。
-
図での位置付け
- 図の中央にあり、ここからサブスクリプションやリソースグループに対して、インフラ構築に必要な操作権限(RBAC)が与えられていることを示しています。
2-3. Azure ネットワーク領域(図の中央・VNet枠内)
2-3-1. デベロッパーセンター(Developer Center)& プロジェクト(Project)
-
役割
- 組織内の開発環境やリソースを一括管理する機能です。
- プロジェクトを作成することで、開発チームごとにリソースを整理・管理できるようになります。
- ※Managed DevOps Pools (MDP)を使う場合はデベロッパーセンターとプロジェクトが必須です。
-
図での位置付け
- 図の右側の枠内です。これらは管理用の仕組みであるため、VNetの外側に配置されています。
- 本構成では、パイプラインの実行環境である Managed DevOps Pools (MDP) をこのプロジェクトの配下で管理しています。
2-3-2. Managed DevOps Pools (MDP)
-
役割
- パイプラインの命令を受けて、実際にBicepコードを実行するマシンのプール(エージェント)です。
-
図での位置付け
- 赤色の点線枠内です。
-
ネットワーク上の特徴
- お客様自身が管理する VNetの内部(MDP subnet)に直接配置 しています。
- これにより、インターネットを一切経由せず、同じVNet内の閉域網に対して安全にアクセスできます。
- サブネットの指定をせずにAzure管理ネットワーク内に作成することも可能ですが、その場合は閉域網への直接操作は不可になります。
- マシン自体はマネージドサービスのため、運用管理の必要はありません。
3. 実行環境について
Azure DevOpsの実行環境には4つの手法がありますが、本構成では Managed DevOps Pools (MDP) を選定しています。
-
Microsoft-hosted
- Microsoft側で用意される実行環境です。
- すぐ利用できる利点はありますが、閉域網の内部リソースにアクセスできません。
- デフォルトで用意されている環境です。
-
Self-hosted
- VNetの中にVirtual Machine (VM) を置くことで閉域網に対する操作は可能ですが、OSのパッチ当てやマシンの管理のメンテナンスをし続ける必要があり、運用負荷が高いです。
-
Azure virtual machine scale set (VMSS)
- 必要に応じて自動的にスケールアップできるセルフホステッドエージェントです。
- スケーリングは自動化されますが、ベースとなるインフラ環境はお客様自身で管理する必要があります。
-
Managed DevOps Pools (MDP)
- Microsoft-hostedとSelf-hostedの両方のいいとこ取りをした最新機能です。
- MicrosoftがOSのパッチ当てやマシンの管理のメンテナンスを実施しますが、実行環境はお客様自身が保有するVNetの中に配置できるため、運用負荷を抑えながら閉域網へのデプロイが可能になります。
4. パイプラインの起動トリガーとリポジトリ
パイプラインの流れと参照リポジトリについて記載します。
4-1. 参照先となるGitリポジトリ
コードの保存場所となるGitリポジトリは、主に以下の3つから選択できます。
Azureとの親和性という観点では、Azure Repos Gitが最も高いです。
| リポジトリ | 概要 |
|---|---|
| Azure Repos Git | Azure DevOpsに内包されているプライベートGitリポジトリです。 Azure DevOps内のプロジェクトやチームと統合されたアクセス制御 (RBAC) を利用できます。 |
| GitHub(外部連携) | GitHub上のリポジトリと連携できます。 Azure Boards等の機能と統合でき、GitHub Appを通じてパイプラインのトリガー設定などを構成できます。 |
| Bitbucket Cloud(外部連携) | Atlassian社が提供するBitbucket Cloudリポジトリと連携できます。 |
引用・詳細:Azure Pipelines でサポートされるリポジトリ (Microsoft Learn)
:GitHub リポジトリをビルドする
:Azure Boards-GitHub統合とは
4-2. 起動トリガーの仕組み
パイプラインは手動で実行することも可能ですが、一般的には コードの変更 (PushやMerge) を検知して 自動実行 (CI/CD) させます。
-
CIトリガー(継続的インテグレーション):
mainブランチなどにコードがpushされた瞬間に、自動的に構文チェックやテストが走る仕組みです。 - PRトリガー(プルリクエスト): ブランチをマージする前の プルリクエスト (PR) が作成された時点で、その変更内容が安全かどうかを事前に検証するためにパイプラインを走らせます。
引用・詳細:パイプラインをトリガーするイベントの指定
4-3. CI/CDパイプラインの処理フロー
トリガーから自動デプロイまでのフローを記載します。
-
① YAMLをPush
- ユーザーがPCから、インフラを定義した「Bicepファイル」と、パイプラインの動きを定義した「
azure-pipelines.yml」をAzure Reposにpushします。
- ユーザーがPCから、インフラを定義した「Bicepファイル」と、パイプラインの動きを定義した「
-
② トリガー起動
- 「
azure-pipelines.yml」で定義した特定のブランチ(main等)への変更を検知し、CI/CD Pipelineが自動で起動します。
- 「
-
③ ビルド検証
- CI PipelineがVNet内にいる MDP (エージェント) に対してコードの構文チェックなどの検証を行うよう指示します。
-
④ デプロイ指示
- CD Pipelineが、VNet内にいる MDP (エージェント) に対してBicepコードからリソースを作成するよう指示を出します。
-
⑤ 権限の利用
- MDPは、あらかじめService Connection 経由で紐づいている Service Principal の権限 を使って、Azure環境(サブスクリプションまたはリソースグループ)へのアクセスが許可されます。
-
⑥ デプロイ完了
- MDPが
resource subnetにリソース作成・更新 (デプロイ) を完了します。(※図ではVirtual MachineとDBを作成する流れを示しています。)
- MDPが
4-4. 承認設定
本番環境など、重要な環境へデプロイする前に上長の承認を挟みたい場合は、Azure DevOpsのEnvironments機能を利用します。
パイプライン内にEnvironmentを指定し、そこに承認とチェックを設定することで、特定のユーザーが承認ボタンを押すまでデプロイ処理(上記手順の④)を一時停止させることが可能です。
実践編
実際にAzure DevOpsとAzureを連携した開発環境の構築方法を記載します。
【実践1】Azure DevOpsの初期セットアップ
Azure環境を構築する前に、「Azure DevOps」の環境(組織とプロジェクト)を用意します。
※すでに環境がある方はスキップして構いません。
1. 組織(Organization)の作成
- Azureポータルから、Azure DevOpsを検索して、 [View my organizations] をクリックします。
- [Create new organization] をクリックします。
- 利用規約に同意して、[Continue] を押下します。
-
[New organization] をクリックし、任意の組織名とロケーション(例:
Asia Pacific等)を選択して組織を作成します。
2. プロジェクト(Project)の作成
組織の作成ができたら、プロジェクト を作成します。
- 組織の画面右上にある [New project] をクリックします。
- 以下の情報を入力します。
- Project name: 任意のプロジェクト名
- Description: プロジェクトの説明
-
Visibility:
Private(非公開)またはPublic(公開)を選択(※通常は社内利用のためPrivateを選択します) -
Advanced:
- Version control:
Git - Work item process:
Basic(今回はインフラ自動化がメインのためデフォルトで構いません)
- Version control:
- [Create] をクリックするとプロジェクトが作成され、ダッシュボード画面が表示されます。
3. リポジトリ(Repos)の初期化
本記事では、Bicepコードやパイプラインの定義ファイル(YAML)を保存するために Azure Repos Git を使用します。
- 左側のメニューから [Repos] をクリックします。
- 初期状態ではリポジトリが空のため、画面下部にある [Initialize] ボタンをクリックして、デフォルトの
mainブランチとREADME.mdを作成します。
【実践2】azコマンドによるインフラ環境の事前準備
Azure DevOpsのパイプライン(MDP)を利用してリソースを自動構築するための環境設定方法を記載します。
ここでは、公式サイトの「クイック スタート: Azure CLI を使用してマネージド DevOps プールを作成する」を参考に、Azure CLI(az コマンド)を使った手順を記載します。
※Git Bashで実行する場合は、パスを正しく読み取れるように export MSYS_NO_PATHCONV=1 を最初に実行してください。
参考: クイック スタート: Azure CLI を使用してマネージド DevOps プールを作成する
1. Azureへのログインとサブスクリプション指定
まずはAzureに接続し、操作するサブスクリプションを指定します。
# Azureへログイン(ブラウザが立ち上がります)
az login
# Azureにログイン後、以下が表示されるため、作業するテナントとサブスクリプションを選択します
A web browser has been opened at https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize. Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with `az login --use-device-code`.
Retrieving tenants and subscriptions for the selection...
[Tenant and subscription selection]
No Subscription name Subscription ID Tenant
----- ------------------- ------------------------------------ -------------
[1] * test-subscription xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx contoso.com
The default is marked with an *; the default tenant is 'contoso.com' and subscription is 'test-subscription' (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
Select a subscription and tenant (Type a number or Enter for no changes): #<==ここでサブスクリプションを選択します
# サブスクリプションとテナントを選択後、以下が表示されます
Tenant: contoso.com
Subscription: test-subscription (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
[Announcements]
With the new Azure CLI login experience, you can select the subscription you want to use more easily. Learn more about it and its configuration at https://go.microsoft.com/fwlink/?linkid=2271236
If you encounter any problem, please open an issue at https://aka.ms/azclibug
[Warning] The login output has been updated. Please be aware that it no longer displays the full list of available subscriptions by default.
作業サブスクリプションを誤った場合は、以下を実施して切り替えます。
# 利用可能なサブスクリプション一覧を確認
az account list --output table
Name CloudName SubscriptionId TenantId State IsDefault
------------------- ----------- ------------------------------------ ------------------------------------ ------- -----------
test-subscription AzureCloud xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy Enabled True
# 操作対象のサブスクリプションIDを指定(ここではサブスクリプションIDをxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxとしています)
az account set --subscription xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
2. リソースグループ作成
構築する環境およびMDPエージェントを動かすためのリソースグループを作成します。
az group create --name <任意のリソースグループ名> --location "japaneast"
3. ネットワークの設定
MDPエージェント用のネットワーク環境を構築します。
# VNet(仮想ネットワーク)の作成
az network vnet create --resource-group <作成したリソースグループ名> --name <任意のVnet名> --address-prefix <任意のVnetプレフィックス(CIDR)>
# MDP配置用のサブネットを作成
# ※MDPをVNet内に配置するには、専用の委任(Delegation)設定が必要です
az network vnet subnet create --resource-group <作成したリソースグループ名> --vnet-name <作成したVnet名> --name <任意のSubnet名> --address-prefixes <任意のSubnetプレフィックス(CIDR)> --delegations "Microsoft.DevOpsInfrastructure/pools"
4. サービスプリンシパルの作成
Azure DevOpsとAzureを連携するためのサービスプリンシパルを作成します。
az ad sp create-for-rbac --name <任意のサービスプリンシパル名>
※ 出力される appId、password、tenant は、後でAzure DevOpsのService Connections を設定する際に必要となるためメモしておいてください。(一度しか表示されません。)
5. サービスプリンシパルロール割り当て
サービスプリンシパルがリソースを操作できるようにするためにリソースグループに権限を割り当てる必要があります。
ロールは一例のため、作成するリソースに応じて変更してください。
- スコープ: 作成したリソースグループ
-
ロール
- 共同作成者 (Contributor): リソース操作用
- Role Based Access Control Administrator: ロール割り当て用(必要なものだけ許可が推奨)
- キー コンテナー シークレット責任者 (Key Vault Secrets Officer): KeyVault操作用
- メンバー: 4で作成したサービスプリンシパル
参考: Azure portal を使用して Azure ロールを割り当てる
6. デベロッパーセンターとプロジェクトの作成
Managed DevOps Pools (MDP)を作成するために、デベロッパーセンターおよびプロジェクトを作成します。
# デベロッパーセンター拡張機能の追加(初回のみ)
az extension add --name devcenter
# デベロッパーセンターの作成
az devcenter admin devcenter create --resource-group <作成したリソースグループ名> --name <任意のデベロッパーセンター名> --location "japaneast"
# プロジェクトの作成(作成したデベロッパーセンターに紐づけ)
az devcenter admin project create --resource-group <作成したリソースグループ名> --name <任意のプロジェクト名> --dev-center-id "<デベロッパーセンターID>"
7. MDPエージェント用サブネットロール割り当て
MDPエージェント用のサブネットには、DevOpsInfrastructureという既存のサービスプリンシパルに対して、Network Contributor(ネットワーク共同作成者) を割り当てる必要があります。
ロールが割り当てられていない場合、権限不足によりMDPの作成に失敗します。
設定方法は以下を確認してください。
参考: DevOpsInfrastructure サービス プリンシパルへの閲覧者とネットワーク共同作成者のアクセス権を付与する
8. Managed DevOps Pools (MDP) の作成
以下のAzure DevOpsの情報が必要です。
- DevOpsのURL:https://dev.azure.com/`Azure DevOpsのOrganization名`
- DevOpsのプロジェクト名:
Azure DevOpsのOrganizationで作成したプロジェクト名
VMSSやimageは環境に合わせて変更してください。
subnetId はサブネットのリソース名ではなくリソースID(/subscriptions/... から始まる文字列)を指定します。
az mdp pool create \
--resource-group <作成したリソースグループ名> \
--name <任意のMDP名> \
--location "japaneast" \
--maximum-concurrency 1 \
--devcenter-project-resource-id "<デベロッパーセンタープロジェクトID>" \
--organization-profile "azure-dev-ops={organizations:[{url:'<DevOpsのURL>',projects:['<DevOpsのプロジェクト名>']}]}" \
--agent-profile "Stateless={}" \
--fabric-profile "vmss={sku:{name:Standard_D2ads_v5},images:[{wellKnownImageName:ubuntu-24.04/latest}],networkProfile:{subnetId:'<作成したサブネットのリソースID>'}}"
【実践3】Azure DevOpsとAzureの連携
Azure側の準備が完了したら、Azure DevOpsと紐づけてパイプライン(MDPエージェント)を動かします。
1. Service Connections(サービス接続)の作成
実践2の「4.」で発行したサービスプリンシパルの情報を使って、Azure DevOpsからAzureを操作するための接続設定を行います。
※今回はシークレットを使用した方法で検証したため、シークレットでの連携方法を記載していますが、現在はワークロードIDフェデレーションが推奨されています。
- Azure DevOpsの対象プロジェクトを開きます。
- 画面左下の歯車アイコン [Project settings] > [Pipelines] > [Service connections] をクリックします。
- 右上の [New service connection] を押下し、[Azure Resource Manager] を選択して、[Next] を押下します。
- 以下入力・選択して、[Verify and save] を押下します。
-
Identity Type:
App registration or managed identity(manual) -
Credential:
secret -
Environment:
Azure Cloud -
Scope level:
Subscription -
Subscription id:
<サブスクリプションID> -
Subscription name:
<サブスクリプション名> -
Application (client) ID:
<サービスプリンシパルのID> -
Directory (tenant) ID:
<テナントID> -
Credential:
<実践2で作成したサービスプリンシパルのパスワード>※Verifyで有効になれば問題ありません -
Service Connection Name:
<サービスプリンシパル名> -
Description (optional):
<Service Connection 説明> -
Security:
Grant access permission to all pipelinesチェックオン
-
Identity Type:
2. Managed DevOps Pools (MDP) の登録確認
実践2の「8.」で作成したMDPが、Azure DevOps側でエージェントプールとして認識されているか確認します。
- [Project settings] > [Pipelines] > [Agent pools] を開きます。
- Azure CLIで指定した
<任意のMDP名>が一覧に表示されていれば連携できています。
3. パイプライン(YAML)の作成と実行テスト
実際にパイプラインを作成して、実行テストを行います。
- Azure DevOpsの左メニューから [Pipelines] > [Pipelines] > [New pipeline] をクリックします。
- Connect画面で、[Azure Repos Git] を選択し、対象のリポジトリを選択します。
- Configure画面で [Starter pipeline] を選択します。
- Review画面で以下のYAMLコードに書き換えて、[Save and Run] を押下します。
trigger:
- main
# 作成したMDPのエージェントプールを指定
pool:
name: <作成したMDP名>
steps:
- task: AzureCLI@2
displayName: 'Azureへの接続テスト'
inputs:
azureSubscription: '<作成したService connection名>'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
echo "MDPエージェント(VNet内)からの実行に成功しました!"
az account show --output table
おわりに
Azure DevOpsとAzureを連携し、インフラ自動化環境を構築する方法を紹介しました。
Managed DevOps Pools(MDP)の登場によって、セキュリティと運用効率を両立したデプロイ環境が構築できるようになりました。
エージェントマシンの運用負荷を低減し、お客様自身のAzure環境にマシンを配置できる点、Entra IDをベースにAzureとAzure DevOpsのユーザーとロールを一元管理できる点等から、Azure環境を使用する場合は、Azure DevOpsの方がGitHubよりもセキュリティや運用面で勝ります。
また、紹介しきれなかったところですが、Azure Boards(タスク管理)との連携で開発プロセスの可視化も可能です。
