Tutorial: Read a secret from Azure Key Vault in a Spring Boot application

This tutorial shows you how to create a Bound Boot app that reads a value from Azure Key Vault. After creating the app, you'll deploy it to Azure App Service and Azure Bound Cloud.

Spring Boot applications externalize sensitive data such as usernames and passwords. Externalizing sensitive information enables better maintainability, testability, and security. Storing secrets exterior of the code is amend than hard coding the information, or inlining it at build time.

In this tutorial, you learn how to:

  • Create an Azure Key Vault and shop a secret
  • Create an app with Spring Initializr
  • Add Fundamental Vault integration to the app
  • Deploy to Azure App Service
  • Redeploy to Azure App Service with managed identities for Azure resources
  • Deploy to Azure Leap Cloud

Prerequisites

  • If yous don't have an Azure subscription, create a gratuitous account before you begin.
  • The curl command. Almost UNIX-similar operating systems have this command pre-installed. OS-specific clients are bachelor at the official curl website.
  • The jq command. Most UNIX-like operating systems have this command pre-installed. Os-specific clients are available at the official jq website.
  • Azure CLI, version 2.14.one or later on
  • A supported Java Development Kit (JDK). For more information, see Java back up on Azure and Azure Stack.
  • Apache Maven, version 3.0 or afterward.

Create a new Azure Cardinal Vault

The post-obit sections evidence you how to sign in to Azure and create an Azure Key Vault.

Sign into Azure and set your subscription

Outset, use the following steps to authenticate using the Azure CLI.

  1. Optionally, sign out and delete some hallmark files to remove any lingering credentials:

                      az logout rm ~/.azure/accessTokens.json rm ~/.azure/azureProfile.json                                  
  2. Sign into your Azure account past using the Azure CLI:

                      az login                                  

    Follow the instructions to complete the sign-in process.

  3. List your subscriptions:

                      az account list                                  

    Azure will return a list of your subscriptions. Re-create the id value for the subscription that you want to utilize; for example:

                      [   {     "cloudName": "AzureCloud",     "id": "ssssssss-ssss-ssss-ssss-ssssssssssss",     "name": "Converted Windows Azure MSDN - Visual Studio Ultimate",     "state": "Enabled",     "tenantId": "tttttttt-tttt-tttt-tttt-tttttttttttt",     "user": {       "name": "contoso@microsoft.com",       "blazon": "user"     }   } ]                                  
  4. Specify the GUID for the subscription you desire to use with Azure; for example:

                      az business relationship set -s ssssssss-ssss-ssss-ssss-ssssssssssss                                  

Create a service principal

Azure Advertisement service principals provide access to Azure resources within your subscription. You can think of a service main as a user identity for a service. "Service" is any application, service, or platform that needs to access Azure resource. You can configure a service principal with access rights scoped but to those resource you specify. Then, configure your awarding or service to use the service principal's credentials to access those resources.

To create a service principal, utilise the following control.

              az advertizement sp create-for-rbac --name contososp --role Contributor                          

The value of the name pick must be unique within your subscription. Save aside the values returned from the command for use later in the tutorial. The render JSON volition expect similar to the following output:

              {   "appId": "sample-app-id",   "displayName": "contososp",   "proper noun": "http://contososp",   "password": "sample-password",   "tenant": "sample-tenant" }                          

Create the Primal Vault instance

