アクセス分散にTraffic Managerを使っていると、メンテナンス期間に入るエンドポイントを停止(無効化)してトラフィックを切り替えたい場合がある。これをPowerShellスクリプトで実装すると、トラフィックの制御を自動化しやすくなる。
対象:Azure Traffic Manager、PowerShell
Azureの「Traffic Manager」を利用している場合、普段は設定済みのルーティング方法で自動的にアクセスを分散しているはずだ。
しかし、これを変更したい場合がある。例えば、あるエンドポイント(オリジンサーバ)がメンテナンス期間に入る前に、そのエンドポイントへのトラフィックを止めておき、メンテナンスが終わって回復したら元に戻したい、という状況だ。
もちろんAzureポータルから手動でこうした設定変更はできる。ただ、予定されたメンテナンスなど、そのトリガーが把握できているなら自動化して省力化を図りたいところだろう。
そこで本Tech TIPSでは、Azure PowerShellを使ってTraffic Managerのトラフィック分散を制御する方法を紹介する。トラフィック制御をPowerShellスクリプトに実装してAzure AutomationのRunbookに登録すれば、希望のタイミングで自動実行できるようになる。
Automationへの登録などについては、Tech TIPS「【Azure】権限に注意! AutomationでApp Serviceの定期的な再起動を自動化する(PowerShell編)」「【Azure】AutomationアカウントでVMの起動/停止を定期的に繰り返すスケジュールを組む(ARMテンプレート編)」を参照していただきたい。
まずは「Get-AzTrafficManagerProfile」コマンドレットで対象のTraffic Managerプロファイルのオブジェクトを取得する。
そこには、Traffic Managerプロファイルに設定済みのTraffic Managerエンドポイント(以下、「エンドポイント」と略)の一覧が含まれていて、「Endpoints」プロパティに配列で格納されている。
# Traffic Managerプロファイルの指定
$TMProfileName = "<Traffic Managerプロファイル名>"
$TMProfileRG = "<↑のリソースグループ名>"
# Traffic Managerプロファイルのオブジェクトを取得
$TMProfile = Get-AzTrafficManagerProfile `
-ResourceGroupName $TMProfileRG -Name $TMProfileName
# ↑の概要を表示
# 列名: 名前、サブドメイン名、ルーティング方法、エンドポイント名の一覧
$TMProfile | Format-Table `
-Property Name, RelativeDnsName, TrafficRoutingMethod, Endpoints
# Traffic Managerのエンドポイント一覧を取得
$TMEndpoints = $TMProfile.Endpoints
# ↑の概要を表示
# 列名: 名前、種類、ターゲットリソース、状態、モニターの状態
$TMEndpoints | Format-Table `
-Property Name, Type, Target, EndpointStatus, EndpointMonitorStatus
上記リストでは変数「$TMEndpoints」にエンドポイント一覧の配列を代入している。ここから対象のエンドポイントを探すことが可能だ(詳しくはすぐ後で説明)。
次に、取得したエンドポイント一覧から対象のエンドポイントを見つける。以下では、エンドポイントとしてApp ServiceによるWebサイトを想定している。
# エンドポイントのApp Serviceの名前
$webAppName = "<App Service名>"
# ↑のデフォルトのFQDN
$webAppDefaultFQDN = $webAppName + ".azurewebsites.net"
# FQDNからエンドポイントを探す
$targetEndpoint = $TMEndpoints | Where-Object { `
# Azureのサービスで、かつターゲットリソース名がFQDNに一致
$_.Type -eq "azureEndpoints" -and $_.Target -eq $webAppDefaultFQDN
}
$targetEndpoint | Format-List # プロパティをリスト表示
各エンドポイントのオブジェクトからは、さまざまなプロパティを取得できる。
例えばエンドポイントがApp Serviceの場合、「Target」プロパティにはApp ServiceのデフォルトのFQDN「<App Service名>.azurewebsites.net」が格納されている。上記リストでは、このプロパティからエンドポイントを特定している。
また「EndpointStatus」プロパティが「Enabled」という文字列ならエンドポイントは有効で、「Disabled」なら無効だと判定できる。さらに「EndpointMonitorStatus」が「Online」という文字列なら、(オブジェクトの取得時点で)エンドポイントと通信できている(正常性チェックが真である)ことが分かる。
エンドポイントを特定できたら、そのオブジェクトを再取得して、最新の状態に更新しよう。エンドポイントとの疎通など、刻々と変わる可能性のある情報も含まれるため、必要に応じて最新の状態をチェックした方がよい。
上記リストのようにして、既にエンドポイントのオブジェクトが取得済みの場合、以下のようにそれを「Get-AzTrafficManagerEndpoint」コマンドレットへパイプで渡すと、簡単に最新の状態を取得(更新)できる。
$targetEndpoint = $targetEndpoint | Get-AzTrafficManagerEndpoint
一方、エンドポイントのオブジェクトが未取得の場合は、以下のようにTraffic Managerのプロファイル名とリソースグループ名、エンドポイント名、エンドポイントの種類の4つ全てを、Get-AzTrafficManagerEndpointコマンドレットのパラメーターに指定しなければならない。
$TMProfileName = "<Traffic Managerプロファイル名>"
$TMProfileRG = "<↑のリソースグループ名>"
$endpointName = "<Traffic Managerエンドポイント名>"
$endpointType = "AzureEndpoints" # App ServiceなどAzureのサービス
#$endpointType = "ExternalEndpoints" # Azure以外のサービスやサーバ
#$endpointType = "NestedEndpoints" # Traffic Managerの入れ子
$targetEndpoint = Get-AzTrafficManagerEndpoint `
-ResourceGroupName $TMProfileRG -ProfileName $TMProfileName `
-Name $endpointName `
-Type $endpointType
最新のエンドポイントのオブジェクトを取得したら、以下のように「Disable-AzTrafficManagerEndpoint」コマンドレットにパイプで渡すと、そのエンドポイントを無効化できる。
$targetEndpoint | Disable-AzTrafficManagerEndpoint -Force # 無効化
$targetEndpoint = $targetEndpoint | Get-AzTrafficManagerEndpoint # 最新状態を取得
$targetEndpoint.EndpointStatus # 「Disabled」すなわち無効のはず
「-Force」パラメーターを付けると、対話的な操作と確認を省略して、無効化を強行できる。AutomationアカウントのRunbookのようにバッチ処理をするなら、このパラメーターは必ず指定すること。
Disable-AzTrafficManagerEndpointコマンドレットは、無効化に成功すると真を返す(失敗したらnull)。エンドポイントのオブジェクトは返さないので、上記リストではGet-AzTrafficManagerEndpointコマンドレットで最新のエンドポイントのオブジェクトを取得し直して、「$targetEndpoint」を更新している。
無効化したエンドポイントを有効化するには、以下のように「Enable-AzTrafficManagerEndpoint」コマンドレットを実行する。
$targetEndpoint | Enable-AzTrafficManagerEndpoint # 有効化
$targetEndpoint = $targetEndpoint | Get-AzTrafficManagerEndpoint # 最新状態を取得
$targetEndpoint.EndpointStatus # 「Enabled」すなわち有効のはず
Disable-AzTrafficManagerEndpointコマンドレットと同じく、エンドポイントのオブジェクトはパイプで渡せる。また戻り値も真(成功)かnull(失敗)である。
■関連リンク
Copyright© Digital Advantage Corp. All Rights Reserved.