Azure の VNet を増やすとき、Excel のアドレス管理台帳を確認したうえで空いている CIDR を決定している方は多いでしょう。今回は、この運用を Azure Virtual Network Manager の IPAM で実現できるかを試しました。

検証構成と前提

次の構成を作成します。VM、NIC、サブネット、ピアリングは作成しません。

testavnm / japaneast
  avnm-ipam-eval
    pool-root: 10.240.0.0/16
      pool-japaneast: 10.240.0.0/20
        reserved-onprem: 10.240.0.0/24
        vnet-ipam-app01: 256 addresses requested
        vnet-ipam-app02: 256 addresses requested
        vnet-ipam-app03: 16 addresses requested
        vnet-ipam-app04: 128 addresses requested
        vnet-ipam-app05: 32 addresses requested

reserved-onprem は、オンプレミスで使う範囲を想定した静的 CIDR の登録です。実際のオンプレミス環境への接続は行いません。

Network Manager と親子プールの作成

まずは AVNM 自体を作ります。Network Manager のスコープには検証対象サブスクリプションを指定しました。

$scope = New-AzNetworkManagerScope `
    -Subscription @('/subscriptions/<subscription-id>')

New-AzNetworkManager `
    -Name 'avnm-ipam-eval' `
    -ResourceGroupName 'testavnm' `
    -Location 'japaneast' `
    -NetworkManagerScope $scope `
    -NetworkManagerScopeAccess Connectivity

続いて、親プールとして 10.240.0.0/16 を作成します。

New-AzNetworkManagerIpamPool `
    -Name 'pool-root' `
    -NetworkManagerName 'avnm-ipam-eval' `
    -ResourceGroupName 'testavnm' `
    -Location 'japaneast' `
    -AddressPrefix @('10.240.0.0/16')

子プールには、親の一部となる 10.240.0.0/20 を明示的に指定します。

New-AzNetworkManagerIpamPool `
    -Name 'pool-japaneast' `
    -NetworkManagerName 'avnm-ipam-eval' `
    -ResourceGroupName 'testavnm' `
    -Location 'japaneast' `
    -AddressPrefix @('10.240.0.0/20') `
    -ParentPoolName 'pool-root'

静的 CIDR の事前登録

自動割り当てで使わせたくない範囲を想定し、子プール内の 10.240.0.0/24 を静的 CIDR として登録します。

New-AzNetworkManagerIpamPoolStaticCidr `
    -Name 'reserved-onprem' `
    -NetworkManagerName 'avnm-ipam-eval' `
    -ResourceGroupName 'testavnm' `
    -PoolName 'pool-japaneast' `
    -AddressPrefix @('10.240.0.0/24')

CIDR 未指定での VNet の作成

ここからは、VNet の CIDR を直接指定せず、子プールから 256 アドレスを要求します。具体的なアドレス空間を指定してない点がポイントです。

$allocation = [Microsoft.Azure.Commands.Network.Models.PSIpamPoolPrefixAllocation]::new()
$allocation.Id = '/subscriptions/<subscription-id>/resourceGroups/testavnm/providers/Microsoft.Network/networkManagers/avnm-ipam-eval/ipamPools/pool-japaneast'
$allocation.NumberOfIpAddresses = '256'

New-AzVirtualNetwork `
    -Name 'vnet-ipam-app01' `
    -ResourceGroupName 'testavnm' `
    -Location 'japaneast' `
    -IpamPoolPrefixAllocation @($allocation)

Get-AzVirtualNetwork `
    -Name 'vnet-ipam-app01' `
    -ResourceGroupName 'testavnm' |
    ConvertTo-Json -Depth 10

以下のように 10.240.0.0/24 の次の 10.240.1.0/24 が割り当てられています。

{
  "AddressSpace": {
    "AddressPrefixes": [
      "10.240.1.0/24"
    ],
    "IpamPoolPrefixAllocations": [
      {
        "Id": "/subscriptions/<subscription-id>/resourceGroups/testavnm/providers/Microsoft.Network/networkManagers/avnm-ipam-eval/ipamPools/pool-japaneast",
        "NumberOfIpAddresses": "256",
        "AllocatedAddressPrefixes": [
          "10.240.1.0/24"
        ]
      }
    ]
  }
}

