App Configuration references in Spring Boot App deployed to Azure App services.
Published Jul 19 2023 07:24 AM 1,909 Views
Microsoft

Azure App Configuration is a service that allows you to manage application settings and feature flags in one place. This is especially useful for modern programs that have many distributed components. By using App Configuration, you can avoid configuration errors during application deployment and ensure that all settings are secure and accessible in one place.

 

Prerequisites:

Create App configuration store.

Supported Java Development Kit

Spring Boot Application. Generate Hello world application code using Spring Initializer (Make sure to add spring web dependency and choose Maven project with Java 8 or higher version)

 

Connect to an App Configuration store.

  • Add the key-value to the App Configuration store. Keys serve as identifiers for key-values and are used to store and retrieve corresponding values. It's a common practice to organize keys into a hierarchical namespace by using a character delimiter, such as / or :. Use a convention best suited to your application.
  • Labels are optional but you can have it differentiate key-values with same key. For example, you can have labels specifying different environments for the same key (Development, Test, Production)

Ramya_Gangula_0-1689617407227.png

 

  • To connect to an App Configuration store, you have to use the Spring Cloud Azure Config starter. This will allow your application to communicate with the App Configuration store. 

 

 

 

<dependency>
			<groupId>com.azure.spring</groupId>
			<artifactId>spring-cloud-azure-appconfiguration-config-web</artifactId>
			<version>4.8.0</version>
		</dependency>

 

 

 

  • Develop the application to retrieve key-value pairs from the configuration store. Here are the Java classes I have.

 

 

package com.example.appconfigsampleJava;

import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "config")
public class MessageProperties {
    private String message;
    private String keyVaultMessage;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public String getKeyVaultMessage() {
        return keyVaultMessage;
    }
    public void setKeyVaultMessage(String keyVaultMessage) {
        this.keyVaultMessage = keyVaultMessage;
    }
}
package com.example.appconfigsampleJava;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.azure.spring.cloud.feature.management.FeatureManager;

@Controller
@ConfigurationProperties("controller")
public class HelloController {
    private final MessageProperties properties;
    private FeatureManager featureManager;

    public HelloController(MessageProperties properties, FeatureManager featureManager) {
        this.properties = properties;
        this.featureManager = featureManager;

    }
    @GetMapping("/hello")
    @ResponseBody
    public String helloWorld() {
        return "Hello World!";
    }
    @GetMapping("/welcome")
    public String mainWithParam(Model model) {
        model.addAttribute("Beta", featureManager.isEnabledAsync("Beta").block());
        return "welcome";
    }
    @GetMapping("/message")
    @ResponseBody
    public String getMessage() {
        return "Message: " + properties.getMessage() + "\nKey Vault message: " + properties.getKeyVaultMessage();
    }
}
package com.example.appconfigsampleJava;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

@SpringBootApplication
@EnableConfigurationProperties(MessageProperties.class)
public class AppconfigsampleJavaApplication {
	public static void main(String[] args) {
		SpringApplication.run(AppconfigsampleJavaApplication.class, args);
	}
}

 

 

  • Created bootstrap.properties with App configuration store endpoint (For running this app locally replace endpoint with connection string), code for automated refresh, feature flags and Spring profiles.

 

 

spring.cloud.azure.appconfiguration.stores[0].endpoint=https://appconfigr.azconfig.io
# code for automated refresh
spring.cloud.azure.appconfiguration.stores[0].monitoring.enabled=true
spring.cloud.azure.appconfiguration.stores[0].monitoring.refresh-interval= 30s
spring.cloud.azure.appconfiguration.stores[0].monitoring.triggers[0].key=sentinel
# code for feature flags
spring.cloud.azure.appconfiguration.stores[0].feature-flags.enabled=true
# spring.profiles.active=Development
# spring.cloud.azure.appconfiguration.stores[0].selects[0].label-filter=${spring.profiles.active}

 

 

Create a Pipeline and Deploy to Azure App Services

In your Azure DevOps project go to:

  1. Pipelines -> Pipelines -> Create pipeline.
  2. Select the repository that is hosting the code.
  3. Select the Maven package Java project Web App to Linux on Azure template.
  4. Select you subscription in the right -hand navbar, when prompted.
  5. Select the web app you are deploying to. Then select validate and configure.
  6. This should generate the following .yaml, which should be sufficient to begin deployment.

Ramya_Gangula_4-1689616715801.png

 

 

 

# Maven package Java project Web App to Linux on Azure
# Build your Java project and deploy it to Azure as a Linux web app
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/java

trigger:
- master

variables:

  # Azure Resource Manager connection created during pipeline creation
  azureSubscription: 'xxxxxx'

  # Web app name
  webAppName: 'springbootappconfig'

  # Environment name
  environmentName: 'springbootappconfig'

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

stages:
- stage: Build
  displayName: Build stage
  jobs:
  - job: MavenPackageAndPublishArtifacts
    displayName: Maven Package and Publish Artifacts
    pool:
      vmImage: $(vmImageName)

    steps:
    - task: Maven@3
      displayName: 'Maven Package'
      inputs:
        mavenPomFile: 'pom.xml'

    - task: CopyFiles@2
      displayName: 'Copy Files to artifact staging directory'
      inputs:
        SourceFolder: '$(System.DefaultWorkingDirectory)'
        Contents: '**/*.jar'
        TargetFolder: $(Build.ArtifactStagingDirectory)

    - upload: $(Build.ArtifactStagingDirectory)
      artifact: drop

- stage: Deploy
  displayName: Deploy stage
  dependsOn: Build
  condition: succeeded()
  jobs:
  - deployment: DeployLinuxWebApp
    displayName: Deploy Linux Web App
    environment: $(environmentName)
    pool:
      vmImage: $(vmImageName)
    strategy:
      runOnce:
        deploy:
          steps:
          - download: current
            artifact: drop
          - task: AzureWebApp@1
            displayName: 'Azure Web App Deploy: springbootappconfig'
            inputs:
              azureSubscription: $(azureSubscription)
              appType: webAppLinux
              appName: $(webAppName)
              package: '$(Pipeline.Workspace)/**/appconfigsampleJava-0.0.1-SNAPSHOT.jar'

 

 

 

Granting your app access to App Configuration

  • You need to provide app permissions to access the configuration in the store. Create/Enable Managed Identity from you App service resource and the assign App Configuration Data Reader role to this identity

Ramya_Gangula_0-1689616971953.png

 

Granting your app access to referenced key vaults.

  • App Configuration and Key Vault are complementary services used side by side in most application deployments.
  • App Configuration makes it easier to use these services together by creating keys that reference values stored in Key Vault. When App Configuration creates these keys, it stores the URIs of the Key Vault values rather than the values themselves.
  • you need to grant your app read access to the secrets in your key vault. This way, the secret always stays with your app. The access can be granted using either a Key Vault access policy or Azure role-based access control.

Here is the output retrieving key-values from App Configuration and Azure Key vault.

 

Ramya_Gangula_1-1689617055188.png

 

Co-Authors
Version history
Last update:
‎Jul 19 2023 07:27 AM
Updated by: