世界中のAzureリージョンでフルメッシュVPNを自動作成しよう

今まではAzure Resource Managerのテンプレートなどの機能に触れてきましたが、Azure Resource ManagerはPowerShellを使った手続き型の処理も可能となっています。

せっかくなので、実用的なサンプルにしようと思いましたので、ささっと書いてみました。以下の設定のコードを書いてみます。

  • リージョン: Japan East,Japan West,East US,West US,Southeast Asia,East Asia
  • リソースグループ:各リージョンに1個作成
  • 仮想ネットワーク:作成したリソースグループに1個作成
  • サブネット:作成した仮想ネットワークに2個作成(一つはゲートウェイ用)
  • VPNピアリング用ゲートウェイ:作成したゲートウェイサブネットに1個作成
  • VPNピアリング接続:フルメッシュにするので、1リージョンに他の拠点分5つ作成で合計30接続

リソースグループ、仮想ネットワーク、サブネット、ゲートウェイサブネット、リージョン間ピアリングの為のゲートウェイ、そのゲートウェイからフルメッシュで相互接続するところまでをスクリプトで完全自動化します。

こんなのを手作業で作ってるのはやってられませんね。こういう時は、巷で話題のインフラストラクチャーアズコード (Infrastructure as Code)です♪

FullMesh

  • 必要なもの Windows端末か、WindowsのVM、もしくはAzure Automation
  • Azure Automation以外の場合は追加でAzure PowerShellのインストール

Azure PowerShellのインストールおよび構成方法

自動化をこつこつと書く

普通のPowerShellでのスクリプティングです。Resource Manager APIでのPowerShellを使った仮想ネットワーク作成の方法は以下を参考にするのが一番早いでしょう。

PowerShell を使用してサイト間 VPN 接続で仮想ネットワークを作成する

以下のスクリプトで完成です、作成には相応の時間がかかりますのでじっくりのんびり待ちましょう。出来上がってしまえば、後はAzure Resource Managerで相互にテンプレートを流せばVM立てられますし、リージョンフェイルオーバとかも楽しいですね。

東日本、西日本、東南アジアに、それぞれVMを起動して相互にPingを打ち合ってみました。
ping.jpg


# fullmeshvpn.ps1
Login-AzureRmAccount
Get-AzureRmSubscription
Select-AzureRmSubscription -SubscriptionName "サブスクリプションの名前"

# パラメーター
$regions = "Japan East","Japan West","East US","West US", "Southeast Asia","East Asia"; # リージョンの並び順で作成され、ネットワーク範囲もインデックス順で作成されます
$sharedkey="IPSEC接続で設定する共有鍵" #Shared key should be a combination of alphabets (a-z or A-Z) and digits (0-9)
$rgprefix="Mesh"
$vnetname="vnet"
$gwipname="gwip"
$gwconfigname="gwconfig"
$vnetgwname="vnetgw"
$vnetconname="vnetcon"

for ( $i = 0; $i -lt $regions.Length; $i++ ){
    $rgname=$rgprefix+$regions[$i].Replace(" ","");

    # VNETの作成
    New-AzureRmResourceGroup -Name $rgname -Location $regions[$i]
    $gateway = New-AzureRmVirtualNetworkSubnetConfig -Name 'GatewaySubnet' -AddressPrefix "10.$i.254.0/28"
    $main = New-AzureRmVirtualNetworkSubnetConfig -Name 'Subnet1' -AddressPrefix "10.$i.0.0/24"
    New-AzureRmVirtualNetwork -Name $vnetname -ResourceGroupName $rgname -Location $regions[$i] -AddressPrefix "10.$i.0.0/16" -Subnet $gateway, $main
    
    # VNETGatewayの作成
    $gwpip= New-AzureRmPublicIpAddress -Name $gwipname -ResourceGroupName $rgname -Location $regions[$i] -AllocationMethod Dynamic

    $vnet = Get-AzureRmVirtualNetwork -Name $vnetname -ResourceGroupName $rgname
    $subnet = Get-AzureRmVirtualNetworkSubnetConfig -Name 'GatewaySubnet' -VirtualNetwork $vnet
    $gwipconfig = New-AzureRmVirtualNetworkGatewayIpConfig -Name $gwconfigname -SubnetId $subnet.Id -PublicIpAddressId $gwpip.Id
    
    New-AzureRmVirtualNetworkGateway -Name $vnetgwname -ResourceGroupName $rgname -Location $regions[$i] -IpConfigurations $gwipconfig -GatewayType Vpn -VpnType RouteBased
}
# 各リージョン間をすべてフルメッシュ接続
foreach($region1 in $regions)
{
    foreach($region2 in $regions)
    {
        if($region1 -eq $region2){
            continue
        }
        $rgname1=$rgprefix+$region1.Replace(" ","")
        $rgname2=$rgprefix+$region2.Replace(" ","")
        $vnetconname=$region1.Replace(" ","")+$region2.Replace(" ","")
        $vnetgw1 = Get-AzureRmVirtualNetworkGateway -Name $vnetgwname -ResourceGroupName $rgname1
        $vnetgw2 = Get-AzureRmVirtualNetworkGateway -Name $vnetgwname -ResourceGroupName $rgname2
        New-AzureRmVirtualNetworkGatewayConnection -Name $vnetconname -ResourceGroupName $rgname1 -VirtualNetworkGateway1 $vnetgw1 -VirtualNetworkGateway2 $vnetgw2 -Location $region1 -ConnectionType VNet2Vnet -SharedKey $sharedkey
    }
}
exit