Migrate Spring Cloud applications to Azure Spring Apps

Note

Azure Spring Apps is the new name for the Azure Spring Cloud service. Although the service has a new name, you'll see the old name in some places for a while as we work to update assets such as screenshots, videos, and diagrams.

This guide describes what you should be aware of when you want to migrate an existing Spring Cloud application to run on Azure Spring Apps.

Pre-migration

To ensure a successful migration, before you start, complete the assessment and inventory steps described in the following sections.

If you can't meet any of these pre-migration requirements, see the following companion migration guides:

  • Migrate executable JAR applications to containers on Azure Kubernetes Service (guidance planned)
  • Migrate executable JAR Applications to Azure Virtual Machines (guidance planned)

Inspect application components

Determine whether and how the file system is used

Find any instances where your services write to and/or read from the local file system. Identify where short-term/temporary files are written and read and where long-lived files are written and read.

Note

Azure Spring Apps provides 5 GB of temporary storage per Azure Spring Apps instance, mounted in /tmp. If temporary files are written in excess of that limit or into a different location, code changes will be required.

Read-only static content

If your application currently serves static content, you'll need an alternate location for it. You may wish to consider moving static content to Azure Blob Storage and adding Azure CDN for lightning-fast downloads globally. For more information, see Static website hosting in Azure Storage and Quickstart: Integrate an Azure storage account with Azure CDN.

Dynamically published static content

If your application allows for static content that is uploaded/produced by your application but is immutable after its creation, you can use Azure Blob Storage and Azure CDN as described above, with an Azure Function to handle uploads and CDN refresh. We've provided a sample implementation for your use at Uploading and CDN-preloading static content with Azure Functions.

Determine whether any of the services contain OS-specific code

If your application contains any code with dependencies on the host OS, then you'll need to refactor it to remove those dependencies. For example, you may need to replace any use of / or \ in file system paths with File.Separator or Paths.get.

Switch to a supported platform

Azure Spring Apps offers specific versions of Java and specific versions of Spring Boot and Spring Cloud. To ensure compatibility, first migrate your application to one of the supported versions of Java in its current environment, then proceed with the remaining migration steps. Be sure to fully test the resulting configuration. Use the latest stable release of your Linux distribution in such tests.

Note

This validation is especially important if your current server is running on an unsupported JDK (such as Oracle JDK or IBM OpenJ9).

To obtain your current Java version, sign in to your production server and run the following command:

java -version

For supported versions of Java, Spring Boot, and Spring Cloud, as well instructions for updating, see Prepare an application for deployment in Azure Spring Apps.

Identify Spring Boot versions

Examine the dependencies of each application being migrated to determine its Spring Boot version.

Maven

In Maven projects, the Spring Boot version is typically found in the <parent> element of the POM file:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.10</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
Gradle

In Gradle projects, the Spring Boot version will typically be found in the plugins section, as the version of the org.springframework.boot plugin:

plugins {
  id 'org.springframework.boot' version '2.7.10'
  id 'io.spring.dependency-management' version '1.0.15.RELEASE'
  id 'java'
}

For any applications using Spring Boot 1.x, follow the Spring Boot 2.0 migration guide to update them to a supported Spring Boot version. For supported versions, see the Spring Boot and Spring Cloud versions section of Prepare an application for deployment in Azure Spring Apps.

Identify Spring Cloud versions

Examine the dependencies of each application you're migrating to determine the version of the Spring Cloud components it uses.

Maven

In Maven projects, the Spring Cloud version is typically set in the spring-cloud.version property:

  <properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>2021.0.6</spring-cloud.version>
  </properties>
Gradle

In Gradle projects, the Spring Cloud version is typically set in the "extra properties" block:

ext {
  set('springCloudVersion', "2021.0.6")
}

You need to update all applications to use supported versions of Spring Cloud. For a list of supported versions, see the Spring Boot and Spring Cloud versions section of Prepare an application for deployment in Azure Spring Apps.

