Migrate Spring Cloud applications to Azure Spring Cloud

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

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 Cloud provides 5 GB of temporary storage per Azure Spring Cloud 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 Cloud 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 a Java Spring application for deployment in Azure Spring Cloud.

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.2.6.RELEASE</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.2.6.RELEASE'
  id 'io.spring.dependency-management' version '1.0.9.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 Prepare a Java Spring app for deployment.

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>Hoxton.SR3</spring-cloud.version>
  </properties>
Gradle

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

ext {
  set('springCloudVersion', "Hoxton.SR3")
}

You'll need to update all applications to use supported versions of Spring Cloud. For a list of supported versions, see Prepare a Java Spring app for deployment.

Identify log aggregation solutions

Identify any log aggregation solutions in use by the applications you are migrating.

Identify application performance management (APM) agents

Identify any application performance monitoring agents in use with your applications (such as Dynatrace and Datadog). In place of such agents, Azure Spring Cloud offers deep integration with Azure Monitor for performance management and real-time response to aberrations. For more information, see Post-migration.

Identify Zipkin dependencies

Determine whether your application has explicit dependencies on Zipkin. Look for dependencies on the io.zipkin.java group in your Maven or Gradle dependencies.

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 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 proprietary 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 identity providers may be configured, consult the following:

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 Cloud 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 explicit configuration server settings

In the services you're migrating, find any explicit assignments of Eureka settings and remove them. Such settings typically appear in application.properties or application.yml files:

application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://myusername:mysecretpassword@localhost:8761/eureka/

If a setting like this appears in your application configuration, remove it. Azure Spring Cloud will automatically inject the connection information of its configuration server.

Create an Azure Spring Cloud instance and apps

Provision an Azure Spring Cloud 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: Launch an existing Azure Spring Cloud application using the Azure portal.

Prepare the Spring Cloud Config server

Configure the configuration server in your Azure Spring Cloud instance. For more information, see Tutorial: 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'll 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 Cloud, 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 persistent storage in Azure Spring Cloud.

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.

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 Cloud 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.

Remove application performance management (APM) integrations

Eliminate any integrations with APM tools/agents. For information on configuring performance management with Azure Monitor, see the Post-migration section.

Replace explicit Zipkin dependencies with Spring Cloud Starters

If any of the migrated applications has explicit Zipkin dependencies, remove them and replace them with Spring Cloud Starters as described in the Distributed Tracing Dependency section of Prepare a Java Spring application for deployment in Azure Spring Cloud. For information on distributed tracing with Azure App Insights, see the Post-migration section.

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 microservices (not including the Spring Cloud Config and Registry servers), as described in the Quickstart: Launch an existing Azure Spring Cloud application using the Azure portal.

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 Cloud 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 Azure Active Directory, no changes should be necessary.
  • If the identity provider is an on-premises Active Directory forest, consider implementing a hybrid identity solution with Azure Active Directory. For guidance, see the Hybrid identity documentation.
  • If the identity provider is another on-premises solution, such as PingFederate, consult the Custom installation of Azure AD Connect topic to configure federation with Azure Active Directory. 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 Cloud 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 Cloud.

  • 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 Distributed Tracing and Azure App Insights to monitor performance and interactions of your applications.

  • 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 Cloud 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