To create and initialize the Azure Key Vault, use the following steps:

  1. Determine which Azure region volition hold your resource.

    1. To run into the list of regions and their locations, encounter Azure geographies.

    2. Use the az account list-locations command to detect the right Name for your chosen region.

                            az account listing-locations --output table                                          

      This tutorial uses eastus.

  2. Create a resources group to hold the Cardinal Vault and the App Service app. The value must be unique inside the Azure subscription. This tutorial uses contosorg.

                      az group create --name contosorg --location eastus                                  
  3. Create a new Cardinal Vault in the resources grouping.

                      az keyvault create \     --resources-group contosorg \     --proper name contosokv \     --enabled-for-deployment true \     --enabled-for-disk-encryption true \     --enabled-for-template-deployment true \     --location eastus \     --query backdrop.vaultUri \     --sku standard                                  

    Note

    The value of the --proper name option must be unique within the Azure subscription.

    This table explains the options shown above.

    Parameter Clarification
    enabled-for-deployment Specifies the Key Vault deployment option.
    enabled-for-disk-encryption Specifies the Primal Vault encryption option.
    enabled-for-template-deployment Specifies the Key Vault encryption choice.
    location Specifies the Azure region where your resources group will be hosted.
    name Specifies a unique name for your Primal Vault.
    query Remember the Key Vault URI from the response. You need the URI to complete this tutorial.
    sku Specifies the Key Vault SKU selection.

    The Azure CLI will display the URI for Key Vault, which yous'll use later; for case:

                      "https://contosokv.vault.azure.net/"                                  
  4. Configure the Primal Vault to allow become and listing operations from that managed identity. The value of the object-id is the appId from the az advertizement sp create-for-rbac control above.

                      az keyvault set-policy --name contosokv --spn http://contososp --hush-hush-permissions go list                                  

    The output will be a JSON object full of information about the Fundamental Vault. Information technology will have a type entry with value Microsoft.KeyVault/vaults.

    This table explains the backdrop shown above.

    Parameter Description
    proper name The name of the Cardinal Vault.
    spn The name from the output of az ad sp create-for-rbac command above.
    secret-permissions The list of operations to permit from the named chief.

    Note

    While the principle of least privilege recommends granting the smallest possible gear up of privileges to a resource, the pattern of the Key Vault integration requires at to the lowest degree go and list.

  5. Store a cloak-and-dagger in your new Key Vault. A common use instance is to store a JDBC connectedness cord. For example:

                      az keyvault undercover set --name "connectionString" \     --vault-name "contosokv" \     --value "jdbc:sqlserver://SERVER.database.windows.net:1433;database=DATABASE;"                                  

    This table explains the options shown above.

    Parameter Clarification
    name Specifies the proper name of your clandestine.
    value Specifies the value of your secret.
    vault-name Specifies your Key Vault name from earlier.

    The Azure CLI will brandish the results of your clandestine creation; for example:

                      {   "attributes": {     "created": "2020-08-24T21:48:09+00:00",     "enabled": true,     "expires": null,     "notBefore": null,     "recoveryLevel": "Purgeable",     "updated": "2020-08-24T21:48:09+00:00"   },   "contentType": null,   "id": "https://contosokv.vault.azure.internet/secrets/connectionString/sample-id",   "kid": null,   "managed": null,   "tags": {     "file-encoding": "utf-8"   },   "value": "jdbc:sqlserver://.database.windows.net:1433;database=DATABASE;" }                                  

At present that you've created a Key Vault and stored a underground, the next section will show you how to create an app with Leap Initializr.

Create the app with Leap Initializr