Identify log aggregation solutions

Identify any log aggregation solutions in use by the applications you're migrating. You need to configure diagnostic settings in migration to make logged events available for consumption. For more information, see the Ensure console logging and configure diagnostic settings section.

Identify application performance management (APM) agents

Identify any application performance monitoring agents in use with your applications. Azure Spring Apps supports integration with Application Insights, New Relic, Elastic APM, Dynatrace, and AppDynamics. If the application is using a supported APM, configure the integration in migration. If the application isn't using a supported APM, consider using Application Insights instead. For more information, see the Migration section.

Identify Zipkin dependencies

Determine whether your application has dependencies on Zipkin. Update the application to use Application Insights instead. For information, see Use Application Insights Java In-Process Agent in Azure Spring Apps and the Post-migration section.

Inventory external resources

Identify external resources, such as data sources, JMS message brokers, and URLs of other services. In Spring Cloud applications, you can typically find the configuration for such resources in one of the following locations:

  • In the src/main/directory folder, in a file typically called application.properties or application.yml.
  • In the Spring Cloud Config repository that you identified in the previous step.

Databases

For any SQL database, identify the connection string.

For a Spring Boot application, connection strings typically appear in configuration files.

Here's an example from an application.properties file:

spring.datasource.url=jdbc:mysql://localhost:3306/mysql_db
spring.datasource.username=dbuser
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

Here's an example from an application.yaml file:

spring:
  data:
    mongodb:
      uri: mongodb://mongouser:deepsecret@mongoserver.contoso.com:27017

See Spring Data documentation for more possible configuration scenarios:

JMS message brokers

Identify the broker or brokers in use by looking in the build manifest (typically, a pom.xml or build.gradle file) for the relevant dependencies.

For example, a Spring Boot application using ActiveMQ would typically contain this dependency in its pom.xml file:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-activemq</artifactId>
</dependency>

Spring Boot applications using commercial brokers typically contain dependencies directly on the brokers' JMS driver libraries. Here's an example from a build.gradle file:

    dependencies {
      ...
      compile("com.ibm.mq:com.ibm.mq.allclient:9.0.4.0")
      ...
    }

After you've identified the broker or brokers in use, find the corresponding settings. In Spring Cloud applications, you can typically find them in the application.properties and application.yml files in the application directory, or in the Spring Cloud Config server repository.

Here's an ActiveMQ example from an application.properties file:

