I was recently part of a project to deploy SharePoint and Office Online Server (OOS) to Azure IaaS as part of a hybrid deployment. A requirement was to make the SharePoint available to the Internet in addition to the OOS (enabling editing of documents/previews online).
The deployment was very simple, 3 VMs were deployed to a subnet that has connectivity to an existing AD:
- SQL Server – 10.244.3.68
- SharePoint Server – 10.244.3.69, alias record sharepoint.onemtcqa.net
- OOS Server – 10.244.3.70, alias oos.onemtcqa.net
The alias records were created on the internal DNS and external DNS, a split-brain DNS. We also had a wildcard certificate for onemtcqa.net which we could therefore use for https for both sites.
Azure has two built-in load balancer solutions (with more available through 3rd party solutions and virtual appliances).
- The layer 4 Azure Load Balancer which could have been used by configuring the front-end as a public IP and supports any protocol
- The layer 7 Azure Application Gateway that in addition to providing capabilities like SSL offload and cookie based affinity also has the optional Web Application Firewall to provide additional protection. More information on the Application Gateway can be found at https://docs.microsoft.com/en-us/azure/application-gateway/application-gateway-introduction. The front-end IP can be internal or public and the back end can load balance to multiple targets (like the layer 4 load balancer option).
Because the services being published were HTTP based, it made sense to utilize the Azure Application Gateway and would provide a great reason to get hands on with the technology. Additionally the added protection via the WAF was a huge benefit.
There are various SKU sizes available for the Azure Application Gateway along with the choice of Standard or WAF integration. Information on the sizes and pricing can be found at https://azure.microsoft.com/en-us/pricing/details/application-gateway/. I used the Medium size which is the smallest possible when using the WAF tier.
There are a number of settings related to the App Gateway which all relate to each other in a specific manner which provides the complete solution. A single App Gateway can publish multiple sites which meant I only needed a single App Gateway instance with a single public IP for both the sites I needed to publish.
Below is a basic picture of the key components related to an App Gateway that I put together to aid in my own understanding! The arrows show directions of link, so the Rule links to three other items which really bind everything together.
When deploying the Application Gateway through the portal there are some initial configurations:
- The SKU
- The virtual network it will connect to and you must specify an empty subnet that can only be populated by App Gateway resources. This should be at least a /29
- The front end IP and if a public IP is created it must be dynamic and cannot have a custom DNS name
- If the listener is HTTP or HTTPs and the port
Note, if using a public IP, because it is dynamic and cannot have a custom DNS name you can check its actual DNS name using PowerShell and then create an alias on the Internet to that DNS name. Use Get-AzureRmPublicIPAddress and use the DnsSettings.Fqdn attribute. For example:
(Get-AzureRmPublicIpAddress -Name HybridInfraAppGatewayQA -ResourceGroupName onemtcqa-exphybridinfra_rg |
Select-Object -ExpandProperty DnsSettings).Fqdn
The name will be <GUID>.cloudapp.net. I created two alias records, sharepoint and oos, both pointing to this name on the public DNS servers.
Once created we need to tweak some things from those created by the portal wizard.
The virtual subnet that is used for the App Gateway needs its NSG modified as some additional ports must be opened from the Any source to the Virtual Network (this is in addition to the AzureLoadBalancer default inbound rule). Add an inbound rule to allow 65503-65534 TCP from Any to VirtualNetwork. Note this only needs to be enabled on the NSG applied to the Application Gateways subnet and NOT the subnets containing the actual back-end resources. Also ensure the Application Gateway subnet can communicate with the subnets hosting the services.
By default the built-in probe that checks if a backend target is healthy and a possible target for traffic looks for a response between 200 and 399 as a healthy response (per https://docs.microsoft.com/en-us/azure/application-gateway/application-gateway-probe-overview) however for the SharePoint site this won’t work as it prompts for authentication so we need to create a custom probe on HTTPS which accepts 200-401. This can be done with PowerShell (I’m using the internal DNS name here which is the same as external):
$gw = Get-AzureRmApplicationGateway -Name HybridInfraAppGatewayQA -ResourceGroupName onemtcqa-exphybridinfra_rg
# Define the status codes to match for the probe
$match=New-AzureRmApplicationGatewayProbeHealthResponseMatch -StatusCode 200-401
# Add a new probe to the application gateway
Add-AzureRmApplicationGatewayProbeConfig -name AppGatewaySPProbe -ApplicationGateway $gw -Protocol Https -Path / -Interval 30 -Timeout 120 -UnhealthyThreshold 3 -Match $match -HostName sharepoint.onemtcqa.net
Set-AzureRmApplicationGateway -ApplicationGateway $gw
Open the HTTP Settings object, ensure it is HTTPS, upload the certificate and select to use a custom probe and select the probe that was just created.
A default listener was created but this can’t be used so instead create a new multi-site listener.
- Use the existing frontend IP configuration and 443 port
- Enter the hostname, e.g. sharepoint.onemtcqa.net
- Protocol is HTTPS
- Use an existing certified or upload a new certificate to use
Open the backend pool and add the internal IP address of the target(s).
The initial default rule created should work which links to the listener created, the backend pool and the HTTP setting that was modified.
If you open the Backend health under Monitoring it should show a status of healthy and you should be able to connect via the external name (that points to the DNS name of the public IP address).
Now the OOS has to be published which does not require authentication which means a different probe must be used which means a different listener and different targets. Even though it will be a different listener its not like old style listeners where only one can listen on a specific port. This is rather just a set of configurations and so multiple 443 listeners can share the same frontend configuration (and therefore public IP).
- Create a new Backend pool with the OOS machines as the target
- Create a new multi-site listener that uses the existing Frontend IP configuration and port with the OOS public hostname, HTTPS and OOS certificate (same if a wildcard or subject alternative names)
- Create a new health probe. Use the OOS internal DNS name, HTTPS and for path use /hosting/discovery
- Create a new HTTP setting that is HTTPS, uses the certificate and uses the new health probe
- Create a new basic rule that uses the new listener, the new backend pool and the new HTTP setting
Click the below to see a large image of the OOS set of additional configurations.
Now your OOS should also be available and working! You have now published two sites through a single Application Gateway.