带网关的VNET中的Azure API管理(502 - Web服务器在充当网关或代理服务器时收到无效响应)

时间:2017-03-12 20:37:15

标签: azure azure-powershell azure-api-management

我需要在内部VNET中将Azure API Management与Application Gateway集成。我使用了Microsoft的手册: Integrate API Management in an internal VNET with Application Gateway

我使用自签名证书进行自定义域名。

以下是带有Application Gateway的内部VNET中的API Management图 enter image description here

我根据以下手册Integrate API Management in an internal VNET with Application Gateway

开发了PowerShell脚本
#Configuration
$organizationName = "TestOrg1"
$resourceGroupName = "API-Management-in-VNET-with-Gateway-Test"
$appGatewayHostname = "myapi.azure-api.net"
$apiManagementServiceName = "MyApi"

#Credentials
$subscriptionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$azureAccountName ="xxxxx@xxxxx.com"
$azurePassword = "xxxxxx"

#Configuration
$location = "South Central US"
$apiManagementAdminEmail = "yyyyyy@xxxxx.com" 
$apiHostname = "api.mydomain.com"
$sslPort = 443

#Network
$virtualNetworkAddressPrefix = "10.0.0.0/16"
$gatewaySubnetAddressPrefix = "10.0.0.0/24"
$apiManagementSubnetAddressPrefix = "10.0.1.0/24"

#Certificate
$pfxCertificatePassword = "xxxxxxxxxxxx"
$certificateThumbprint = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$pfxCertificateFilename = $PSScriptRoot + "\PfxCert.pfx"
$cerCertificateFilename = $PSScriptRoot + "\CerCert.cer" 

#Output colors
$foregroundColor = "green"
$backgroundColor = "black"

#Log 
$ErrorActionPreference = "SilentlyContinue"
Stop-Transcript | out-null
$ErrorActionPreference = "Continue"
$date = (get-date).tostring("MM-dd-yyyy-HH-mm-ss")
$logFile = $PSScriptRoot + "\log\CreateApiManagementEnvLog-" + $date + ".txt"
Start-Transcript -path $logFile
$startTime = Get-Date
Write-Host("Start Time: " + $startTime) 
$azurePasswordSecureString = ConvertTo-SecureString $azurePassword -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PSCredential($azureAccountName, $azurePasswordSecureString)
$colors = "-foregroundcolor $foregroundColor -backgroundcolor $backgroundcolor"

#Step 01
Login-AzureRmAccount -Credential $credentials
Write-Host("Step 01 [Login-AzureRmAccount] completed") $colors

#Step 02
Get-AzureRmSubscription -Subscriptionid $subscriptionId | Select-AzureRmSubscription
Write-Host("Step 02 [Get-AzureRmSubscription] completed") $colors

#Step 03
New-AzureRmResourceGroup -Name $resourceGroupName -Location $location
Write-Host("Step 03 [New-AzureRmResourceGroup] completed") $colors

#Step 04
$appgatewaysubnet = New-AzureRmVirtualNetworkSubnetConfig -Name apim01 -AddressPrefix $gatewaySubnetAddressPrefix
Write-Host("Step 04 [New-AzureRmVirtualNetworkSubnetConfig] completed") $colors

#Step 05
$apimsubnet = New-AzureRmVirtualNetworkSubnetConfig -Name apim02 -AddressPrefix $apiManagementSubnetAddressPrefix
Write-Host("Step 05 [New-AzureRmVirtualNetworkSubnetConfig] completed") $colors

#Step 06
$vnet = New-AzureRmVirtualNetwork -Name appgwvnet -ResourceGroupName $resourceGroupName -Location $location -AddressPrefix $virtualNetworkAddressPrefix -Subnet $appgatewaysubnet,$apimsubnet
Write-Host("Step 06 [New-AzureRmVirtualNetwork] completed") $colors

