Blog Post

Apps on Azure Blog
6 MIN READ

How to expose Internal Azure Spring Apps with VNet Injection to the Internet

wanjing's avatar
wanjing
Icon for Microsoft rankMicrosoft
Jun 05, 2023

When an Azure Spring Apps service instance is deployed in your virtual network (VNET), applications on the service instance are only accessible within the private network. To make these applications accessible on the Internet, there are several options available.

 

In this article, we will discuss these methods and provide a comprehensive guide on how to set them up from start to finish.

 

Prerequisites

 

1. Deploy an ASA instance in VNet following: https://learn.microsoft.com/en-us/azure/spring-apps/how-to-deploy-in-azure-virtual-network?tabs=azure-portal.

2. Create an Azure Private DNS Zone in your subscription to translate/resolve the private fully qualified domain name (FQDN) to its IP address following: https://learn.microsoft.com/en-us/azure/spring-apps/access-app-virtual-network?tabs=azure-portal

 

After completing the above configurations, the app is now accessible from your VNet. You can assign an endpoint to the Spring app and test it on a jump box machine inside the VNet. The app should be accessible via the URL: https://instancename-appname.private.azuremicroservices.io.

 

Now, to access the application from the internet, you have 3 options:

  1. Utilize the Azure Spring Apps public endpoint.
  2. Implement an application gateway with the default domain.
  3. Implement an application gateway with a custom domain.

 

Option1: Utilize the Azure Spring Apps public endpoint.

An Azure Spring App public endpoint is designed to expose applications on Azure Spring Apps to the internet from a public network. You can expose your applications to the internet with one click using the Azure portal or Azure CLI. The only extra expense is a standard public IP for one Azure Spring Apps service instance, regardless of how many apps you want to expose. For more details, please refer to: https://learn.microsoft.com/en-us/azure/spring-apps/how-to-access-app-from-internet-virtual-network?tabs=azure-portal

 

 

Option2: Implement an application gateway with the default domain.

If you do not have a custom domain and SSL certificate, but still wish to test the accessibility of your Spring app using the default domain, you can follow the steps outlined below. However, it is important to note that this approach is only recommended for testing purposes and should not be used for a production environment.

 

To proceed with the setup, start by following the instructions provided in the App Service and Application Gateway document to configure the backend pools, backend settings, and listeners. You can access the guide from this link: https://learn.microsoft.com/en-us/azure/application-gateway/configure-web-app?tabs=defaultdomain%2Cazure-portal. Be sure to carefully follow each step to ensure that the setup is completed correctly.

 

1. Backend pools - use the FQDN of ASA: <service-name>-<appname>.private.azuremicroservices.io.

2. Backend settings:

  • Port: 443
  • Use Well-Known CA Certificate: yes
  • Override with Specific Domain Name: <service-name>-<appname>.private.azuremicroservices.io

3. Listeners - Assuming there is no custom domain available or associated certificate, we will configure the Application Gateway to listen for HTTP traffic on port 80.

4. Create a rule that combines the Listeners, Backend Pools, and Backend Settings together.

5. After completing the above configurations, if you attempt to access the Application Gateway's public IP through HTTP, you will encounter a 308 permanent redirection error. This is because instead of forwarding the request to your Spring app from the Application Gateway, it redirects you directly to the Spring app's private URL, which is not accessible from the public internet.

 

After conducting research and tests, I discovered that the root cause of the 308 permanent redirection error on the Spring app's default domain is due to two main factors:

  • The Application Gateway is sending the request to the Spring app's port 80, instead of using the desired port 443 as set up in the backend settings.
  • The Spring app's default domain does not support HTTP on port 80, and instead redirects to HTTPS on port 443. As a result, the Spring app returns a 308 permanent redirection status.
  • It is important to note that the HTTPS-only setting for Spring apps under custom domains does not apply to the Spring app's default domain.

      

 

The application gateway inserts six additional headers to all requests before forwarding them to the backend: x-forwarded-for, x-forwarded-port, x-forwarded-proto, x-original-host, x-original-url, and x-appgw-trace-id. The valid values for x-forwarded-proto are HTTP or HTTPS, and x-forwarded-port specifies the port where the request reached the application gateway.

 

Since we connect to the application gateway using HTTP and port 80, the request forwarded to the Spring app has headers x-forwarded-proto set to HTTP and x-forwarded-port set to 80. Even if the traffic is with HTTPS and port 443, the spring app misunderstands the request due to incorrect values in the headers.

 

To resolve this issue, we need to enforce the application gateway to use port 443 and HTTPS when communicating with the Spring app by overwriting the headers.

  •  In application gateway, add a rewrite rule.
  •  Associate the rewrite with the rule we set previously for backend pools, backend settings and Listeners.

     

  • Add 2 rule configurations to rewrite x-forwarded-proto set to HTTPS and x-forwarded-port set to 443.

    