2 個目も同じ子プールから同じ数を要求します。

$allocation = [Microsoft.Azure.Commands.Network.Models.PSIpamPoolPrefixAllocation]::new()
$allocation.Id = '/subscriptions/<subscription-id>/resourceGroups/testavnm/providers/Microsoft.Network/networkManagers/avnm-ipam-eval/ipamPools/pool-japaneast'
$allocation.NumberOfIpAddresses = '256'

New-AzVirtualNetwork `
    -Name 'vnet-ipam-app02' `
    -ResourceGroupName 'testavnm' `
    -Location 'japaneast' `
    -IpamPoolPrefixAllocation @($allocation)

Get-AzVirtualNetwork `
    -Name 'vnet-ipam-app02' `
    -ResourceGroupName 'testavnm' |
    ConvertTo-Json -Depth 10

次の空きである 10.240.2.0/24 が割り当てられます。

{
  "AddressSpace": {
    "AddressPrefixes": [
      "10.240.2.0/24"
    ],
    "IpamPoolPrefixAllocations": [
      {
        "Id": "/subscriptions/<subscription-id>/resourceGroups/testavnm/providers/Microsoft.Network/networkManagers/avnm-ipam-eval/ipamPools/pool-japaneast",
        "NumberOfIpAddresses": "256",
        "AllocatedAddressPrefixes": [
          "10.240.2.0/24"
        ]
      }
    ]
  }
}

静的 CIDR の 10.240.0.0/24 を避け、VNet 1 に 10.240.1.0/24、VNet 2 に 10.240.2.0/24 が割り当てられました。どちらも子プールの /20 内に収まります。

16 個と 128 個のアドレスの追加要求

ここまでは /24 を 2 個割り当てた結果でした。次に、同じ子プールから 16 個、128 個の順でアドレスを要求します。既存の VNet は変更せず、新しい VNet を 2 個追加しました。

16 個の要求に対する /28 の割り当て

CIDR は指定せず、要求アドレス数を '16' にします。作成直後に Get で取得し、アドレス空間を JSON で確認しました。

Import-Module Az.Network -ErrorAction Stop

$allocation = [Microsoft.Azure.Commands.Network.Models.PSIpamPoolPrefixAllocation]::new()
$allocation.Id = '/subscriptions/<subscription-id>/resourceGroups/testavnm/providers/Microsoft.Network/networkManagers/avnm-ipam-eval/ipamPools/pool-japaneast'
$allocation.NumberOfIpAddresses = '16'

New-AzVirtualNetwork `
    -Name 'vnet-ipam-app03' `
    -ResourceGroupName 'testavnm' `
    -Location 'japaneast' `
    -IpamPoolPrefixAllocation @($allocation)

$vnet3 = Get-AzVirtualNetwork `
    -Name 'vnet-ipam-app03' `
    -ResourceGroupName 'testavnm'

ConvertTo-Json -InputObject $vnet3.AddressSpace -Depth 10
{
  "AddressPrefixes": [
    "10.240.3.0/28"
  ],
  "IpamPoolPrefixAllocations": [
    {
      "Id": "/subscriptions/<subscription-id>/resourceGroups/testavnm/providers/Microsoft.Network/networkManagers/avnm-ipam-eval/ipamPools/pool-japaneast",
      "NumberOfIpAddresses": "16",
      "AllocatedAddressPrefixes": [
        "10.240.3.0/28"
      ]
    }
  ]
}

10.240.3.0/28 が割り当てられました。要求されたアドレス数を満たす、先頭の空きを使ってくれるようです。

続く 128 個の要求に対する /25 の割り当て

次は新しい割り当てオブジェクトに '128' を設定します。

Import-Module Az.Network -ErrorAction Stop

$allocation = [Microsoft.Azure.Commands.Network.Models.PSIpamPoolPrefixAllocation]::new()
$allocation.Id = '/subscriptions/<subscription-id>/resourceGroups/testavnm/providers/Microsoft.Network/networkManagers/avnm-ipam-eval/ipamPools/pool-japaneast'
$allocation.NumberOfIpAddresses = '128'

