とあるお客様から「Application Gateway の機能 (とくにルーティング) がどんなものか知りたい」とおっしゃるので、ちょっとやってみたらとても苦労したので、備忘録としてここに残しておく。
デモの構成
バックエンドに仮想マシンを立てて Web サーバーを構築して...というのがとても面倒くさく思い、Web Apps で賄いました。
アクセス URL のパスが "/site01/" なら「アプリ01」へ、"/site02/" なら「アプリ02」へとルーティングしようと思います。
後で、Azure AD 認証も組み込もうと思うので、Application Gateway にカスタムドメインの SSL 証明書もアップロードしておきます。
Application Gateway に実装したいこと
- SSL オフロード
- バックエンドは Web Apps (FQDN で指定)
- URL パスベースでルーティング
- セッションアフィニティを有効
これらをすべて実装するには、Azure ポータルでは作れないので、全部 PowerShell を使って作ってみることにしました。
PowerShell スクリプト
そして出来上がった PowerShell スクリプトがこちら。
要素間の関連がちょっと厳しいので、以下のようにいくつか分けて実行しました。
※なお、それぞれ実行するのに、10 ~ 20 分くらいかかる。
まずは基本的な Application Gateway を作成します。
## AzureRM モジュールをインポート
# Import-Module AzureRM
## Azure にサインイン
# Login-AzureRmAccount
# Azure サブスクリプションを選択
Select-AzureRmSubscription -Subscription xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# リソースグループの名前
$RGName = 'demodemo-rg'
# パブリック IP アドレスの名前
$pipName = 'demodemo-agw-ip'
# 仮想ネットワークの名前
$vnetName = 'demodemo-vnet'
# アプリケーションゲートウェイ用サブネットの名前
$subnetName = 'AGW-subnet'
# アプリケーションゲートウェイの名前
$agwName = 'demodemo-agw'
############################################################
#
# 基本的なアプリケーションゲートウェイの作成
#
############################################################
# 以下のリソースは事前に作成しておく
# 仮想ネットワークを取得
$vnet = Get-AzureRmVirtualNetwork -ResourceGroupName $RGName -Name $vnetName
# アプリケーションゲートウェイ用サブネットを取得
$subnet = Get-AzureRmVirtualNetworkSubnetConfig -VirtualNetwork $vnet -Name $subnetName
# パブリック IP アドレスを取得
$pip = Get-AzureRmPublicIpAddress -ResourceGroupName $RGName -Name $pipName
# ここから Application Gateway の作成
# IP 構成を作成
$gipconfig = New-AzureRmApplicationGatewayIPConfiguration -Name gatewayIP01 -Subnet $subnet
# バックエンドプールを作成
$pool = New-AzureRmApplicationGatewayBackendAddressPool -Name appGatewayBackendPool -BackendFqdns 'sitedef.azurewebsites.net'
# プローブ用のステータスコードを定義
$match = New-AzureRmApplicationGatewayProbeHealthResponseMatch -StatusCode 200-401
# プローブを作成
$probeconfig = New-AzureRmApplicationGatewayProbeConfig -Name webappprobe -Protocol Http -Path / -Interval 30 -Timeout 120 -UnhealthyThreshold 3 -PickHostNameFromBackendHttpSettings -Match $match
# バックエンドの HTTP 設定を作成
$poolSetting = New-AzureRmApplicationGatewayBackendHttpSettings -Name appGatewayBackendHttpSettings -Port 80 -Protocol Http -CookieBasedAffinity Enabled -RequestTimeout 120 -PickHostNameFromBackendAddress -Probe $probeconfig
# フロントエンド IP ポートを作成
$fp = New-AzureRmApplicationGatewayFrontendPort -Name frontendport01 -Port 80
# フロントエンド IP 構成を作成
$fipconfig = New-AzureRmApplicationGatewayFrontendIPConfig -Name fipconfig01 -PublicIPAddress $pip
# HTTP リスナーを作成
$listener = New-AzureRmApplicationGatewayHttpListener -Name listener01 -Protocol Http -FrontendIPConfiguration $fipconfig -FrontendPort $fp
# ルーティング規則を構成
$rule = New-AzureRmApplicationGatewayRequestRoutingRule -Name rule01 -RuleType Basic -BackendHttpSettings $poolSetting -HttpListener $listener -BackendAddressPool $pool
# アプリケーションゲートウェイ SKU を定義
$sku = New-AzureRmApplicationGatewaySku -Name Standard_Small -Tier Standard -Capacity 2
# アプリケーションゲートウェイを作成
$appgw = New-AzureRmApplicationGateway -Name $agwName -ResourceGroupName $RGName -Location JapanEast -BackendAddressPools $pool -BackendHttpSettingsCollection $poolSetting -Probes $probeconfig -FrontendIpConfigurations $fipconfig -GatewayIpConfigurations $gipconfig -FrontendPorts $fp -HttpListeners $listener -RequestRoutingRules $rule -Sku $sku
ここからは SSL の構成と URL パスベースのルーティング規則を構成します。
以下の要素を追加します。
- フロントエンド IP ポート
- バックエンドプール (Web アプリケーション)
- サーバー証明書
############################################################
#
# SSL の構成と URL パスベースのルーティング規則
#
############################################################
############################################################
### フロントエンド IP ポートを追加
### バックエンドプールを追加
### サーバー証明書(PFX)を追加
# アプリケーションゲートウェイを取得
$appgw = Get-AzureRmApplicationGateway -Name $agwName -ResourceGroupName $RGName
# フロントエンド IP ポートを追加
Add-AzureRmApplicationGatewayFrontendPort -ApplicationGateway $appgw -Name frontendport02 -Port 443
# バックエンドプールを追加
Add-AzureRmApplicationGatewayBackendAddressPool -ApplicationGateway $appgw -Name site01BackendPool -BackendFqdns site01a.azurewebsites.net,site01b.azurewebsites.net
Add-AzureRmApplicationGatewayBackendAddressPool -ApplicationGateway $appgw -Name site02BackendPool -BackendFqdns site02a.azurewebsites.net,site02b.azurewebsites.net
# サーバー証明書 (PFX) は事前に準備しておく
# サーバー証明書を追加
$password = ConvertTo-SecureString 'demodemo@201805' -AsPlainText -Force
Add-AzureRmApplicationGatewaySslCertificate -ApplicationGateway $appgw -Name SSLCert02 -CertificateFile 'C:\temp\www.demodemo.pgw.jp.pfx' -Password $password
# アプリケーションゲートウェイに反映
Set-AzureRmApplicationGateway -ApplicationGateway $appgw
次に、以下の要素を使って「フロントのリスナー条件と SSL オフロード」を追加します。
- フロントエンド IP ポート
- フロントエンド IP 構成
- サーバー証明書
############################################################
### フロントのリスナー条件や SSL オフロードの指定
# アプリケーションゲートウェイを取得
$appgw = Get-AzureRmApplicationGateway -Name $agwName -ResourceGroupName $RGName
# フロントエンド IP ポートを取得
$fport = Get-AzureRmApplicationGatewayFrontendPort -ApplicationGateway $appgw -Name FrontendPort02
# フロントエンド IP 構成を取得
$fipconfig = Get-AzureRmApplicationGatewayFrontendIPConfig -ApplicationGateway $appgw -Name fipconfig01
# サーバー証明書を取得
$sslcert = Get-AzureRmApplicationGatewaySslCertificate -ApplicationGateway $appgw -Name SSLCert02
# フロントのリスナー条件や SSL オフロードの指定
Add-AzureRmApplicationGatewayHttpListener -ApplicationGateway $appgw -Name Listener02 -Protocol Https -FrontendIPConfiguration $fipconfig -FrontendPort $fport -SslCertificate $sslcert
# アプリケーションゲートウェイに反映
Set-AzureRmApplicationGateway -ApplicationGateway $appgw
さらに、以下の要素を使って「URL パスマップ (パスとバックエンドプールの規則)」を追加します。
- バックエンドプール HTTP 設定
- バックエンドプール (デフォルトと Web アプリケーション)
############################################################
### URL パスマップを追加
# アプリケーションゲートウェイを取得
$appgw = Get-AzureRmApplicationGateway -Name $agwName -ResourceGroupName $RGName
# バックエンドの HTTP 設定を取得
$poolSetting = Get-AzureRmApplicationGatewayBackendHttpSettings -ApplicationGateway $appgw -Name appGatewayBackendHttpSettings
# バックエンドプールを取得
$defaultpool = Get-AzureRmApplicationGatewayBackendAddressPool -ApplicationGateway $appgw -Name appGatewayBackendPool
$site01Pool = Get-AzureRmApplicationGatewayBackendAddressPool -ApplicationGateway $appgw -Name site01BackendPool
$site02Pool = Get-AzureRmApplicationGatewayBackendAddressPool -ApplicationGateway $appgw -Name site02BackendPool
# パス規則を作成
$site01PathRule = New-AzureRmApplicationGatewayPathRuleConfig -Name site01PathRule -Paths "/site01/*" -BackendAddressPool $site01Pool -BackendHttpSettings $poolSetting
$site02PathRule = New-AzureRmApplicationGatewayPathRuleConfig -Name site02PathRule -Paths "/site02/*" -BackendAddressPool $site02Pool -BackendHttpSettings $poolSetting
# URL パスマップ構成を追加
Add-AzureRmApplicationGatewayUrlPathMapConfig -ApplicationGateway $appgw -Name urlpathmap -PathRules $site01PathRule,$site02PathRule -DefaultBackendAddressPool $defaultpool -DefaultBackendHttpSettings $poolSetting
# アプリケーションゲートウェイに反映
Set-AzureRmApplicationGateway -ApplicationGateway $appgw
最後に、以下の要素を使って「ルーティング規則」を追加します。
- HTTP リスナー
- URL パスマップ構成
############################################################
### ルーティング規則を追加
# アプリケーションゲートウェイを取得
$appgw = Get-AzureRmApplicationGateway -Name $agwName -ResourceGroupName $RGName
# HTTP リスナーを取得
$listener = Get-AzureRmApplicationGatewayHttpListener -ApplicationGateway $appgw -Name Listener02
# URL パスマップ構成を取得
$urlpathmap = Get-AzureRmApplicationGatewayUrlPathMapConfig -ApplicationGateway $appgw -Name urlpathmap
# フロントとバックエンドとのルーティンングルールを指定
Add-AzureRmApplicationGatewayRequestRoutingRule -ApplicationGateway $appgw -Name rule02 -RuleType PathBasedRouting -HttpListener $listener -UrlPathMap $urlpathmap
# アプリケーションゲートウェイに反映
Set-AzureRmApplicationGateway -ApplicationGateway $appgw
アクセス制御も忘れずに
Application Gateway リソースは仮想ネットワークのサブネットに配置します。そのサブネットにネットワーク セキュリティ グループ (NSG) を設定しましょう。
NSG の受信トラフィック規則に、以下のルールを追加します。
Name | 優先順位 | 発信元 IP | 発信元ポート | 宛先 IP | 宛先ポート | プロトコル | アクセス |
---|---|---|---|---|---|---|---|
AllowHttpsInBound | 100 | Internet | * | Any | 443 | TCP | 許可 |
AllowAGWHealthCheck InBound | 110 | Internet | * | Any | 65503-65534 | Any | 許可 |
「AllowHttpsInBound」は、Web サーバーにアクセスする通信を許可するためのルール。
「AllowAGWHealthCheckInBound」はバックエンド正常性のチェックで行う通信を許可するためのルールで、これを許可していないと正常にルーティングしてくれないのでご注意。
まとめ
Application Gateway 内の構成を把握しておかないと、Azure ポータルで作るにせよ、PowerShell を使って作るにせよ、迷子になりそうです。
それと細かな設定はやはり PowerShell を使わないと...となるので、一から PowerShell で作りましょう。
あと、Application Gateway には URL を書き換える機能は残念ながらありません。よって、www.demodemo.pgw.jp/site01/ に対する要求は対応するバックエンドへルーティングされますが、その際には /site01/ のパスも含めた URL でバックエンドの Web サーバーにアクセスされます。