🚧

プライベート リンク経由でAzure CLIより操作

2023/09/26に公開

外部通信要件が厳しい環境で合ったりする場合でも何とかAzure CLI/Azure PowerShellを使いたいという要望があり、以下の内容を手元で確認を行ったため自分宛てにメモとして残しておく。

API を使用して Azure リソースを管理するためのプライベート リンクを作成する

はじめにAzure ポータルの操作を含め、Azure APIを用いた操作はすべてAzure Resource Manager (以降、ARM)を通して行われる。

Azure Resource Manager
出典元; Azure Resource Manager とは

これまではクライアントから ARM のエンドポイントまではインターネット経由であったが、
これをプライベートエンドポイント経由 (プライベート IP アドレスによる通信) にできるという話。

なお、既に先人の方が築いた資産が大分参考になったのでここにご紹介。

https://zenn.dev/tomot/articles/342ddb164aa459

前準備

必要なアクセス許可にあるように、ルート管理グループに対して所有者または共同管理者権限を持つ必要がある。

そのためには、操作ユーザーを昇格させ、ロールの割り当てを行う必要がある。

Azure のすべてのサブスクリプションと管理グループを管理する目的でアクセス権限を昇格させる

Alt text

その後、ロールの割り当てを行う。

az role assignment create --assignee "<ユーザー プリンシパル名" --role Owner --scope "/providers/Microsoft.Management/managementGroups/<Azure AD テナントID>"

設定

今回は予め labrmpl という名前のリソースグループを作成しており、そちらを使用する。

プライベート リンクの作成

$ az resourcemanagement private-link create -g labrmpl -n labrmpl -l japaneast
{
  "id": "/subscriptions/<サブスクリプション ID>/resourceGroups/labrmpl/providers/Microsoft.Authorization/resourceManagementPrivateLinks/labrmpl",
  "location": "japaneast",
  "name": "labrmpl",
  "properties": {
    "privateEndpointConnections": []
  },
  "resourceGroup": "labrmpl",
  "type": "Microsoft.Authorization/resourceManagementPrivateLinks"
}

プライベート リンク関連付けの作成

名前はGUIDの形式を取るため、予め uuidgen コマンドなどで生成しておく。また、--public-network-access 現時点では enabled しか指定できない (恐らく disabled が指定できればパブリックアクセスが制限できる想定だが、デットロックを招きそう...)

$ az private-link association create --management-group-id <Azure ADテナント ID> --name <用意したGUID> --privatelink /subscriptions/<サブスクリプション ID>/resourceGroups/labrmpl/providers/Microsoft.Authorization/resourceManagementPrivateLinks/labrmpl --public-network-access enabled
{
  "id": "/providers/Microsoft.Management/managementGroups/<Azure ADテナント ID>/providers/Microsoft.Authorization/privateLinkAssociations/<用意したGUID>",
  "name": "<用意したGUID>",
  "properties": {
    "privateLink": "/subscriptions/<サブスクリプション ID>/resourceGroups/labrmpl/providers/Microsoft.Authorization/resourceManagementPrivateLinks/labrmpl",
    "publicNetworkAccess": "Enabled",
    "scope": "/providers/Microsoft.Management/managementGroups/<Azure ADテナント ID>",
    "tenantId": "<Azure ADテナント ID>"
  },
  "type": "Microsoft.Authorization/privateLinkAssociations"
}

プライベート エンドポイントを作成するため、仮想ネットワークを作成する。

$ az network vnet create -g labrmpl -l japaneast -n clivnet --address-prefixes 10.0.0.0/16 --subnet-name default --subnet-prefixes 10.0.0.0/24

プライベート エンドポイントを作成
10.0.0.4 が割り当てられていることを確認

$ id=$(az resourcemanagement private-link show -g labrmpl -n labrmpl --query 'id' -o tsv)
$ az network private-endpoint create --connection-name rmplconnect -n rmplpe --private-connection-resource-id $id -g labrmpl --subnet default --group-id ResourceManagement --vnet-name clivnet

...(省略)...

  "customDnsConfigs": [
    {
      "fqdn": "management.azure.com",
      "ipAddresses": [
        "10.0.0.4"
      ]
    },
    {
      "fqdn": "edge.management.azure.com",
      "ipAddresses": [
        "10.0.0.4"
      ]
    }
  ],

...(省略)...

プライベート DNS ゾーンを作成

$ az network private-dns zone create -g labrmpl -n "privatelink.azure.com"
$ az network private-dns link vnet create -g labrmpl -z "privatelink.azure.com" -n dns-link -v clivnet -e false
$ az network private-endpoint dns-zone-group create -g labrmpl --endpoint-name rmplpe -n zone-group --private-dns-zone "privatelink.azure.com" --zone-name rmpl

...(省略)...
      "recordSets": [
        {
          "fqdn": "management.privatelink.azure.com",
          "ipAddresses": [
            "10.0.0.4"
          ],
          "provisioningState": "Succeeded",
          "recordSetName": "management",
          "recordType": "A",
          "ttl": 10
        },
        {
          "fqdn": "edge.management.privatelink.azure.com",
          "ipAddresses": [
            "10.0.0.4"
          ],
          "provisioningState": "Succeeded",
          "recordSetName": "edge.management",
          "recordType": "A",
          "ttl": 10
        }
      ]
    }
  ],

...(省略)...

確認

ここからは確認のため、仮想マシンをデプロイし動作を見てみる。

$ az vm create -g labrmpl -n clivm --image Ubuntu2204 --vnet-name clivnet --subnet default --admin-username azureuser --ssh-key-value ~/.ssh/id_rsa.pub
azureuser@clivm:~$ nslookup management.azure.com
Server:         127.0.0.53
Address:        127.0.0.53#53

Non-authoritative answer:
management.azure.com    canonical name = management.privatelink.azure.com.
Name:   management.privatelink.azure.com
Address: 10.0.0.4

Azure CLIをインストールして操作を確認
参考にした記事では、システム マネージド ID で認証を行われているが、通常の対話的なログインも可能。
なお、マネージド ID を使う場合、事前に対象システム マネージド IDに対しロールの付与が必要 (参考)。

適当にストレージ アカウントを作るなど

azureuser@clivm:~$ az storage account create --name sa202309211 --resource-group labrmpl

併せて取ったネットワークパケットキャプチャをみると、
確かにプライベート エンドポイントのIPアドレスに名前解決されて通信が成功していることが分かる。

Alt text

まとめ

  • アウトバウンドを制限している環境でもAzure CLIを利用できそう
    • ただし、AKSやAzure Bastionはサポートしていないので注意
  • 現時点ではパブリックアクセスを無効にできない
GitHubで編集を提案

Discussion