spring.activemq.brokerurl=broker:(tcp://localhost:61616,network:static:tcp://remotehost:61616)?persistent=false&useJmx=true
spring.activemq.user=admin
spring.activemq.password=tryandguess

For more information on ActiveMQ configuration, see the Spring Boot messaging documentation.

Here's an IBM MQ example from an application.yaml file:

ibm:
  mq:
    queueManager: qm1
    channel: dev.ORDERS
    connName: localhost(14)
    user: admin
    password: big$ecr3t

For more information on IBM MQ configuration, see the IBM MQ Spring components documentation.

Identify external caches

Identify any external caches in use. Frequently, Redis is used via Spring Data Redis. For configuration information, see the Spring Data Redis documentation.

Determine whether session data is being cached via Spring Session by searching for the respective configuration (in Java or XML).

Identity providers

Identify all identity providers and all Spring Cloud applications that require authentication and/or authorization. For information on how you can configure identity providers, see the following resources:

Resources configured through VMware Tanzu Application Service (TAS) (formerly Pivotal Cloud Foundry)

For applications managed with TAS, external resources, including the resources described earlier, are often configured via TAS service bindings. To examine the configuration for such resources, use the TAS (Cloud Foundry) CLI to view the VCAP_SERVICES variable for the application.

# Log into TAS, if needed (enter credentials when prompted)
cf login -a <API endpoint>

# Set the organization and space containing the application, if not already selected during login.
cf target org <organization name>
cf target space <space name>

# Display variables for the application
cf env <Application Name>

Examine the VCAP_SERVICES variable for configuration settings of external services bound to the application. For more information, see the TAS (Cloud Foundry) documentation.

All other external resources

It isn't feasible for this guide to document every possible external dependency. After the migration, it's your responsibility to verify that you can satisfy every external dependency of your application.

Inventory configuration sources and secrets

Inventory passwords and secure strings

Check all properties and configuration files and all environment variables on the production deployment(s) for any secret strings and passwords. In a Spring Cloud application, you can typically find such strings in the application.properties or application.yml file in individual services or in the Spring Cloud Config repository.

Inventory certificates

Document all the certificates used for public SSL endpoints or communication with backend databases and other systems. You can view all certificates on the production server(s) by running the following command:

keytool -list -v -keystore <path to keystore>

Determine whether Spring Cloud Vault is used

If you use Spring Cloud Vault to store and access secrets, identify the backing secret store (for example, HashiCorp Vault or CredHub). Then identify all the secrets used by the application code.

Locate the configuration server source

If your application uses a Spring Cloud Config server, identify where the configuration is stored. You'll typically find this setting in the bootstrap.yml or bootstrap.properties file, or sometimes in the application.yml or application.properties file. The setting will look like the following example:

spring.cloud.config.server.git.uri: file://${user.home}/spring-cloud-config-repo

While git is most commonly used as Spring Cloud Config's backing datastore, as shown earlier, one of the other possible backends may be in use. Consult the Spring Cloud Config documentation for information on other backends, such as Relational Database (JDBC), SVN, and the local file system.

Note

If your configuration server data is stored on premises, such as GitHub Enterprise, you'll need to make it available to Azure Spring Apps via a Git repository.

Inspect the deployment architecture

Document hardware requirements for each service

For each of your Spring Cloud services (not including the configuration server, registry, or gateway), document the following information:

  • The number of instances running.
  • The number of CPUs allocated to each instance.
  • The amount of RAM allocated to each instance.

Document geo-replication/distribution

Determine whether the Spring Cloud applications are currently distributed among several regions or data centers. Document the uptime requirements/SLA for the applications you're migrating.

Identify clients that bypass the service registry

Identify any client applications that invoke any of the services to be migrated without using the Spring Cloud Service Registry. After the migration, such invocations will no longer be possible. Update such clients to use Spring Cloud OpenFeign before migration.

Migration

Remove restricted configurations

In the services you’re migrating, find and remove any explicit assignments of the following restricted settings. These properties are automatically injected into your application environment to access Config Server and Service Discovery. If these properties are in your Config Server application files, you might experience conflicts and unexpected behavior. For more information, see the Restriction section of Configure a managed Spring Cloud Config Server in Azure Spring Apps

  • eureka.client.service-url.defaultZone
  • eureka.client.tls.keystore
  • eureka.instance.preferIpAddress
  • eureka.instance.instance-id
  • server.port
  • spring.cloud.config.tls.keystore
  • spring.config.import
  • spring.application.name
  • spring.jmx.enabled
  • management.endpoints.jmx.exposure.include

Create an Azure Spring Apps instance and apps

Provision an Azure Spring Apps instance in your Azure subscription. Then, provision an app for every service you're migrating. Don't include the Spring Cloud registry and configuration servers. Do include the Spring Cloud Gateway service. For instructions, see Quickstart: Deploy your first application to Azure Spring Apps.

Prepare the Spring Cloud Config server

Configure the configuration server in your Azure Spring Apps instance. For more information, see Set up a Spring Cloud Config Server instance for your service.

Note

If your current Spring Cloud Config repository is on the local file system or on premises, you first need to migrate or replicate your configuration files to a private cloud-based repository, such as GitHub, Azure Repos, or BitBucket.

Ensure console logging and configure diagnostic settings

Configure your logging so that all output is routed to the console and not to files.

After an application is deployed to Azure Spring Apps, add a diagnostic setting to make logged events available for consumption, for example via Azure Monitor Log Analytics.

LogStash/ELK Stack

If you use LogStash/ELK Stack for log aggregation, configure the diagnostic setting to stream the console output to an Azure Event Hub. Then, use the LogStash EventHub plugin to ingest logged events into LogStash.

Splunk

If you use Splunk for log aggregation, configure the diagnostic setting to stream the console output to Azure Blob Storage. Then, use the Splunk Add-on for Microsoft Cloud Services to ingest logged events into Splunk.

Configure persistent storage

If any part of your application reads or writes to the local file system, you'll need to configure persistent storage to replace the local file system. For more information, see Use built-in persistent storage in Azure Spring Apps.

You should write any temporary files to the /tmp directory. For OS independence, you can get this directory by using System.getProperty("java.io.tmpdir"). You can also use java.nio.Files::createTempFile to create temporary files.

VMware Tanzu components

In Enterprise tier, Application Configuration Service for VMware Tanzu® is provided to support externalized configuration for your apps. Managed Spring Cloud Config Server isn't available in Enterprise tier and is only available in Standard and Basic tier of Azure Spring Apps.

Application Configuration Service for Tanzu

Application Configuration Service for Tanzu is one of the commercial VMware Tanzu components. Application Configuration Service for Tanzu is Kubernetes-native, and different from Spring Cloud Config Server. Application Configuration Service for Tanzu enables the management of Kubernetes-native ConfigMap resources that are populated from properties defined in one or more Git repositories.

In Enterprise tier, there's no Spring Cloud Config Server, but you can use Application Configuration Service for Tanzu to manage centralized configurations. For more information, see Use Application Configuration Service for Tanzu

To use Application Configuration Service for Tanzu, do the following steps for each of your apps:

  1. Add an explicit app binding to declare that your app needs to use Application Configuration Service for Tanzu.

    Note

    When you change the bind/unbind status, you must restart or redeploy the app to make the change take effect.

  2. Set config file patterns. Config file patterns enable you to choose which application and profile the app uses. For more information, see the Pattern section of Use Application Configuration Service for Tanzu.

    Another option is to set the config file patterns at the same time as your app deployment, as shown in the following example:

    az spring app deploy \
        --name <app-name> \
        --artifact-path <path-to-your-JAR-file> \
        --config-file-pattern <config-file-pattern>
    

Application Configuration Service for Tanzu runs on Kubernetes. To help enable a transparent local development experience, we provide the following suggestions.

  • If you already have a Git repository to store your externalized configuration, you can set up Spring Cloud Config Server locally as the centralized configuration for your application. After Config Server starts, it clones the Git repository and provides the repository content through its web controller. For more information, see Spring Cloud Config in the Spring documentation. The spring-cloud-config-client provides the ability for your application to automatically pick up the external configuration from the Config Server.

  • If you don't have a Git repository or you don't want to set up Config Server locally, you can use the configuration file directly in your project. We recommend that you use a profile to isolate the configuration file so that it's used only in your development environment. For example, use dev as the profile. Then, you can create an application-dev.yml file in the src/main/resource folder to store the configuration. To get your app to use this configuration, start the app locally with --spring.profiles.active=dev.

Tanzu Service Registry

VMware Tanzu® Service Registry is one of the commercial VMware Tanzu components. Tanzu Service Registry provides your Enterprise-tier apps with an implementation of the Service Discovery pattern, one of the key tenets of a microservice-based architecture. Your apps can use Tanzu Service Registry to dynamically discover and call registered services. Using Tanzu Service Registry is preferable to hand-configuring each client of a service, which can be difficult, or adopting some form of access convention, which can be brittle in production. For more information, see Use Tanzu Service Registry.

Migrate Spring Cloud Vault secrets to Azure KeyVault

You can inject secrets directly into applications through Spring by using the Azure KeyVault Spring Boot Starter. For more information, see How to use the Spring Boot Starter for Azure Key Vault.

Note

Migration may require you to rename some secrets. Update your application code accordingly.

Migrate all certificates to KeyVault

Azure Spring Apps doesn't provide access to the JRE keystore, so you must migrate certificates to Azure KeyVault, and change the application code to access certificates in KeyVault. For more information, see Get started with Key Vault certificates and Azure Key Vault Certificate client library for Java.

Configure application performance management (APM) integrations

Azure Spring Apps offers the following APM integrations. Follow the links to enable the APM you need:

If your application isn't using a supported APM, consider using Application Insights instead. Azure Spring Apps offers deep integration with Application Insights for performance management and real-time response to aberrations.

Disable metrics clients and endpoints in your applications

Remove any metrics clients used or any metrics endpoints exposed in your applications.

Deploy the services

Deploy each of the migrated Spring apps (not including the Spring Cloud Config and Registry servers), as described in Quickstart: Deploy your first application to Azure Spring Apps.

Configure per-service secrets and externalized settings

You can inject any per-service configuration settings into each service as environment variables. Use the following steps in the Azure portal:

  1. Navigate to the Azure Spring Apps Instance and select Apps.
  2. Select the service to configure.
  3. Select Configuration.
  4. Enter the variables to configure.
  5. Select Save.

Spring Cloud App Configuration Settings

Migrate and enable the identity provider

If any of the Spring Cloud applications require authentication or authorization, ensure they're configured to access the identity provider:

  • If the identity provider is Microsoft Entra ID, no changes should be necessary.
  • If the identity provider is an on-premises Active Directory forest, consider implementing a hybrid identity solution with Microsoft Entra ID. For guidance, see the Hybrid identity documentation.
  • If the identity provider is another on-premises solution, such as PingFederate, consult the Custom installation of Microsoft Entra Connect topic to configure federation with Microsoft Entra ID. Alternatively, consider using Spring Security to use your identity provider through OAuth2/OpenID Connect or SAML.

Update client applications

Update the configuration of all client applications to use the published Azure Spring Apps endpoints for migrated applications.

Post-migration

  • Consider adding a deployment pipeline for automatic, consistent deployments. Instructions are available for Azure Pipelines, for GitHub Actions, and for Jenkins.

  • Consider using staging deployments to test code changes in production before they're available to some or all of your end users. For more information, see Set up a staging environment in Azure Spring Apps.

  • Consider adding service bindings to connect your application to supported Azure databases. These service bindings would eliminate the need for you to provide connection information, including credentials, to your Spring Cloud applications.

  • Consider using Azure Application Insights to monitor performance and interactions of your applications. For more information, see Application Insights Java In-Process Agent in Azure Spring Apps.

  • Consider adding Azure Monitor alert rules and action groups to quickly detect and address aberrant conditions. For more information, see Tutorial: Monitor Spring Cloud resources using alerts and action groups.

  • Consider replicating the Azure Spring Apps deployment in another region for lower latency and higher reliability and fault tolerance. Use Azure Traffic Manager to load balance among deployments or use Azure Front Door to add SSL offloading and Web Application Firewall with DDoS protection.

  • If geo-replication isn't necessary, consider adding an Azure Application Gateway to add SSL offloading and Web Application Firewall with DDoS protection.

  • If your applications use legacy Spring Cloud Netflix components, consider replacing them with current alternatives:

    Legacy Current
    Spring Cloud Eureka Spring Cloud Service Registry
    Spring Cloud Netflix Zuul Spring Cloud Gateway
    Spring Cloud Netflix Archaius Spring Cloud Config Server
    Spring Cloud Netflix Ribbon Spring Cloud Load Balancer (client-side load balancer)
    Spring Cloud Hystrix Spring Cloud Circuit Breaker + Resilience4J
    Spring Cloud Netflix Turbine Micrometer + Prometheus