#Step 07
$appgatewaysubnetdata=$vnet.Subnets[0]
Write-Host("Step 07 [$appgatewaysubnetdata] completed") $colors

#Step 08
$apimsubnetdata=$vnet.Subnets[1]
Write-Host("Step 08 [$apimsubnetdata] completed") $colors

#Step 10
$apimVirtualNetwork = New-AzureRmApiManagementVirtualNetwork -Location $location -SubnetResourceId $apimsubnetdata.Id
Write-Host("Step 09 [New-AzureRmApiManagementVirtualNetwork] completed") $colors

#Step 10
$apimService = New-AzureRmApiManagement -ResourceGroupName "$resourceGroupName" -Location $location -Name $apiManagementServiceName -Organization $organizationName -AdminEmail $apiManagementAdminEmail -VirtualNetwork $apimVirtualNetwork -VpnType "Internal" -Sku "Premium"
Write-Host("Step 10 [New-AzureRmApiManagement] completed") $colors

#Step 11
$certUploadResult = Import-AzureRmApiManagementHostnameCertificate -ResourceGroupName "$resourceGroupName" -Name $apiManagementServiceName -HostnameType "Proxy" -PfxPath $pfxCertificateFilename -PfxPassword $pfxCertificatePassword -PassThru
Write-Host("Step 11 [Import-AzureRmApiManagementHostnameCertificate] completed") $colors

#Step 12
$proxyHostnameConfig = New-AzureRmApiManagementHostnameConfiguration -CertificateThumbprint $certificateThumbprint -Hostname "$apiHostname"
Write-Host("Step 12 [New-AzureRmApiManagementHostnameConfiguration] completed") $colors

#Step 13
$result = Set-AzureRmApiManagementHostnames -Name $apiManagementServiceName -ResourceGroupName "$resourceGroupName" –PortalHostnameConfiguration $proxyHostnameConfig
Write-Host("Step 13 [Set-AzureRmApiManagementHostnames] completed") $colors

#Step 14
$publicip = New-AzureRmPublicIpAddress -ResourceGroupName $resourceGroupName -name publicIP01 -location $location -AllocationMethod Dynamic
Write-Host("Step 14 [New-AzureRmPublicIpAddress] completed") $colors

#Step 15
$gipconfig = New-AzureRmApplicationGatewayIPConfiguration -Name gatewayIP01 -Subnet $appgatewaysubnetdata
Write-Host("Step 15 [New-AzureRmApplicationGatewayIPConfiguration] completed") $colors

#Step 16
$fp01 = New-AzureRmApplicationGatewayFrontendPort -Name 'port01' -Port $sslPort
Write-Host("Step 16 [New-AzureRmApplicationGatewayFrontendPort] completed") $colors

#Step 17
$fipconfig01 = New-AzureRmApplicationGatewayFrontendIPConfig -Name "frontend1" -PublicIPAddress $publicip
Write-Host("Step 17 [New-AzureRmApplicationGatewayFrontendIPConfig] completed") $colors

#Step 18
$cert = New-AzureRmApplicationGatewaySslCertificate -Name cert01 -CertificateFile $pfxCertificateFilename -Password $pfxCertificatePassword
Write-Host("Step 18 [New-AzureRmApplicationGatewaySslCertificate] completed") $colors

#Step 19
$listener = New-AzureRmApplicationGatewayHttpListener -Name listener01 -Protocol Https -FrontendIPConfiguration $fipconfig01 -FrontendPort $fp01 -SslCertificate $cert
Write-Host("Step 19 [New-AzureRmApplicationGatewayHttpListener] completed") $colors

#Step 20
$apimprobe = New-AzureRmApplicationGatewayProbeConfig -Name apimproxyprobe -Protocol Https -HostName $appGatewayHostname -Path "/status-0123456789abcdef" -Interval 30 -Timeout 120 -UnhealthyThreshold 8
Write-Host("Step 20 [New-AzureRmApplicationGatewayHttpListener] completed") $colors

