Availability Zones を用いたAzure IaaS サービスの構築

##はじめに
今回はMicrosoft Azure Tech Advent Calendar 2018 の投稿ということで、日本リージョンにはまだ利用可能になっていないけど、今後使用できるようになるはずの可用性オプションのAvailability Zones（可用性ゾーン）についてまとめていきたいと思います。

##Availability Zones（可用性ゾーン）の概要
まずは、Availability Zonesって何ぞやというところなんですが、一言でいうと「Azureサービスをリージョン内のデータセンター間で冗長化するオプション」です。公式ドキュメントには次のように書かれています。

　Azure の Availability Zones の概要
　https://docs.microsoft.com/ja-jp/azure/availability-zones/az-overview#services-that-support-availability-zones

"Availability Zones は高可用性を備えたサービスで、アプリケーションとデータをデータセンターの障害から保護します。 Availability Zones は、Azure リージョン内の一意の物理的な場所です。 それぞれのゾーンは、独立した電源、冷却手段、ネットワークを備えた 1 つまたは複数のデータセンターで構成されています。 回復性を確保するため、有効になっているリージョンにはいずれも最低 3 つのゾーンが別個に存在しています。 Availability Zones は 1 リージョン内で物理的に分離されているため、データセンターで障害が発生した場合でもアプリケーションとデータを保護できます。 ゾーン冗長サービスによって、単一障害点から保護されるように Availability Zones 全体でアプリケーションとデータがレプリケートされます。"

