API management is configured in an VNET.
Similarly, the Developer portal also configured in VNET with public access endpoint enabled via application gateway.
Even after enabling the endpoint of developer portal in public via app gateway the portal fails to load the apis in api listing page in the new developer portal implemented by this repo: https://github.com/Azure/api-management-developer-portal
The management endpoint is not accessible now and below error thrown:
Starting the new developer portal out of Azure GUI, chromes inspection says it cant access the management endpoint. I figured that its port 443 is blocked (or disabled?) in internal vnet mode. The NSG (or no NSG at all) is allowing any/any access on 443.
To fix this issue i referred this bug reply from Microsoft team and enabled the public access for the management endpoint also via app gateway.
You need to allow Internet access to the management endpoint. I suggest that you open an Azure support request, they will be able to walk you through the setup.
Documentation is published here: https://docs.microsoft.com/en-us/azure/api-management/api-management-howto-integrate-internal-vnet-appgateway
Notes from above link:
Combining API Management provisioned in an internal VNET with the Application Gateway frontend enables the following scenarios:
Use the same API Management resource for consumption by both internal consumers and external consumers.
Use a single API Management resource and have a subset of APIs defined in API Management available for external consumers.
Provide a turn-key way to switch access to API Management from the public Internet on and off.
Back-end server pool: This is the internal virtual IP address of the API Management service.
Back-end server pool settings: Every pool has settings like port, protocol, and cookie-based affinity. These settings are applied to all servers within the pool.
Front-end port: This is the public port that is opened on the application gateway. Traffic hitting it gets redirected to one of the back-end servers.
Listener: The listener has a front-end port, a protocol (Http or Https, these values are case-sensitive), and the TLS/SSL certificate name (if configuring TLS offload).
Rule: The rule binds a listener to a back-end server pool.
Custom Health Probe: Application Gateway, by default, uses IP address based probes to figure out which servers in the BackendAddressPool are active. The API Management service only responds to requests with the correct host header, hence the default probes fail. A custom health probe needs to be defined to help application gateway determine that the service is alive and it should forward requests.
Custom domain certificates: To access API Management from the internet, you need to create a CNAME mapping of its hostname to the Application Gateway front-end DNS name. This ensures that the hostname header and certificate sent to Application Gateway that is forwarded to API Management is one APIM can recognize as valid. In this example, we will use two certificates for the backend and for the developer portal.
Create a resource group for Resource Manager.
Create a Virtual Network, subnet, and public IP for the Application Gateway. Create another subnet for API Management.
Create an API Management service inside the VNET subnet created above and ensure you use the Internal mode.
Set up a custom domain name in the API Management service.
Create an Application Gateway configuration object.
Create an Application Gateway resource.
Create a CNAME from the public DNS name of the Application Gateway to the API Management proxy hostname.
In this guide we will also expose the developer portal to external audiences through the Application Gateway. It requires additional steps to create developer portals listener, probe, settings and rules. All details are provided in respective steps.
To prevent Application Gateway WAF from breaking the download of OpenAPI specification in the developer portal, you need to disable the firewall rule
942200 - "Detects MySQL comment-/space-obfuscated injections and backtick termination".
Application Gateway WAF rules, which may break portals functionality include:
942370for the administrative mode
942440for the published portal
Log in to Azure
Authenticate with your credentials.
Select the desired subscription.
$subscriptionId = "00000000-0000-0000-0000-000000000000" # GUID of your Azure subscription Get-AzSubscription -Subscriptionid $subscriptionId | Select-AzSubscription
Create a resource group (skip this step if youre using an existing resource group).
$resGroupName = "apim-appGw-RG" # resource group name $location = "West US" # Azure region New-AzResourceGroup -Name $resGroupName -Location $location
Azure Resource Manager requires that all resource groups specify a location. This is used as the default location for resources in that resource group. Make sure that all commands to create an application gateway use the same resource group.
The following example shows how to create a Virtual Network using Resource Manager.
Assign the address range 10.0.0.0/24 to the subnet variable to be used for Application Gateway while creating a Virtual Network.
$appgatewaysubnet = New-AzVirtualNetworkSubnetConfig -Name "apim01" -AddressPrefix "10.0.0.0/24"
Assign the address range 10.0.1.0/24 to the subnet variable to be used for API Management while creating a Virtual Network.
$apimsubnet = New-AzVirtualNetworkSubnetConfig -Name "apim02" -AddressPrefix "10.0.1.0/24"
Create a Virtual Network named appgwvnet in resource group apim-appGw-RG for the West US region. Use the prefix 10.0.0.0/16 with subnets 10.0.0.0/24 and 10.0.1.0/24.
$vnet = New-AzVirtualNetwork -Name "appgwvnet" -ResourceGroupName $resGroupName -Location $location -AddressPrefix "10.0.0.0/16" -Subnet $appgatewaysubnet,$apimsubnet
Assign a subnet variable for the next steps
$appgatewaysubnetdata = $vnet.Subnets $apimsubnetdata = $vnet.Subnets
The following example shows how to create an API Management service in a VNET configured for internal access only.
Create an API Management Virtual Network object using the subnet $apimsubnetdata created above.
$apimVirtualNetwork = New-AzApiManagementVirtualNetwork -SubnetResourceId $apimsubnetdata.Id
Create an API Management service inside the Virtual Network.
$apimServiceName = "ContosoApi" # API Management service instance name $apimOrganization = "Contoso" # organization name $apimAdminEmail = "email@example.com" # administrator's email address $apimService = New-AzApiManagement -ResourceGroupName $resGroupName -Location $location -Name $apimServiceName -Organization $apimOrganization -AdminEmail $apimAdminEmail -VirtualNetwork $apimVirtualNetwork -VpnType "Internal" -Sku "Developer"
After the above command succeeds refer to DNS Configuration required to access internal VNET API Management service to access it. This step may take more than half an hour.
The new developer portal also requires enabling connectivity to the API Managements management endpoint in addition to the steps below.
Initialize the following variables with the details of the certificates with private keys for the domains. In this example, we will use
$gatewayHostname = "api.contoso.net" # API gateway host $portalHostname = "portal.contoso.net" # API developer portal host $gatewayCertCerPath = "C:\Users\Contoso\gateway.cer" # full path to api.contoso.net .cer file $gatewayCertPfxPath = "C:\Users\Contoso\gateway.pfx" # full path to api.contoso.net .pfx file $portalCertPfxPath = "C:\Users\Contoso\portal.pfx" # full path to portal.contoso.net .pfx file $gatewayCertPfxPassword = "certificatePassword123" # password for api.contoso.net pfx certificate $portalCertPfxPassword = "certificatePassword123" # password for portal.contoso.net pfx certificate $certPwd = ConvertTo-SecureString -String $gatewayCertPfxPassword -AsPlainText -Force $certPortalPwd = ConvertTo-SecureString -String $portalCertPfxPassword -AsPlainText -Force
Create and set the hostname configuration objects for the proxy and for the portal.
$proxyHostnameConfig = New-AzApiManagementCustomHostnameConfiguration -Hostname $gatewayHostname -HostnameType Proxy -PfxPath $gatewayCertPfxPath -PfxPassword $certPwd $portalHostnameConfig = New-AzApiManagementCustomHostnameConfiguration -Hostname $portalHostname -HostnameType DeveloperPortal -PfxPath $portalCertPfxPath -PfxPassword $certPortalPwd $apimService.ProxyCustomHostnameConfiguration = $proxyHostnameConfig $apimService.PortalCustomHostnameConfiguration = $portalHostnameConfig Set-AzApiManagement -InputObject $apimService
To configure the legacy developer portal connectivity you need to replace
-HostnameType DeveloperPortal with
Create a public IP resource publicIP01 in the resource group.
$publicip = New-AzPublicIpAddress -ResourceGroupName $resGroupName -name "publicIP01" -location $location -AllocationMethod Dynamic
An IP address is assigned to the application gateway when the service starts.
All configuration items must be set up before creating the application gateway. The following steps create the configuration items that are needed for an application gateway resource.
Create an application gateway IP configuration named gatewayIP01. When Application Gateway starts, it picks up an IP address from the subnet configured and route network traffic to the IP addresses in the back-end IP pool. Keep in mind that each instance takes one IP address.
$gipconfig = New-AzApplicationGatewayIPConfiguration -Name "gatewayIP01" -Subnet $appgatewaysubnetdata
Configure the front-end IP port for the public IP endpoint. This port is the port that end users connect to.
$fp01 = New-AzApplicationGatewayFrontendPort -Name "port01" -Port 443
Configure the front-end IP with public IP endpoint.
$fipconfig01 = New-AzApplicationGatewayFrontendIPConfig -Name "frontend1" -PublicIPAddress $publicip
Configure the certificates for the Application Gateway, which will be used to decrypt and re-encrypt the traffic passing through.
$cert = New-AzApplicationGatewaySslCertificate -Name "cert01" -CertificateFile $gatewayCertPfxPath -Password $certPwd $certPortal = New-AzApplicationGatewaySslCertificate -Name "cert02" -CertificateFile $portalCertPfxPath -Password $certPortalPwd
Create the HTTP listeners for the Application Gateway. Assign the front-end IP configuration, port, and TLS/SSL certificates to them.
$listener = New-AzApplicationGatewayHttpListener -Name "listener01" -Protocol "Https" -FrontendIPConfiguration $fipconfig01 -FrontendPort $fp01 -SslCertificate $cert -HostName $gatewayHostname -RequireServerNameIndication true $portalListener = New-AzApplicationGatewayHttpListener -Name "listener02" -Protocol "Https" -FrontendIPConfiguration $fipconfig01 -FrontendPort $fp01 -SslCertificate $certPortal -HostName $portalHostname -RequireServerNameIndication true
Create custom probes to the API Management service
ContosoApi proxy domain endpoint. The path
/status-0123456789abcdef is a default health endpoint hosted on all the API Management services. Set
api.contoso.net as a custom probe hostname to secure it with the TLS/SSL certificate.
contosoapi.azure-api.net is the default proxy hostname configured when a service named
contosoapi is created in public Azure.
$apimprobe = New-AzApplicationGatewayProbeConfig -Name "apimproxyprobe" -Protocol "Https" -HostName $gatewayHostname -Path "/status-0123456789abcdef" -Interval 30 -Timeout 120 -UnhealthyThreshold 8 $apimPortalProbe = New-AzApplicationGatewayProbeConfig -Name "apimportalprobe" -Protocol "Https" -HostName $portalHostname -Path "/internal-status-0123456789abcdef" -Interval 60 -Timeout 300 -UnhealthyThreshold 8
Upload the certificate to be used on the TLS-enabled backend pool resources. This is the same certificate which you provided in Step 4 above.
$authcert = New-AzApplicationGatewayAuthenticationCertificate -Name "whitelistcert1" -CertificateFile $gatewayCertCerPath
Configure HTTP backend settings for the Application Gateway. This includes setting a time-out limit for backend request, after which theyre canceled. This value is different from the probe time-out.
$apimPoolSetting = New-AzApplicationGatewayBackendHttpSettings -Name "apimPoolSetting" -Port 443 -Protocol "Https" -CookieBasedAffinity "Disabled" -Probe $apimprobe -AuthenticationCertificates $authcert -RequestTimeout 180 $apimPoolPortalSetting = New-AzApplicationGatewayBackendHttpSettings -Name "apimPoolPortalSetting" -Port 443 -Protocol "Https" -CookieBasedAffinity "Disabled" -Probe $apimPortalProbe -AuthenticationCertificates $authcert -RequestTimeout 180
Configure a back-end IP address pool named apimbackend with the internal virtual IP address of the API Management service created above.
$apimProxyBackendPool = New-AzApplicationGatewayBackendAddressPool -Name "apimbackend" -BackendIPAddresses $apimService.PrivateIPAddresses
Create rules for the Application Gateway to use basic routing.
$rule01 = New-AzApplicationGatewayRequestRoutingRule -Name "rule1" -RuleType Basic -HttpListener $listener -BackendAddressPool $apimProxyBackendPool -BackendHttpSettings $apimPoolSetting $rule02 = New-AzApplicationGatewayRequestRoutingRule -Name "rule2" -RuleType Basic -HttpListener $portalListener -BackendAddressPool $apimProxyBackendPool -BackendHttpSettings $apimPoolPortalSetting
Change the -RuleType and routing, to restrict access to certain pages of the developer portal.
Configure the number of instances and size for the Application Gateway. In this example, we are using the WAF SKU for increased security of the API Management resource.
$sku = New-AzApplicationGatewaySku -Name "WAF_Medium" -Tier "WAF" -Capacity 2
Configure WAF to be in Prevention mode.
$config = New-AzApplicationGatewayWebApplicationFirewallConfiguration -Enabled $true -FirewallMode "Prevention"
Create an Application Gateway with all the configuration objects from the preceding steps.
$appgwName = "apim-app-gw" $appgw = New-AzApplicationGateway -Name $appgwName -ResourceGroupName $resGroupName -Location $location -BackendAddressPools $apimProxyBackendPool -BackendHttpSettingsCollection $apimPoolSetting, $apimPoolPortalSetting -FrontendIpConfigurations $fipconfig01 -GatewayIpConfigurations $gipconfig -FrontendPorts $fp01 -HttpListeners $listener, $portalListener -RequestRoutingRules $rule01, $rule02 -Sku $sku -WebApplicationFirewallConfig $config -SslCertificates $cert, $certPortal -AuthenticationCertificates $authcert -Probes $apimprobe, $apimPortalProbe
Once the gateway is created, the next step is to configure the front end for communication. When using a public IP, Application Gateway requires a dynamically assigned DNS name, which may not be easy to use.
The Application Gateways DNS name should be used to create a CNAME record which points the APIM proxy host name (e.g.
api.contoso.net in the examples above) to this DNS name. To configure the frontend IP CNAME record, retrieve the details of the Application Gateway and its associated IP/DNS name using the PublicIPAddress element. The use of A-records is not recommended since the VIP may change on restart of gateway.
Get-AzPublicIpAddress -ResourceGroupName $resGroupName -Name "publicIP01"