#Step 21
$authcert = New-AzureRmApplicationGatewayAuthenticationCertificate -Name 'whitelistcert1' -CertificateFile $cerCertificateFilename
Write-Host("Step 21 [New-AzureRmApplicationGatewayAuthenticationCertificate] completed") $colors

#Step 22
$apimPoolSetting = New-AzureRmApplicationGatewayBackendHttpSettings -Name "apimPoolSetting" -Port $sslPort -Protocol Https -CookieBasedAffinity Disabled -Probe $apimprobe -AuthenticationCertificates $authcert -RequestTimeout 180
Write-Host("Step 22 [New-AzureRmApplicationGatewayBackendHttpSettings] completed") $colors

#Step 23
$apimProxyBackendPool = New-AzureRmApplicationGatewayBackendAddressPool -Name apimbackend -BackendIPAddresses $apimService.StaticIPs[0]
Write-Host("Step 23 [New-AzureRmApplicationGatewayBackendAddressPool] completed") $colors

#Step 24
$echoapiRule = New-AzureRmApplicationGatewayPathRuleConfig -Name "externalapis" -Paths "/echo/*" -BackendAddressPool $apimProxyBackendPool -BackendHttpSettings $apimPoolSetting
Write-Host("Step 24 [New-AzureRmApplicationGatewayPathRuleConfig] completed") $colors

#Step 25
$urlPathMap = New-AzureRmApplicationGatewayUrlPathMapConfig -Name "urlpathmap" -PathRules $echoapiRule -DefaultBackendAddressPool $apimProxyBackendPool -DefaultBackendHttpSettings $apimPoolSetting
Write-Host("Step 25 [New-AzureRmApplicationGatewayUrlPathMapConfig] completed") $colors

#Step 26
$rule01 = New-AzureRmApplicationGatewayRequestRoutingRule -Name "rule1" -RuleType PathBasedRouting -HttpListener $listener -UrlPathMap $urlPathMap
Write-Host("Step 26 [New-AzureRmApplicationGatewayRequestRoutingRule] completed") $colors

#Step 27
$sku = New-AzureRmApplicationGatewaySku -Name WAF_Medium -Tier WAF -Capacity 2
Write-Host("Step 27 [New-AzureRmApplicationGatewaySku] completed") $colors

#Step 28
$config = New-AzureRmApplicationGatewayWebApplicationFirewallConfiguration -Enabled $true -FirewallMode "Prevention"
Write-Host("Step 28 [New-AzureRmApplicationGatewayWebApplicationFirewallConfiguration] completed") $colors

#Step 29
$appgw = New-AzureRmApplicationGateway -Name appgwtest -ResourceGroupName $resourceGroupName -Location $location -BackendAddressPools $apimProxyBackendPool -BackendHttpSettingsCollection $apimPoolSetting -FrontendIpConfigurations $fipconfig01 -GatewayIpConfigurations $gipconfig -FrontendPorts $fp01 -HttpListeners $listener -UrlPathMaps $urlPathMap -RequestRoutingRules $rule01 -Sku $sku -WebApplicationFirewallConfig $config -SslCertificates $cert -AuthenticationCertificates $authcert -Probes $apimprobe
Write-Host("Step 29 [New-AzureRmApplicationGateway] completed") $colors

#Step 30
Get-AzureRmPublicIpAddress -ResourceGroupName $resourceGroupName -Name publicIP01
Write-Host("Step 30 [Get-AzureRmPublicIpAddress] completed") $colors

#Step 31
Write-Host("Step 31 You need to create CNAME record for custom api domain(see DnsSettingsText -> fqdn)") $colors

#Done
Write-Host("Done") $colors
$endTime = Get-Date
$elapsedTime = New-Timespan –Start $startTime –End $endTime

Write-Host("End Time: " + $endTime) $colors
Write-Host("Elapsed Time: " + $elapsedTime) $colors
Write-Host "Press any key to continue ..." $colors