Now you should be able to access the spring app via application gateway public IP address!

 

Option3: Implement an application gateway with a custom domain.

If you have a valid custom domain and SSL certificate signed by a well-known trusted CA, you can proceed with the following steps. However, if you are using a self-signed certificate with a custom domain, there are certain additional considerations to be aware of.

 

To begin the setup process, ensure that you have properly prepared your self-signed certificate by including the root, intermediate and client certificates in the certificate chain with the same hostname as your custom domain. You can refer to the following link for more details : https://learn.microsoft.com/EN-US/azure/spring-apps/tutorial-custom-domain?tabs=Azure-portal#prepare-your-certificate-file-in-pfx-optional.

  1. Merge the root certificate, middle certificate, and client certificate into a PFX file.

  2. Import the PFX file certificate into Azure Key Vault.

  3. Grant Azure Spring Apps access to your Key Vault.

  4. Import the certificate from Azure Key Vault to your Spring app.

  5. Add a custom domain to your Spring app.

  6. Go to your DNS provider and add a CNAME record to map your domain to <service-name>-<appname>.private.azuremicroservices.io. If this is a custom domain created for testing purposes, you can add the CNAME record in Azure Private DNS zone.

  7. Add an SSL binding to your Spring app.

     

After the operation is complete, you will be able to access your Spring app using a custom domain from the Virtual Network (VNet).

 

Then the same configuration needs to be applied to the Application Gateway. It is important to note that if you are using a self-signed certificate in the backend settings of your Application Gateway, you will need to select "No" for "Use well-known CA certificate" and upload the root certificate(.cer) that was merged into the PFX file in the previous step, under "Trusted root certificate".

In the "Host name" section, make sure to select "Override with specific domain name" and ensure that the hostname matches the one specified in the SSL certificate.

In the "Listeners" settings, add a new listener on port 443 and select the existing certificate with the merged certificate.

For testing purposes, edit your Windows host file and add a record to map the custom domain with the Application Gateway's public IP address. Or if you owned this domain, you could add a A record on domain provider to point to Application Gateway's public IP to make it work.

 

Once this is done, you will be able to access your Spring app with the custom domain from a public network. Enjoy!

 

Reference doc: https://learn.microsoft.com/en-us/azure/spring-apps/expose-apps-gateway-tls-termination?tabs=azure-cli

 

 

Updated Jun 05, 2023
Version 1.0

2 Comments

  • hi Faisal1775 , thanks a lot for the summarize. 

     

    I just want to dig deeper on configurations regarding implementing "Application Gateway" section. My customer was facing lot of different issues when trying these implementations, I just want to list them out so if anyone is facing the same issue, they can find the solution.

  • Faisal1775's avatar
    Faisal1775
    Brass Contributor

    To expose internal Azure Spring apps with VNet injection to the internet, you can follow these general steps:

    1. Set up VNet integration: Ensure that your Azure Spring Cloud service is integrated with a virtual network (VNet). This enables the communication between the app and resources within the VNet.

    2. Configure network security groups (NSGs): NSGs allow you to control inbound and outbound network traffic to your Azure Spring Cloud service. Configure appropriate NSG rules to allow inbound traffic from the internet to the necessary ports used by your application.

    3. Set up an Application Gateway or Load Balancer: To expose your internal app to the internet, you can use Azure Application Gateway or Azure Load Balancer. These services act as a reverse proxy, forwarding incoming internet traffic to your app.

      a. Configure the Application Gateway or Load Balancer to receive traffic on a public IP address or a custom domain.

      b. Create a backend pool that points to the internal IP address or hostname of your Azure Spring Cloud app.

      c. Define a frontend listener and associate it with the public IP address or custom domain.

      d. Set up routing rules to route incoming traffic to the appropriate backend pool.

    4. Configure DNS settings: If you're using a custom domain, ensure that the DNS settings for your domain are correctly configured to point to the public IP address or custom domain associated with your Application Gateway or Load Balancer.

    5. Test connectivity: After completing the configuration, test the connectivity by accessing your app using the public IP address or custom domain. Ensure that traffic is correctly routed from the internet to your Azure Spring Cloud app within the VNethttps://seocompanyscottsdaleaz.com/

    It's important to note that the specific steps and configuration details may vary depending on the exact setup of your Azure environment, such as the choice between Application Gateway or Load Balancer. It's recommended to refer to the official Microsoft Azure documentation and relevant Azure Spring Cloud documentation for detailed instructions and best practices based on your specific requirements.