我需要在内部VNET中将Azure API Management与Application Gateway集成。我使用了Microsoft的手册: Integrate API Management in an internal VNET with Application Gateway
我使用自签名证书进行自定义域名。
以下是带有Application Gateway的内部VNET中的API Management图
我根据以下手册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实例未响应默认运行状况探测。
自定义运行状况探测的配置无效或不正确。请求超时或用户请求的连接问题。
我的问题是
答案 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,#2和Integrate API Management in an internal VNET with Application Gateway手册现已更新。
答案 1 :(得分:1)
答案 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