$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

Stop-Transcript

配置脚本成功运行。没有任何错误。但是,如果我尝试通过网关访问Echo API,则会出现错误:“ 502 - Web服务器在充当网关或代理服务器时收到无效响应。”如果我使用Azure API管理服务而没有内部虚拟网络工作正常。

我经历了几本手册: How to use Azure API Management with virtual networks

Troubleshooting bad gateway errors in Application Gateway

Control network traffic flow with network security groups

我找到了这些细节:

配置Azure应用程序网关后,用户可能遇到的错误之一是“服务器错误:502 - Web服务器在充当网关或代理服务器时收到无效响应”。由于以下主要原因,可能会发生此错误:

  • Azure Application Gateway的后端池未配置或为空。

  • VM Scale Set中的VM或实例都不健康。

  • 后端VM或VM Scale Set实例未响应默认运行状况探测。

  • 自定义运行状况探测的配置无效或不正确。请求超时或用户请求的连接问题。

我的问题是

  1. 我是否需要配置虚拟机?
  2. 我是否需要使用Azure网络安全组为我拥有的子网配置防火墙规则?
  3. 我应该以Base-64编码还是DER编码二进制格式导出自定义域自签名证书,以将其上传到Azure?
  4. 如何解决我的问题?
  5. Microsoft手册Integrate API Management in an internal VNET with Application Gateway遗漏了什么?
  6. 如何解决502错误?

3 个答案:

答案 0 :(得分:3)

最后,我解决了(502)网关问题。问题出在Integrate API Management in an internal VNET with Application Gateway手册中。

错误的行:

#Step 13
$result = Set-AzureRmApiManagementHostnames -Name $apiManagementServiceName -ResourceGroupName "$resourceGroupName" –PortalHostnameConfiguration $proxyHostnameConfig

要为API代理-ProxyHostnameConfiguration $proxyHostnameConfig设置自定义域名,应使用-PortalHostnameConfiguration $proxyHostnameConfig

实际上,我在Integrate API Management in an internal VNET with Application Gateway手册中发现了2个错误。

Contributed #1#2Integrate API Management in an internal VNET with Application Gateway手册现已更新。

答案 1 :(得分:1)

  1. 您需要创建一个VM以在内部测试APIM(您可以使用this指南)
  2. 不,除非您想限制某种流量
  3. 问题不明确,上传到准确的位置,但通常Azure服务接受base64编码的证书
  4. 在VNet内创建VM并尝试访问API Management
  5. 不知道,可能没什么,我很少看到MS文档中明显错误的内容
  6. 确保HTTP探测显示正常,检查API网关配置,如果您使用证书与APIM通信,则应确保APIM接受该证书

答案 2 :(得分:0)

帖子Integrate API Management in an internal VNET with Application Gateway涵盖了仅通过应用网关公开网关/代理的某些API的方案。

如果您还想通过Application Gateway访问Developer Portal / Publisher Portal。您需要按照文档Create AppGateway to access multiple web application

进行操作