わかる人にはわかりそうですが、わからない人にはわからんような記述ですね。
特に Public Cloud は現世から離れた雲の向こうで落ちることなく可用性・冗長性はいい感じにやってくれてるっていう認識だと意味がわからないような気がします。Availability Zonesのような冗長化オプションを使いこなすには、Cloudだってどこかにデータセンターがあって無数の物理サーバーがあって、その中で自分の使っているサービスが動いているということをイメージする必要があります。次の絵を見るとイメージがしやすいかもしれません。
![Zone.png](https://qiita-image-store.s3.amazonaws.com/0/192113/d2c99738-c87c-89fe-c839-75bc008a688c.png)
Azure Region = 東南アジアなどの仮想マシンを作成するときに選択するリージョン
Availability Zones = １つのリージョン内の独立した電源、冷却手段、ネットワークを備えたデータセンター（施設）

なので、Availability Zonesを使用すると仮想マシン3台構成のシステムを構築した場合に、仮想マシンAはZone1, 仮想マシンBはZone2, 仮想マシンCはZone3といった1つのリージョンでデータセンターをそれぞれ跨いだ構成にすることができます。それにより、例えば、１つのデータセンターレベルでの障害あった時に、残りの仮想マシンは生存することができ、システムとしての冗長性が担保されます。

###既存の可用性オプションとの違い
Availability Zoneは2017年に発表されましたが、それ以前からAzureには可用性を高めるためのオプションがいくつか用意されていました。代表的なものがペアリージョンと可用性セットです。

■ペアリージョンとの差異
Azureの冗長化の方向性として、１つのリージョン内での冗長性を増やす以外に、できるだけ多くのリージョンを増やすことに力を入れていました。そのため現在54リージョンに拡大しており他のサービスとしてもかなり多いです。日本という比較的狭い単位でも、東日本と西日本という２つのリージョンをペアとして提供されていました。
ペアリージョンの物理的な距離は数百km離れておりリージョン間で可用性を組むことで、あるリージョンレベルがお亡くなりになるような自然災害への対策として冗長性を向上させることができます。ペアリージョンとAvailability Zonesは併用が可能なため、組み合わせることでより高い可用性も実現できます。一方、パフォーマンス等の観点から物理的距離をあけることが要件に見合わない場合はAvailability Zonesだけでの冗長化を検討するのが良いかもしれません。
![region.PNG](https://qiita-image-store.s3.amazonaws.com/0/192113/760d88c0-722e-0756-ac63-a708e567ab84.png)

 Azure リージョン
 https://azure.microsoft.com/ja-jp/global-infrastructure/regions/

 ペアになっているリージョン
 https://docs.microsoft.com/ja-jp/azure/best-practices-availability-paired-regions#what-are-paired-regions

■可用性セットとの差異
可用性セットはリージョン内での可用性オプションという意味では、Availability Zonesと同じですが、Availability Zonesと異なりデータセンター間での分散配置が保証されません。従って、仮想マシンが稼働しているデータセンターレベルで障害が発生した場合は、可用性セット内の仮想マシンが同時にダウンすることがありえるという差異があります。また、可用性セットは現在Azureの全てのリージョンで利用できます。また可用性セットは現在可用性ゾーンと併用することはできません。

　Azure での Windows 仮想マシンの可用性の管理
　https://docs.microsoft.com/ja-jp/azure/virtual-machines/windows/manage-availability

##Availability Zones仮想マシンの構築
Availabilty Zoneを使用したIaaS仮想マシンの作成は、現在 Azureポータル、Azure Powershell、Azure CLIなどの複数の方法が利用できます。
###Azureポータル
Azureポータルからの構成は非常にシンプルで、https://portal.azure.com にアクセスし仮想マシンの作成画面で、「可用性オプション」 > 可用性ゾーンを選択するだけです。
![av.png](https://qiita-image-store.s3.amazonaws.com/0/192113/73a510df-ffb7-4936-4c77-4b1d5de7ac13.png)

###Azure powershell
コマンドの方が便利な場合もあると思うので、Azure PowerShellを用いた方法についても記載します。
せっかくなので”東南アジアリージョン”のAvailabilty Zone 3つに分散して３台の仮想マシンを作成するスクリプトを作成してみました。
スクリプトをそのまま実行すると、ログインとサブスクリプションの選択が求められるので選択すると、バックグラウンドで仮想マシンがそれぞれのZoneに３台作成されます。

```powershell
#パラメータ
$ResourceGroupName = "AZTest" #リソースグループ名
$Location = "SouthEast Asia" #リージョン名
$VnetName = "AZVnet" #仮想ネットワーク名
$AddressPrefix = "192.168.1.0/25" #プレフィックス
$SubnetName = "subnet1" #サブネット名
$SubnetPrefix = "192.168.1.0/27" #プレフィックス

#ログイン
Login-AzureRmAccount

#サブスクリプションの選択
$subscriptionId = (Get-AzureRmSubscription | Out-GridView -Title "Select an Azure Subscription ..." -PassThru).SubscriptionId 
Select-AzureRmSubscription -SubscriptionId $subscriptionId 

#リソースグループの作成
New-AzureRmResourceGroup -Name $ResourceGroupName -Location $Location

#サブネット作成
$subnetConfig = New-AzureRmVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $SubnetPrefix

#仮想ネットワークの作成
$vnet = New-AzureRmVirtualNetwork -ResourceGroupName $ResourceGroupName -Location $Location `
 -Name $VnetName -AddressPrefix $AddressPrefix -Subnet $subnetConfig

#ネットワークセキュリティグループの作成
$nsgRuleRDP = New-AzureRmNetworkSecurityRuleConfig -Name myNetworkSecurityGroupRuleRDP  -Protocol Tcp `
    -Direction Inbound -Priority 1000 -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix * `
    -DestinationPortRange 3389 -Access Allow

$nsg = New-AzureRmNetworkSecurityGroup -ResourceGroupName $ResourceGroupName -Location $Location `
    -Name myNetworkSecurityGroup -SecurityRules $nsgRuleRDP

#仮想マシンの管理者アカウント設定
$cred = Get-Credential

for ($i=1; $i -le 3; $i++){
#パブリックIPの作成
    $pip = New-AzureRmPublicIpAddress -ResourceGroupName $ResourceGroupName -Location $Location -Zone $i `
        -AllocationMethod Static -IdleTimeoutInMinutes 4 -Name "mypublicdns$i"

    #ネットワークインターフェースの作成
    $nic = New-AzureRmNetworkInterface -Name "myNic$i" -ResourceGroupName $ResourceGroupName -Location $Location `
        -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -NetworkSecurityGroupId $nsg.Id

    #仮想マシンの作成
    $vmConfig = New-AzureRmVMConfig -VMName "myV$i" -VMSize "Standard_D1_v2" -Zone $i | `
        Set-AzureRmVMOperatingSystem -Windows -ComputerName myVM$i -Credential $cred | `
        Set-AzureRmVMSourceImage -PublisherName MicrosoftWindowsServer -Offer WindowsServer `
        -Skus 2016-Datacenter -Version latest | Add-AzureRmVMNetworkInterface -Id $nic.Id
    New-AzureRmVM -ResourceGroupName $ResourceGroupName -Location $Location -VM $vmConfig -AsJob
}
```

##最後に
今回の投稿はここまでにして、また可用性セット構成の仮想マシンを可用性ゾーンの変換方法なども公開したいなと思います。
上記を読んでAzureのインフラの仕組みに興味が出てきた方は、次の資料もおすすめです。良いクリスマスを！

　詳説 Azure IaaS ～私はインフラが好きだ～
　https://channel9.msdn.com/Events/de-code/2016/INF-001
　
　[Azure] マイクロソフトのデータセンター
　https://www.youtube.com/watch?v=2hmtcdi5LwQ