Connect Azure Spring Apps to Key Vault using managed identities
Note
The Basic, Standard, and Enterprise plans will be deprecated starting from mid-March, 2025, with a 3 year retirement period. We recommend transitioning to Azure Container Apps. For more information, see the Azure Spring Apps retirement announcement.
The Standard consumption and dedicated plan will be deprecated starting September 30, 2024, with a complete shutdown after six months. We recommend transitioning to Azure Container Apps. For more information, see Migrate Azure Spring Apps Standard consumption and dedicated plan to Azure Container Apps.
This article applies to: ✅ Java ❎ C#
This article shows you how to create a system-assigned or user-assigned managed identity for an app deployed to Azure Spring Apps and use it to access Azure Key Vault.
Azure Key Vault can be used to securely store and tightly control access to tokens, passwords, certificates, API keys, and other secrets for your app. You can create a managed identity in Microsoft Entra ID, and authenticate to any service that supports Microsoft Entra authentication, including Key Vault, without having to display credentials in your code.
The following video describes how to manage secrets using Azure Key Vault.
Prerequisites
- An Azure subscription. If you don't have a subscription, create a free account before you begin.
- If you're deploying an Azure Spring Apps Enterprise plan instance for the first time in the target subscription, see the Requirements section of Enterprise plan in Azure Marketplace.
- Azure CLI, version 2.55.0 or higher.
- An Azure subscription. If you don't have a subscription, create a free account before you begin.
- Azure CLI, version 2.55.0 or higher.
Provide names for each resource
Create variables to hold the resource names by using the following commands. Be sure to replace the placeholders with your own values.
export LOCATION=<location>
export RESOURCE_GROUP=myresourcegroup
export SPRING_APPS=myasa
export APP=springapp-system
export KEY_VAULT=<your-keyvault-name>
Create a resource group
A resource group is a logical container into which Azure resources are deployed and managed. Create a resource group to contain both the Key Vault and Spring Cloud using the az group create command, as shown in the following example:
az group create --name ${RESOURCE_GROUP} --location ${LOCATION}
Set up your Key Vault
To create a Key Vault, use the az keyvault create command, as shown in the following example:
Important
Each Key Vault must have a unique name.
az keyvault create \
--resource-group ${RESOURCE_GROUP} \
--name ${KEY_VAULT}
Use the following command to show the app URL and then make a note of the returned URL, which is in the format https://${KEY_VAULT}.vault.azure.net
. Use this value in the following step.
az keyvault show \
--resource-group ${RESOURCE_GROUP} \
--name ${KEY_VAULT} \
--query properties.vaultUri --output tsv
You can now place a secret in your Key Vault by using the az keyvault secret set command, as shown in the following example:
az keyvault secret set \
--vault-name ${KEY_VAULT} \
--name "connectionString" \
--value "jdbc:sqlserver://SERVER.database.windows.net:1433;database=DATABASE;"
Create Azure Spring Apps service and app
After you install all corresponding extensions, use the following command to create an Azure Spring Apps instance:
az extension add --upgrade --name spring
az spring create \
--resource-group ${RESOURCE_GROUP} \
--sku Enterprise \
--name ${SPRING_APPS}
The following example creates the app with a system-assigned managed identity, as requested by the --system-assigned
parameter:
az spring app create \
--resource-group ${RESOURCE_GROUP} \
--service ${SPRING_APPS} \
--name ${APP} \
--assign-endpoint true \
--system-assigned
export MANAGED_IDENTITY_PRINCIPAL_ID=$(az spring app show \
--resource-group ${RESOURCE_GROUP} \
--service ${SPRING_APPS} \
--name ${APP} \
--query identity.principalId --output tsv)
az extension add --upgrade --name spring
az spring create \
--resource-group ${RESOURCE_GROUP} \
--name ${SPRING_APPS}
The following example creates an app named springapp
with a system-assigned managed identity, as requested by the --system-assigned
parameter.
az spring app create \
--resource-group ${RESOURCE_GROUP} \
--service ${SPRING_APPS} \
--name ${APP} \
--assign-endpoint true \
--runtime-version Java_17 \
--system-assigned
export MANAGED_IDENTITY_PRINCIPAL_ID=$(az spring app show \
--resource-group ${RESOURCE_GROUP} \
--service ${SPRING_APPS} \
--name ${APP} \
--query identity.principalId --output tsv)
Grant your app access to Key Vault
Use the following command to grant proper access in Key Vault for your app:
az keyvault set-policy \
--name ${KEY_VAULT} \
--object-id ${MANAGED_IDENTITY_PRINCIPAL_ID} \
--secret-permissions set get list
Note
For system-assigned managed identity, use az keyvault delete-policy --name ${KEY_VAULT} --object-id ${MANAGED_IDENTITY_PRINCIPAL_ID}
to remove the access for your app after system-assigned managed identity is disabled.
Build a sample Spring Boot app with Spring Boot starter
This app has access to get secrets from Azure Key Vault. Use the Azure Key Vault Secrets Spring boot starter. Azure Key Vault is added as an instance of Spring PropertySource. Secrets stored in Azure Key Vault can be conveniently accessed and used like any externalized configuration property, such as properties in files.
Use the following command to generate a sample project from
start.spring.io
with Azure Key Vault Spring Starter.curl https://start.spring.io/starter.tgz -d dependencies=web,azure-keyvault -d baseDir=springapp -d bootVersion=3.2.1 -d javaVersion=17 -d type=maven-project | tar -xzvf -
Specify your Key Vault in your app.
cd springapp vim src/main/resources/application.properties
To use managed identity for an app deployed to Azure Spring Apps, add properties with the following content to the src/main/resources/application.properties file.
spring.cloud.azure.keyvault.secret.property-sources[0].endpoint=<your-keyvault-url> spring.cloud.azure.keyvault.secret.property-sources[0].credential.managed-identity-enabled=true
Note
You must add the key vault URL in the application.properties file as shown previously. Otherwise, the key vault URL may not be captured during runtime.
Update src/main/java/com/example/demo/DemoApplication.java with the following code example. This code retrieves the connection string from the Key Vault.
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class DemoApplication implements CommandLineRunner { @Value("${connectionString}") private String connectionString; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @GetMapping("get") public String get() { return connectionString; } public void run(String... args) throws Exception { System.out.println(String.format("\nConnection String stored in Azure Key Vault:\n%s\n",connectionString)); } }
If you open the pom.xml file, you can see the
spring-cloud-azure-starter-keyvault
dependency, as shown in the following example:<dependency> <groupId>com.azure.spring</groupId> <artifactId>spring-cloud-azure-starter-keyvault</artifactId> </dependency>
Use the following command to deploy your app to Azure Spring Apps:
az spring app deploy \ --resource-group ${RESOURCE_GROUP} \ --service ${SPRING_APPS} \ --name ${APP} \ --source-path
Use the following command to deploy your app to Azure Spring Apps:
az spring app deploy \ --resource-group ${RESOURCE_GROUP} \ --service ${SPRING_APPS} \ --name ${APP} \ --source-path \ --build-env BP_JVM_VERSION=17
To test your app, access the public endpoint or test endpoint by using the following command:
curl https://${SPRING_APPS}-${APP}.azuremicroservices.io/get
The following message is returned in the response body:
jdbc:sqlserver://SERVER.database.windows.net:1433;database=DATABASE;
.
Clean up resources
Use the following command to delete the entire resource group, including the newly created service instance:
az group delete --name ${RESOURCE_GROUP} --yes