New-AzVirtualNetwork `
    -Name 'vnet-ipam-app04' `
    -ResourceGroupName 'testavnm' `
    -Location 'japaneast' `
    -IpamPoolPrefixAllocation @($allocation)

$vnet4 = Get-AzVirtualNetwork `
    -Name 'vnet-ipam-app04' `
    -ResourceGroupName 'testavnm'

ConvertTo-Json -InputObject $vnet4.AddressSpace -Depth 10
{
  "AddressPrefixes": [
    "10.240.3.128/25"
  ],
  "IpamPoolPrefixAllocations": [
    {
      "Id": "/subscriptions/<subscription-id>/resourceGroups/testavnm/providers/Microsoft.Network/networkManagers/avnm-ipam-eval/ipamPools/pool-japaneast",
      "NumberOfIpAddresses": "128",
      "AllocatedAddressPrefixes": [
        "10.240.3.128/25"
      ]
    }
  ]
}

割り当ては 10.240.3.128/25 です。次の空きを利用しました。賢い。

さらに 32 個のアドレスの追加要求

続けて、同じ子プールから 32 個のアドレスを要求する VNet をもう 1 個追加しました。AVNM はどこの範囲を使うのでしょうか。10.240.3.0 の空きを使うのか、10.240.4.0 に進むのか。

Import-Module Az.Network -ErrorAction Stop

$allocation = [Microsoft.Azure.Commands.Network.Models.PSIpamPoolPrefixAllocation]::new()
$allocation.Id = '/subscriptions/<subscription-id>/resourceGroups/testavnm/providers/Microsoft.Network/networkManagers/avnm-ipam-eval/ipamPools/pool-japaneast'
$allocation.NumberOfIpAddresses = '32'

$created = New-AzVirtualNetwork `
    -Name 'vnet-ipam-app05' `
    -ResourceGroupName 'testavnm' `
    -Location 'japaneast' `
    -IpamPoolPrefixAllocation @($allocation)

$vnet5 = Get-AzVirtualNetwork `
    -Name 'vnet-ipam-app05' `
    -ResourceGroupName 'testavnm'

ConvertTo-Json -InputObject $vnet5.AddressSpace -Depth 10
{
  "AddressPrefixes": [
    "10.240.3.32/27"
  ],
  "IpamPoolPrefixAllocations": [
    {
      "Id": "/subscriptions/<subscription-id>/resourceGroups/testavnm/providers/Microsoft.Network/networkManagers/avnm-ipam-eval/ipamPools/pool-japaneast",
      "NumberOfIpAddresses": "32",
      "AllocatedAddressPrefixes": [
        "10.240.3.32/27"
      ]
    }
  ]
}

割り当てられたのは 10.240.3.32/27 です。前回空きとして残っていた 10.240.3.16 ~ 10.240.3.127 の中に収まっています。賢い。

まとめ

IPAM を使うと、アドレスの大枠を親プール、用途別の範囲を子プールとして管理し、必要なアドレス数を指定するだけで VNet の CIDR が割り当てられました。与えられたアドレス数をもとに自動的に正しい空きを払い出す賢い台帳です。サブネット計算ツールを使った Excel ベースのアドレス発番とおさらばできそうです。

また、サブスクリプションと VNET を自動的に払い出す仕組みとの相性が良さそうです。利用者が申請フォーム的なものに入力した必要なアドレス数をもとに、AVNM の IPAM で空いているアドレス帯を自動的に払い出して VNET を作れます。利用者はネットワーク管理者からアドレス空間を入手する手間が省けますし、ネットワーク管理者はアドレスの払い出しを自動化の仕組みに委任できます。みんなハッピー。

参考リンク

  • 当サイトは個人のブログです。このブログに示されている見解や意見は個人的なものであり、所属組織の見解や意見を表明するものではありません。
  • 公開情報を踏まえて正確な情報を掲載するよう努めますが、その内容の完全性や正確性、有用性、安全性、最新性について一切保証しません。
  • 添付文章やリンク先などを含む本サイトの内容は作成時点でのものであり、予告なく変更される場合があります。