This section shows how to utilise Leap Initializr to create and run a Spring Boot web application with primal vault secrets included.

  1. Scan to https://start.spring.io/.
  2. Select the choices as shown in the moving picture following this list.
    • Project: Maven Project
    • Linguistic communication: Java
    • Bound Kick: ii.half-dozen.i
    • Group: com.contoso (Y'all can put any valid Coffee parcel name here.)
    • Antiquity: keyvault (You tin can put any valid Java form proper noun here.)
    • Packaging: Jar
    • Java: 11 (Y'all tin can choose 8, but this tutorial was validated with 11.)
  3. Select Add Dependencies....
  4. In the text field, type Jump Web and press Ctrl+Enter.
  5. In the text field type Azure Key Vault and printing Enter. Your screen should look like the post-obit. Spring Initializr with correct choices selected.
  6. At the bottom of the page, select Generate.
  7. When prompted, download the projection to a path on your local reckoner. This tutorial uses a keyvault directory in the current user's home directory. The values above will give you lot a keyvault.zip file in that directory.

Use the following steps to examine the application and run information technology locally.

  1. Unzip the keyvault.naught file. The file layout will wait similar the following. This tutorial ignores the test directory and its contents.

                      ├── Aid.physician ├── mvnw ├── mvnw.cmd ├── pom.xml └── src     ├── principal     │   ├── java     │   │   └── com     │   │       └── contoso     │   │           └── keyvault     │   │               └── KeyvaultApplication.java     │   └── resource     │       ├── application.properties     │       ├── static     │       └── templates                                  
  2. Open up the KeyvaultApplication.java file in a text editor. Edit the file so that information technology has the following contents.

                      import org.springframework.kicking.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.demark.note.RestController;  @SpringBootApplication @RestController public form KeyvaultApplication {      public static void main(String[] args) {         SpringApplication.run(KeyvaultApplication.grade, args);     }      @GetMapping("get")     public String get() {         return connectionString;     }      private String connectionString = "defaultValue\n";      public void run(Cord... varl) throws Exception {         System.out.println(String.format("\nConnection Cord stored in Azure Key Vault:\due north%s\n",connectionString));     }  }                                  

    The post-obit listing highlights some details about this code:

    • The class is annotated with @RestController. @RestController tells Leap Kicking that the class can respond to RESTful HTTP requests.
    • The class has a method annotated with @GetMapping(get). @GetMapping tells Spring Boot to send HTTP requests with the path /go to that method, allowing the response from that method to be returned to the HTTP client.
    • The class has a private instance variable connectionString. The value of this example variable is returned from the get() method.
  3. Open up a Bash window and navigate to the pinnacle-level keyvault directory, where the pom.xml file is located.

  4. Enter the following command:

                      mvn spring-boot:run                                  

    The command outputs Completed initialization, which indicates that the server is ready.

  5. In a separate Bash window, enter the following command:

                      curl http://localhost:8080/get                                  

    The output will show defaultValue.

  6. Kill the process that's running from mvn bound-boot:run. You can type Ctrl-C, or you can use the jps command to go the pid of the Launcher procedure and impale information technology.

Create the app without Spring Initializr

This section shows how to include Azure Central Vault secrets to your existing Jump Boot project without using Spring Initializr.

To manually add together the same the configuration that Spring Initializr generates, add the following configuration to your pom.xml file.

              <properties>      <azure.version>3.13.0</azure.version> </properties> <dependencies>      <dependency>          <groupId>com.azure.leap</groupId>          <artifactId>azure-leap-boot-starter-keyvault-secrets</artifactId>      </dependency> </dependencies> <dependencyManagement>      <dependencies>          <dependency>              <groupId>com.azure.spring</groupId>              <artifactId>azure-spring-kicking-bom</artifactId>              <version>${azure.version}</version>              <type>pom</type>              <scope>import</scope>          </dependency>      </dependencies> </dependencyManagement>                          

Add Key Vault configuration to the app

This section shows you lot how to add Key Vault configuration to your locally running awarding by modifying the Spring Kicking application KeyvaultApplication.

Just equally Key Vault allows externalizing secrets from awarding code, Spring configuration allows externalizing configuration from lawmaking. The simplest grade of Bound configuration is the application.properties file. In a Maven project, this file is located at src/main/resources/application.backdrop. Spring Initializr helpfully includes a nil length file at this location. Apply the following steps to add the necessary configuration to this file.

  1. Edit the src/main/resources/application.properties file and then that it has the following contents, adjusting the values for your Azure subscription.

                      azure.keyvault.customer-id=<your customer ID> azure.keyvault.client-key=<your client key> azure.keyvault.enabled=true azure.keyvault.tenant-id=<your tenant ID> azure.keyvault.uri=https://contosokv.vault.azure.net/                                  

    This table explains the properties shown above.

    Parameter Clarification
    azure.keyvault.client-id The appId from the return JSON from az advertisement sp create-for-rbac.
    azure.keyvault.customer-key The password from the return JSON from az advertising sp create-for-rbac.
    azure.keyvault.enabled This configuration can be useful when enabled or disabled should be set at deployment fourth dimension. For more information on Spring configuration, meet Externalized Configuration in the Spring documentation.
    azure.keyvault.tenant-id The tenant from the return JSON from az advert sp create-for-rbac.
    azure.keyvault.uri The value output from the az keyvault create command higher up.

    For the complete listing of properties, meet Azure Key Vault Secrets Spring Boot starter client library for Java.

  2. Save the file and close information technology.

  3. Open src/main/coffee/com/contoso/keyvault/KeyvaultApplication.coffee in an editor.

  4. Add the following import statement.

                      import org.springframework.beans.manufactory.annotation.Value;                                  
  5. Add together the following note to the connectionString example variable.

                      @Value("${connectionString}") individual String connectionString;                                  

    The Cardinal Vault integration provides a Spring PropertySource that'due south populated from the values of the Cardinal Vault. For more implementation details, see Azure Key Vault Secrets Spring Boot starter client library for Java.

  6. Open a Bash window and navigate to the height-level keyvault directory, where the pom.xml file is located.

  7. Enter the post-obit command:

                      mvn clean parcel bound-boot:run                                  

    The command outputs initialization completed, which indicates that the server is ready.

  8. In a separate Bash window, enter the following command:

                      curl http://localhost:8080/get                                  

    The output volition show jdbc:sqlserver://SERVER.database.windows.net:1433;database=DATABASE instead of defaultValue.

  9. Impale the process that's running from mvn spring-boot:run. You tin type Ctrl-C, or yous can use the jps control to go the pid of the Launcher procedure and kill it.

Deploy to Azure App Service

The post-obit steps show you how to deploy the KeyvaultApplication to Azure App Service.

  1. In the top-level keyvault directory, open the pom.xml file.

  2. In the <build><plugins> department, add the azure-webapp-maven-plugin by inserting the following XML.

                      <plugin>   <groupId>com.microsoft.azure</groupId>   <artifactId>azure-webapp-maven-plugin</artifactId>   <version>2.2.2</version> </plugin>                                  

    Note

    Don't worry about the formatting. The azure-webapp-maven-plugin volition reformat the entire POM during this process.

  3. Save and close the pom.xml file

  4. At a command line, utilise the following command to invoke the config goal of the newly added plugin.

                      mvn azure-webapp:config                                  

    The Maven plugin volition ask you some questions and edit the pom.xml file based on the answers. Use the following values:

    • For Subscription, ensure you've selected the same subscription ID with the Key Vault you created.
    • For Spider web App, y'all can either select an existing Spider web App or select <create> to create a new one. If yous select an existing Spider web App, it will jump directly to the last confirm step.
    • For OS, ensure linux is selected.
    • For javaVersion, ensure you lot select the Java version you chose in Leap Initializr. This tutorial uses version 11.
    • Accept the defaults for the remaining questions.
    • When asked to ostend, reply Y to continue or N to offset answering the questions again. When the plugin completes running, y'all're ready to edit the POM.
  5. Next, open up the modified pom.xml in an editor. The contents of the file should be similar to the following XML. Supervene upon the following placeholders with the specified values if you didn't already provide the value in the previous stride.

    • YOUR_SUBSCRIPTION_ID: This placeholder shows the location of the ID provided previously.
    • YOUR_RESOURCE_GROUP_NAME: Replace this placeholder with the value that yous specified when you created the Key Vault.
    • YOUR_APP_NAME: Replace this placeholder with a sensible value that'southward unique within your subscription.
    • YOUR_REGION: Replace this placeholder with the value that you specified when you lot created the Key Vault.
    • APP_SETTINGS: Copy the indicated <appSettings> element from the instance and paste it into that location in your pom.xml file. This setting causes the server to listen on TCP port 80.
                      <plugins>   <plugin>     <groupId>org.springframework.kicking</groupId>     <artifactId>leap-boot-maven-plugin</artifactId>   </plugin>   <plugin>     <groupId>com.microsoft.azure</groupId>     <artifactId>azure-webapp-maven-plugin</artifactId>     <version>2.2.2</version>     <configuration>       <schemaVersion>V2</schemaVersion>       <subscriptionId>YOUR_SUBSCRIPTION_ID</subscriptionId>       <resourceGroup>YOUR_RESOURCE_GROUP_NAME</resourceGroup>       <appName>YOUR_APP_NAME</appName>       <pricingTier>P1v2</pricingTier>       <region>YOUR_REGION</region>       <runtime>         <os>linux</os>         <javaVersion>coffee 11</javaVersion>         <webContainer>Java SE</webContainer>       </runtime>       <!-- start of APP_SETTINGS -->       <appSettings>         <property>           <name>JAVA_OPTS</proper name>           <value>-Dserver.port=lxxx</value>         </holding>       </appSettings>       <!-- terminate of APP_SETTINGS -->       <deployment>         <resources>           <resource>             <directory>${projection.basedir}/target</directory>             <includes>               <include>*.jar</include>             </includes>           </resource>         </resources>       </deployment>     </configuration>   </plugin> </plugins>                                  
  6. Salvage and close the POM.

  7. Utilize the following command to deploy the app to Azure App Service.

                      mvn -DskipTests clean bundle azure-webapp:deploy                                  

    This command may take several minutes, depending on many factors beyond your control. When you encounter output similar to the following example, you know your app has been successfully deployed.

                      [INFO] Deploying the zip package contosokeyvault-22b7c1a3-b41b-4082-a9f0-9339723fa36a11893059035499017844.zip... [INFO] Successfully deployed the artifact to https://contosokeyvault.azurewebsites.net [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time:  01:45 min [INFO] Finished at: 2020-08-16T22:47:48-04:00 [INFO] ------------------------------------------------------------------------                                  
  8. Wait three to five minutes to let the deployment to complete. Then you may access the deployment with a roll command like to the ane shown previously, just this fourth dimension using the hostname shown in your BUILD SUCCESS output. The post-obit instance uses contosokeyvault as shown in the output above.

                      curlicue https://contosokeyvault.azurewebsites.net/get                                  

    The following output indicates success.

                      jdbc:sqlserver://SERVER.database.windows.net:1433;database=DATABASE;                                  

You've at present deployed your app to Azure App Service.

Redeploy to Azure App Service and use managed identities for Azure resources

This section describes how to associate an identity with the Azure resource for the app. This association is required so that Azure tin utilize security and track access.

One of the foundational principles of cloud computing is to pay for only the resources you use. Such fine-grained resource tracking is only possible if every resources is associated with an identity. Azure App Service and Azure Cardinal Vault are two of the many Azure services that take advantage of managed identities for Azure resources. For more information nigh this important technology, see What are managed identities for Azure resources?

Note

"Managed identities for Azure resources" is the new name for the service formerly known as Managed Service Identity (MSI).

Use the post-obit steps to create the managed identity for the Azure App Service app and and so allow that identity to access the Key Vault.

  1. Create a managed identity for the App Service app. Replace the <your resource group name> and <your app name> placeholders with the values of the <resourceGroup> and <appName> elements from your pom.xml file.

                      az webapp identity assign --resource-group <your resource group name> --name <your app name>                                  

    The output volition be similar to the following instance. Note down the value of principalId for the adjacent stride.

                      {   "principalId": "<your principal ID>",   "tenantId": "<your tenant ID>",   "type": "SystemAssigned",   "userAssignedIdentities": aught }                                  
  2. Edit the application.properties so that it names the managed identity for Azure resources created in the preceding footstep.

    1. Remove the azure.keyvault.client-key.
    2. Update the azure.keyvault.customer-id to have the value of the principalId from the preceding step. The completed file should now look like the following example.
                      azure.keyvault.client-id=<your principal ID> azure.keyvault.enabled=true azure.keyvault.tenant-id=<your tenant ID> azure.keyvault.uri=https://contosokv.vault.azure.internet/                                  
  3. Configure the Key Vault to permit become and list operations from the managed identity. The value of the object-id is the principalId from the preceding output.

                      az keyvault gear up-policy \     --name <your Key Vault name> \     --object-id <your principal ID> \     --undercover-permissions become list                                  

    The output will be a JSON object full of information about the Central Vault. It volition have a type entry with value Microsoft.KeyVault/vaults

    This tabular array explains the properties shown above.

    Parameter Clarification
    name The name of the Key Vault.
    object-id The principalId from the preceding command.
    secret-permissions The listing of operations to allow from the named primary.
  4. Package and redeploy the application.

                      mvn -DskipTests clean packet azure-webapp:deploy                                  
  5. For skillful mensurate, expect a few more minutes to allow the deployment to settle down. Then you may contact the deployment with a curl command similar to the 1 shown previously, but this time using the hostname shown in your BUILD SUCCESS output. The following example uses contosokeyvault as shown in the BUILD SUCCESS output from the previous section.

                      curl https://contosokeyvault.azurewebsites.net/get                                  

    The following output indicates success.

                      jdbc:sqlserver://SERVER.database.windows.net:1433;database=DATABASE;                                  

Instead of returning defaultValue, the app gets connectionString from the Key Vault.

Deploy to Azure Spring Cloud

In this section, you'll deploy the app to Azure Jump Deject.

Azure Spring Cloud is a fully managed platform for deploying and running your Leap Boot applications in Azure. For an overview of Azure Bound Cloud, see What is Azure Spring Cloud?.

This department will use the Bound Kicking app and Key Vault that y'all created previously with a new instance of Azure Spring Cloud.

The following steps will testify how to create an Azure Jump Cloud resource and deploy the app to information technology. Make sure you've installed the Azure CLI extension for Azure Spring Cloud every bit shown in the Prerequisites.

  1. Decide on a proper noun for the service instance. To use Azure Spring Cloud within your Azure subscription, y'all must create an Azure resource of blazon Azure Spring Cloud. Equally with all other Azure resources, the service instance must stay inside a resource group. Utilise the resource grouping yous already created to hold the service instance, and choose a name for your Azure Spring Cloud instance. Create the service instance with the post-obit command.

                      az bound-cloud create --resource-group <your resource group name> --name <your Azure Leap Cloud example name>                                  

    This control takes several minutes to complete.

  2. Create a Spring Cloud App inside the service.

                      az jump-cloud app create \     --resource-grouping <your resources group proper name> \     --service <your Azure Spring Deject case name> \     --name <your app proper noun> \     --assign-identity \     --is-public true \     --runtime-version Java_11 \                                  

    This tabular array explains the options shown in a higher place.

    Parameter Description
    resource-grouping The proper name of the resource group where you created the existing service instance.
    service The name of the existing service.
    name The name of the app.
    assign-identity Causes the service to create an identity for managed identities for Azure resources.
    is-public Assign a public DNS domain name to the service.
    runtime-version The Java runtime version. The value must match the value called in Spring Initializr above.

    To understand the difference between service and app, come across App and deployment in Azure Spring Cloud.

  3. Apply the following command to get the managed identity for the Azure resource and use it to configure the existing Key Vault to allow admission from this App.

                      SERVICE_IDENTITY=$(az leap-cloud app show --resource-group "contosorg" --name "contosoascsapp" --service "contososvc" | jq -r '.identity.principalId') az keyvault ready-policy \     --name <your Key Vault name> \     --object-id <the value of the environs variable SERVICE_IDENTITY> \     --secret-permissions set get listing                                  
  4. Because the existing Spring Kick app already has an awarding.properties file with the necessary configuration, nosotros tin can deploy this app directly to Jump Cloud using the following command. Run the control in the directory containing the POM.

                      az leap-cloud app deploy \     --resource-group <your resources group proper noun> \     --name <your Spring Deject app proper noun> \     --jar-path target/keyvault-0.0.1-SNAPSHOT.jar \     --service <your Azure Bound Cloud case name>                                  

    This command creates a Deployment within the app, within the service. For more details on the concepts of service instances, apps, and Deployments see App and deployment in Azure Jump Cloud.

    If the deployment isn't successful, configure the logs for troubleshooting every bit described in Configure awarding logs. The logs volition likely have useful information to diagnose and resolve the problem.

  5. When the app has been successfully deployed, you tin can utilise scroll to verify the Key Vault integration is working. Because you specified --is-public, the default URL for your service is https://<your Azure Spring Cloud instance name>-<your app name>.azuremicroservices.io/. The post-obit command shows an example where the service instance proper noun is contososvc and the app proper name is contosoascsapp. The URL appends the value of the @GetMapping annotation.

                      curl https://contososvc-contosoascsapp.azuremicroservices.io/get                                  

    The output will evidence jdbc:sqlserver://SERVER.database.windows.net:1433;database=DATABASE.

Summary

In this tutorial, you created a new Java web awarding using the Spring Initializr. Yous created an Azure Key Vault to store sensitive data, then configured your awarding to recall information from your Key Vault. After testing it locally, you deployed the app to Azure App Service and Azure Bound Cloud.

Clean up resources

When you're finished with the Azure resources you created in this tutorial, yous can delete them using the following control:

              az group delete --proper name <your resources grouping name>                          

Next steps

To larn more most Spring and Azure, continue to the next article on the Spring on Azure documentation heart.