掲載内容は個人の見解であり、所属する企業を代表するものではありません.
タイトルのような質問を後輩ちゃんからいただいたので、試してみたところ出来たんですが、ドキュメント読んでもこのパターンはちょっと実装方法がわかりにくいなと思ったのでここに記します。 想定としては Hub VNET 側に開発端末としての Dev Box や作業用の端末などが接続されていて、ADE : Azure Deployment Environment を使用してSpoke VNET 側に Azure サービスをデプロイしてアプリを開発したいけど、Public Network 経由は嫌なので閉域アクセスしたい、というようなケースになると思います。 つまり、Hub VNET は既にデプロイ済みのものとして、Spoke VNET と Peering の設定だけを ADE でデプロイしたり削除したりしたい、ということですね。
なお、この記事では [Azure Deployment Environment]そのものについて詳しい解説は省きます。 ADE 初心者の方は クイックスタート 等に従って、自作のテンプレートをカタログとして登録、ADE でデプロイする一連の環境を作成してみてください。 また ADE 自体はざっくりいえば Azure の IaC 技術を使用して、カタログ管理された環境をデプロイしてくれるサービスです。 つまり Azure Resource Manager や Bicep 言語の知識が必要です。 さらに、ADE は開発者に代わって Azure リソースのデプロイを代行してくれるサービスですので、 実際の操作を行ってくれる サービスアカウント の知識、 Azure でのアクセス制御の仕組みである Azure RBAC の知識も重要です。
まずは VNET Peering を構成する ARM テンプレートないしは Bicep テンプレートが必要です。 参考情報を探していたところ、以下の素敵な記事が見つかりました。
こちらの記事を参考にすると VNET Peering するには 4 つのリソース、すなわち VNET が2つ、片方の VNET を親として、もう片方を参照する VNET Peering が2つ必要なことが分かります。
ここで Hub VNET が既に存在している前提で、かつ、ADE で Spoke VNET と Peering だけをデプロイしたいわけなので、以下のようなリソースグループ編成になります。
hub-spoke-rg
とします)
hub-vnet
)hub-vnet
を親として spoke-xx-vnet
を参照する VNET Peeringspoke-xx-vnet
)spoke-xx-vnet
を親として hub-vnet
を参照する VNET Peeringつまり ADE で作成したいのは下図の赤字部分が該当します。
ここで気を付けたいのは ADE でデプロイするときは ADE が作成する環境である 右側のリソースグループをスコープとしたデプロイ になるということです。 つまり既存のハブ側のリソースグループへの VNET Peering のデプロイを行うためには Bicep ファイルを分離し、 モジュールとして別スコープのデプロイ をしてあげる必要があります。 というわけで実際の Bicep テンプレートの例は以下のようになります。
さて ADE がデプロイするとき、基本的には以下の操作が行われています。
environment.yaml
で指定されたテンプレートを使用してデプロイするこのとき 4 番目の手順の過程ででハブ側のリソースグループに対してモジュールのデプロイが行われるわけですが、サービスプリンシパルはそちらのリソースグループに対してロールを割り当てられていないので何も出来ません。 つまり事前にサービスプリンシパルに対して必要な操作を含んだ RBAC ロールを割り当てておく必要があるわけですね。 上記の通りサービスプリンシパルの名前さえ分かっていれば通常の RBAC ロール割り当てですので、ハブ側のリソースグループに対して共同作成者でも与えておきましょう。 (ちゃんとやるならスコープとロールはもっと絞り込むべきです)
これでサービスプリンシパルはスコープ側だけでなくハブ側にもいろいろ出来るようになります。
上記は自動的に作成されるサービスプリンシパルに対してのロールを割り当てていますが、ユーザー割り当て Managed ID を使用してデプロイさせることも可能です。 複数の環境でのデプロイに使用したいとかいう場合にはこちらの方が便利かもしれません。 明示的にリソースが見えるのでわかりやすいというメリットもありますね。
それでは準備が整いましたので、マニフェストファイル( environment.yaml
)を作成してデプロイしてみましょう。
実際のサンプルはこちらをご参照ください。
出来上がったものがこちらです。 VNET と Peering しか作ってませんが、オールグリーンなのできっと大丈夫でしょう。
ここで以下の点に留意してください。
単に ADE でスポーク VNET を生やしたいだけなので Bicep テンプレートはシンプルですが、割と ADE の仕組みに踏み込むことになってしまいました。 ただこの挙動を抑えておくことで、各開発者の専用の環境を簡単にデプロイできるだけでなく、環境全体で共有するインフラ部分に対する各種の設定変更をセットで行うことが出来るような気がします。 実際に試してはいませんが、以下のようなユースケースが思いつきます。
ニッチなケースかもしれませんが、このような使い方もあるんだなということを知っていただければ幸いです。
ここでは知らなくても問題ではないけどちょっと Azure に詳しくなれそうな情報をいくつか紹介します。
Azure Portal から VNET Peering の設定をポチポチやると VNET Peering 自体は単なる設定情報にしか見えないですが、上記の通り VNET Peering 自体も ARM リソースです。 つまり以下のコマンドで確認することが可能です。
SUBSC=guid-of-your-subscription-id
RG=hub-spoke-rg
VNET=hub-vnet
PEERING=peering1
az resource show --ids /subscriptions/${SUBSC}/resourceGroups/${RG}/providers/Microsoft.Network/virtualNetworks/${VNET}/virtualNetworkPeerings/${PEERING}
{
"id": "/subscriptions/guid/resourceGroups/hub-spoke-rg/providers/Microsoft.Network/virtualNetworks/hub-vnet/virtualNetworkPeerings/peering1",
"resourceGroup": "hub-spoke-rg",
"type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings",
"name": "peering1",
"properties": {
"allowForwardedTraffic": true,
"allowGatewayTransit": false,
"allowVirtualNetworkAccess": true,
"doNotVerifyRemoteGateways": false,
"peerCompleteVnets": true,
"peeringState": "Connected",
"peeringSyncLevel": "FullyInSync",
"provisioningState": "Succeeded",
"remoteAddressSpace": {
"addressPrefixes": [
"10.1.0.0/16"
]
},
"remoteVirtualNetwork": {
"id": "/subscriptions/guid/resourceGroups/projectName-environmentName/providers/Microsoft.Network/virtualNetworks/spoke-vnet",
"resourceGroup": "projectName-environmentName"
},
"remoteVirtualNetworkAddressSpace": {
"addressPrefixes": [
"10.1.0.0/16"
]
},
"useRemoteGateways": false
}
}
ドキュメントにはあまり詳しく書かれていないのですが、 ADE によるデプロイ中は前述のとおり各プロジェクトの環境名がついたサービスプリンシパルに対するアクセス権の付与と剥奪が動的に行われます。
これによって開発者自身がサブスクリプションに対してアクセス権を持つことなく、様々なリソースのデプロイが可能になっているわけです。
この挙動はデプロイ中には アクセス制御 (IAM)
の画面で、デプロイ後は アクティビティログ
でも確認できます。
さてサービスプリンシパルと書いてますが、プロジェクトで環境を構成する際の画面からもわかるとおり、これはシステム割り当て Managed ID です。
これは Entra ID の管理画面 エンタープライズ アプリケーション
で確認することが出来ます。
フィルターとして アプリケーションの種類 == マネージド ID
とすると見つけやすいです。
システム割り当てマネージド ID があるということは、このプロジェクトに割り当てた環境も
ARM リソース であるということも予想が付きますね。
以下のようなスクリプトを使う環境の種類の設定情報が確認でき、Entra ID の画面で確認したオブジェクト ID と一致するシステム割当マネージド ID が確認できます。
また、この環境が対象とするサブスクリプション(deploymentTargetId
) や、ADE を利用してデプロイするユーザーに割り当てられるロール(ここでは閲覧者)も確認できます。
SUBSC=guid
RG=devenv-rg
PROJ=demo-proj
ENV=Dev
az resource show --ids /subscriptions/${SUBSC}/resourceGroups/${RG}/providers/Microsoft.DevCenter/projects/${PROJ}/environmentTypes/${ENV}
{
"id": "/subscriptions/guid/resourceGroups/rg/providers/Microsoft.DevCenter/projects/proj/environmentTypes/env",
"type": "microsoft.devcenter/projects/environmenttypes",
"identity": {
"principalId": "38445c3e-843a-41fc-87fa-96fdf5c0ccf7",
"tenantId": "xxxxxxxx-xxxx-xxxx-xxxxxxxxx",
"type": "SystemAssigned",
"userAssignedIdentities": null
},
"properties": {
"creatorRoleAssignment": {
"roles": {
"acdd72a7-3385-48ef-bd42-f606fba81ae7": {}
}
},
"deploymentTargetId": "/subscriptions/guid",
"environmentCount": 1,
"provisioningState": "Succeeded",
"status": "Enabled"
}
}