我试图捕捉,这里的步骤发生变化(可能会有轻微的拼写错误)

    #Configuration
    $organizationName = "TestOrg1"
    $resourceGroupName = "API-Management-in-VNET-with-Gateway-Test"
    $appGatewayHostname = "myapi.azure-api.net"
    $apiPortalHostname = "myapi.portal.azure-api.net"
    $apiManagementServiceName = "MyApi"

    #Credentials
    $subscriptionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    $azureAccountName ="xxxxx@xxxxx.com"
    $azurePassword = "xxxxxx"

    #Configuration
    $location = "South Central US"
    $apiManagementAdminEmail = "yyyyyy@xxxxx.com" 
    $apiHostname = "api.mydomain.com"
    $portalHostname = "portal.mydomain.com"
    $sslPort = 443

    #Network
    $virtualNetworkAddressPrefix = "10.0.0.0/16"
    $gatewaySubnetAddressPrefix = "10.0.0.0/24"
    $apiManagementSubnetAddressPrefix = "10.0.1.0/24"

    #Certificate <!-- This Certificate is *.mydomain.com -->
    $pfxCertificatePassword = "xxxxxxxxxxxx"
    $certificateThumbprint = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    $pfxCertificateFilename = $PSScriptRoot + "\PfxCert.pfx"
    $cerCertificateFilename = $PSScriptRoot + "\CerCert.cer" 

    #Output colors
    $foregroundColor = "green"
    $backgroundColor = "black"

    #Log 
    $ErrorActionPreference = "SilentlyContinue"
    Stop-Transcript | out-null
    $ErrorActionPreference = "Continue"
    $date = (get-date).tostring("MM-dd-yyyy-HH-mm-ss")
    $logFile = $PSScriptRoot + "\log\CreateApiManagementEnvLog-" + $date + ".txt"
    Start-Transcript -path $logFile
    $startTime = Get-Date
    Write-Host("Start Time: " + $startTime) 
    $azurePasswordSecureString = ConvertTo-SecureString $azurePassword -AsPlainText -Force
    $credentials = New-Object System.Management.Automation.PSCredential($azureAccountName, $azurePasswordSecureString)
    $colors = "-foregroundcolor $foregroundColor -backgroundcolor $backgroundcolor"

    #Step 01
    Login-AzureRmAccount -Credential $credentials
    Write-Host("Step 01 [Login-AzureRmAccount] completed") $colors

    #Step 02
    Get-AzureRmSubscription -Subscriptionid $subscriptionId | Select-AzureRmSubscription
    Write-Host("Step 02 [Get-AzureRmSubscription] completed") $colors

    #Step 03
    New-AzureRmResourceGroup -Name $resourceGroupName -Location $location
    Write-Host("Step 03 [New-AzureRmResourceGroup] completed") $colors

    #Step 04
    $appgatewaysubnet = New-AzureRmVirtualNetworkSubnetConfig -Name apim01 -AddressPrefix $gatewaySubnetAddressPrefix
    Write-Host("Step 04 [New-AzureRmVirtualNetworkSubnetConfig] completed") $colors

    #Step 05
    $apimsubnet = New-AzureRmVirtualNetworkSubnetConfig -Name apim02 -AddressPrefix $apiManagementSubnetAddressPrefix
    Write-Host("Step 05 [New-AzureRmVirtualNetworkSubnetConfig] completed") $colors

    #Step 06
    $vnet = New-AzureRmVirtualNetwork -Name appgwvnet -ResourceGroupName $resourceGroupName -Location $location -AddressPrefix $virtualNetworkAddressPrefix -Subnet $appgatewaysubnet,$apimsubnet
    Write-Host("Step 06 [New-AzureRmVirtualNetwork] completed") $colors

    #Step 07
    $appgatewaysubnetdata=$vnet.Subnets[0]
    Write-Host("Step 07 [$appgatewaysubnetdata] completed") $colors

    #Step 08
    $apimsubnetdata=$vnet.Subnets[1]
    Write-Host("Step 08 [$apimsubnetdata] completed") $colors

    #Step 10
    $apimVirtualNetwork = New-AzureRmApiManagementVirtualNetwork -Location $location -SubnetResourceId $apimsubnetdata.Id
    Write-Host("Step 09 [New-AzureRmApiManagementVirtualNetwork] completed") $colors

    #Step 11
    $apimService = New-AzureRmApiManagement -ResourceGroupName "$resourceGroupName" -Location $location -Name $apiManagementServiceName -Organization $organizationName -AdminEmail $apiManagementAdminEmail -VirtualNetwork $apimVirtualNetwork -VpnType "Internal" -Sku "Premium"
    Write-Host("Step 10 [New-AzureRmApiManagement] completed") $colors

    #Step 12
    $certUploadResult = Import-AzureRmApiManagementHostnameCertificate -ResourceGroupName "$resourceGroupName" -Name $apiManagementServiceName -HostnameType "Proxy" -PfxPath $pfxCertificateFilename -PfxPassword $pfxCertificatePassword -PassThru
    Write-Host("Step 11 [Import-AzureRmApiManagementHostnameCertificate] completed") $colors

    #Step 13
    $proxyHostnameConfig = New-AzureRmApiManagementHostnameConfiguration -CertificateThumbprint $certificateThumbprint -Hostname "$apiHostname"
    Write-Host("Step 12 [New-AzureRmApiManagementHostnameConfiguration] completed") $colors

    $portalHostnameConfig = New-AzureRmApiManagementHostnameConfiguration -CertificateThumbprint $certificateThumbprint -Hostname "$portalHostname"
    Write-Host("Step 12 [New-AzureRmApiManagementHostnameConfiguration] completed") $colors

    #Step 14
    $result = Set-AzureRmApiManagementHostnames -Name $apiManagementServiceName -ResourceGroupName "$resourceGroupName" –PortalHostnameConfiguration $portalHostnameConfig -ProxyHostnameConfiguration $proxyHostnameConfig
    Write-Host("Step 13 [Set-AzureRmApiManagementHostnames] completed") $colors

    #Step 15
    $publicip = New-AzureRmPublicIpAddress -ResourceGroupName $resourceGroupName -name publicIP01 -location $location -AllocationMethod Dynamic
    Write-Host("Step 14 [New-AzureRmPublicIpAddress] completed") $colors

    #Step 16
    $gipconfig = New-AzureRmApplicationGatewayIPConfiguration -Name gatewayIP01 -Subnet $appgatewaysubnetdata
    Write-Host("Step 15 [New-AzureRmApplicationGatewayIPConfiguration] completed") $colors

    #Step 17
    $fp01 = New-AzureRmApplicationGatewayFrontendPort -Name 'port01' -Port $sslPort
    Write-Host("Step 16 [New-AzureRmApplicationGatewayFrontendPort] completed") $colors

    #Step 18
    $fipconfig01 = New-AzureRmApplicationGatewayFrontendIPConfig -Name "frontend1" -PublicIPAddress $publicip
    Write-Host("Step 17 [New-AzureRmApplicationGatewayFrontendIPConfig] completed") $colors

    #Step 19
    $cert = New-AzureRmApplicationGatewaySslCertificate -Name cert01 -CertificateFile $pfxCertificateFilename -Password $pfxCertificatePassword
    Write-Host("Step 18 [New-AzureRmApplicationGatewaySslCertificate] completed") $colors

    #Step 20
    $apimlistener = New-AzureRmApplicationGatewayHttpListener -Name listener01 -Protocol Https -FrontendIPConfiguration $fipconfig01 -FrontendPort $fp01 -SslCertificate $cert -HostName $appGatewayHostname
    Write-Host("Step 19 [New-AzureRmApplicationGatewayHttpListener] completed") $colors

    $apimportallistener = New-AzureRmApplicationGatewayHttpListener -Name listener02 -Protocol Https -FrontendIPConfiguration $fipconfig01 -FrontendPort $fp01 -SslCertificate $cert -HostName $apiPortalHostname
    Write-Host("Step 19 [New-AzureRmApplicationGatewayHttpListener] completed") $colors

    #Step 21
    $apimprobe = New-AzureRmApplicationGatewayProbeConfig -Name apimproxyprobe -Protocol Https -HostName $appGatewayHostname -Path "/status-0123456789abcdef" -Interval 30 -Timeout 120 -UnhealthyThreshold 8
    Write-Host("Step 20 [New-AzureRmApplicationGatewayProbeConfig] completed") $colors

    $apimportalprobe = New-AzureRmApplicationGatewayProbeConfig -Name apimportalprobe -Protocol Https -HostName $apiPortalHostname -Path "/status-0123456789abcdef" -Interval 30 -Timeout 120 -UnhealthyThreshold 8
    Write-Host("Step 20 [New-AzureRmApplicationGatewayProbeConfig] completed") $colors

    #Step 22
    $authcert = New-AzureRmApplicationGatewayAuthenticationCertificate -Name 'whitelistcert1' -CertificateFile $cerCertificateFilename
    Write-Host("Step 21 [New-AzureRmApplicationGatewayAuthenticationCertificate] completed") $colors

    #Step 23
    $apimPoolSetting = New-AzureRmApplicationGatewayBackendHttpSettings -Name "apimPoolSetting" -Port $sslPort -Protocol Https -CookieBasedAffinity Disabled -Probe $apimprobe -AuthenticationCertificates $authcert -RequestTimeout 180
    Write-Host("Step 22 [New-AzureRmApplicationGatewayBackendHttpSettings] completed") $colors

    $apimPoolPortalSetting = New-AzureRmApplicationGatewayBackendHttpSettings -Name "apimPoolPortalSetting" -Port $sslPort -Protocol Https -CookieBasedAffinity Disabled -Probe $apimportalprobe -AuthenticationCertificates $authcert -RequestTimeout 180
    Write-Host("Step 22 [New-AzureRmApplicationGatewayBackendHttpSettings] completed") $colors

    #Step 24
    $apimProxyBackendPool = New-AzureRmApplicationGatewayBackendAddressPool -Name apimbackend -BackendIPAddresses $apimService.StaticIPs[0]
    Write-Host("Step 23 [New-AzureRmApplicationGatewayBackendAddressPool] completed") $colors


    #Step 25
    $rule01 = New-AzureRmApplicationGatewayRequestRoutingRule -Name "rule1" -RuleType Basic -HttpListener $apimlistener 
    Write-Host("Step 26 [New-AzureRmApplicationGatewayRequestRoutingRule] completed") $colors

    $rule02 = New-AzureRmApplicationGatewayRequestRoutingRule -Name "rule2" -RuleType Basic -HttpListener $apimportallistener
    Write-Host("Step 26 [New-AzureRmApplicationGatewayRequestRoutingRule] completed") $colors

    #Step 26
    $sku = New-AzureRmApplicationGatewaySku -Name Standard_Medium -Tier Standard -Capacity 2
    Write-Host("Step 27 [New-AzureRmApplicationGatewaySku] completed") $colors

    #Step 27
    $appgw = New-AzureRmApplicationGateway -Name appgwtest -ResourceGroupName $resourceGroupName -Location $location -BackendAddressPools $apimProxyBackendPool -BackendHttpSettingsCollection $apimPoolSetting, $apimPoolPortalSetting -FrontendIpConfigurations $fipconfig01 -GatewayIpConfigurations $gipconfig -FrontendPorts $fp01 -HttpListeners $apimlistener, $apimportallistener -RequestRoutingRules $rule01, $rule02 -Sku $sku -SslCertificates $cert -AuthenticationCertificates $authcert -Probes $apimprobe, $apimportalprobe
    Write-Host("Step 29 [New-AzureRmApplicationGateway] completed") $colors

    #Step 28
    Get-AzureRmPublicIpAddress -ResourceGroupName $resourceGroupName -Name publicIP01
    Write-Host("Step 30 [Get-AzureRmPublicIpAddress] completed") $colors

    #Step 29
    Write-Host("Step 31 You need to create CNAME record for custom api domain(see DnsSettingsText -> fqdn)") $colors

    #Done
    Write-Host("Done") $colors
    $endTime = Get-Date
    $elapsedTime = New-Timespan –Start $startTime –End $endTime

    Write-Host("End Time: " + $endTime) $colors
    Write-Host("Elapsed Time: " + $elapsedTime) $colors
    Write-Host "Press any key to continue ..." $colors

    $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

    Stop-Transcript