Quickstart: Use Azure App Configuration in Azure Kubernetes Service

In Kubernetes, you set up pods to consume configuration from ConfigMaps. It lets you decouple configuration from your container images, making your applications easily portable. Azure App Configuration Kubernetes Provider can construct ConfigMaps and Secrets from your key-values and Key Vault references in Azure App Configuration. It enables you to take advantage of Azure App Configuration for the centralized storage and management of your configuration without any changes to your application code.

A ConfigMap can be consumed as environment variables or a mounted file. In this quickstart, you incorporate Azure App Configuration Kubernetes Provider in an Azure Kubernetes Service workload where you run a simple ASP.NET Core app consuming configuration from a JSON file.

Tip

See options for workloads hosted in Kubernetes to access Azure App Configuration.

Note

This quickstart will walk you through setting up the Azure App Configuration Kubernetes Provider. Optionally, you can use the following Azure Developer CLI commands with the azure-appconfig-aks template to provision Azure resources and deploy the sample application used by this quickstart. For more information about this template, visit the azure-appconfig-aks repo on GitHub.

azd init -t azure-appconfig-aks
azd up

Prerequisites

Create an application running in AKS

In this section, you will create a simple ASP.NET Core web application running in Azure Kubernetes Service (AKS). The application reads configuration from a local JSON file. In the next section, you will enable it to consume configuration from Azure App Configuration without changing the application code. If you already have an AKS application that reads configuration from a file, skip this section and go to Use App Configuration Kubernetes Provider. You only need to ensure the configuration file generated by the provider matches the file path used by your application.

Create an application

  1. Use the .NET command-line interface (CLI) and run the following command to create a new ASP.NET Core web app project in a new MyWebApp directory:

    dotnet new webapp --output MyWebApp --framework net6.0
    
  2. Open Index.cshtml in the Pages directory, and update the content with the following code.

    @page
    @model IndexModel
    @using Microsoft.Extensions.Configuration
    @inject IConfiguration Configuration
    @{
        ViewData["Title"] = "Home page";
    }
    
    <style>
        h1 {
            color: @Configuration["Settings:FontColor"];
        }
    </style>
    
    <div class="text-center">
        <h1>@Configuration["Settings:Message"]</h1>
    </div>
    
  3. Create a config directory in the root of your project and add a mysettings.json file to it with the following content.

    {
      "Settings": {
        "FontColor": "Black",
        "Message": "Message from the local configuration"
      }
    }
    
  4. Open program.cs and add the JSON file to the configuration source by calling the AddJsonFile method.

    // Existing code in Program.cs
    // ... ...
    
    // Add a JSON configuration source 
    builder.Configuration.AddJsonFile("config/mysettings.json", reloadOnChange: true, optional: false);
    
    var app = builder.Build();
    
    // The rest of existing code in program.cs
    // ... ...
    

Containerize the application

  1. Run the dotnet publish command to build the app in release mode and create the assets in the published directory.

    dotnet publish -c Release -o published
    
  2. Create a file named Dockerfile at the root of your project directory, open it in a text editor, and enter the following content. A Dockerfile is a text file that doesn't have an extension and that is used to create a container image.

    FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS runtime
    WORKDIR /app
    COPY published/ ./
    ENTRYPOINT ["dotnet", "MyWebApp.dll"]
    
  3. Build a container image named aspnetapp by running the following command.

    docker build --tag aspnetapp .
    

Push the image to Azure Container Registry

  1. Run the az acr login command to log in your container registry. The following example logs into a registry named myregistry. Replace the registry name with yours.

    az acr login --name myregistry
    

    The command returns Login Succeeded once login is successful.

  2. Use docker tag to create a tag myregistry.azurecr.io/aspnetapp:v1 for the image aspnetapp.

    docker tag aspnetapp myregistry.azurecr.io/aspnetapp:v1
    

    Tip

    To review the list of your existing docker images and tags, run docker image ls. In this scenario, you should see at least two images: aspnetapp and myregistry.azurecr.io/aspnetapp.

  3. Use docker push to upload the image to the container registry. For example, the following command pushes the image to a repository named aspnetapp with tag v1 under the registry myregistry.

    docker push myregistry.azurecr.io/aspnetapp:v1
    

Deploy the application

  1. Create a Deployment directory in the root directory of your project.

  2. Add a deployment.yaml file to the Deployment directory with the following content to create a deployment. Replace the value of template.spec.containers.image with the image you created in the previous step.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: aspnetapp-demo
      labels:
        app: aspnetapp-demo
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: aspnetapp-demo
      template:
        metadata:
          labels:
            app: aspnetapp-demo
        spec:
          containers:
          - name: aspnetapp
            image: myregistry.azurecr.io/aspnetapp:v1
            ports:
            - containerPort: 80
    
  3. Add a service.yaml file to the Deployment directory with the following content to create a LoadBalancer service.

    apiVersion: v1
    kind: Service
    metadata:
      name: aspnetapp-demo-service
    spec:
      type: LoadBalancer
      ports:
      - port: 80
      selector:
        app: aspnetapp-demo
    
  4. Run the following command to deploy the application to the AKS cluster.

    kubectl create namespace appconfig-demo
    kubectl apply -f ./Deployment -n appconfig-demo
    
  5. Run the following command and get the External IP address exposed by the LoadBalancer service.

    kubectl get service aspnetapp-demo-service -n appconfig-demo
    
  6. Open a browser window, and navigate to the IP address obtained in the previous step. The web page looks like this:

    Screenshot showing Kubernetes Provider before using configMap.

Use App Configuration Kubernetes Provider

Now that you have an application running in AKS, you'll deploy the App Configuration Kubernetes Provider to your AKS cluster running as a Kubernetes controller. The provider retrieves data from your App Configuration store and creates a ConfigMap, which is consumable as a JSON file mounted in a data volume.

Set up the Azure App Configuration store

Add following key-values to the App Configuration store and leave Label and Content Type with their default values. For more information about how to add key-values to a store using the Azure portal or the CLI, go to Create a key-value.

Key Value
Settings:FontColor Green
Settings:Message Hello from Azure App Configuration

Set up the App Configuration Kubernetes Provider

  1. Run the following command to get access credentials for your AKS cluster. Replace the value of the name and resource-group parameters with your AKS instance:

    az aks get-credentials --name <your-aks-instance-name> --resource-group <your-aks-resource-group>
    
  2. Install Azure App Configuration Kubernetes Provider to your AKS cluster using helm:

    helm install azureappconfiguration.kubernetesprovider \
         oci://mcr.microsoft.com/azure-app-configuration/helmchart/kubernetes-provider \
         --namespace azappconfig-system \
         --create-namespace
    

    Tip

    The App Configuration Kubernetes Provider is also available as an AKS extension. This integration allows for seamless installation and management via the Azure CLI, ARM templates, or Bicep templates. Utilizing the AKS extension facilitates automatic minor/patch version updates, ensuring your system is always up-to-date. For detailed installation instructions, please refer to the Azure App Configuration extension for Azure Kubernetes Service.

  3. Add an appConfigurationProvider.yaml file to the Deployment directory with the following content to create an AzureAppConfigurationProvider resource. AzureAppConfigurationProvider is a custom resource that defines what data to download from an Azure App Configuration store and creates a ConfigMap.

    apiVersion: azconfig.io/v1
    kind: AzureAppConfigurationProvider
    metadata:
      name: appconfigurationprovider-sample
    spec:
      endpoint: <your-app-configuration-store-endpoint>
      target:
        configMapName: configmap-created-by-appconfig-provider
        configMapData: 
          type: json
          key: mysettings.json
      auth:
        workloadIdentity:
          serviceAccountName: <your-service-account-name>
    

    Replace the value of the endpoint field with the endpoint of your Azure App Configuration store. Proceed to the next step to update the auth section with your authentication information.

    Note

    AzureAppConfigurationProvider is a declarative API object. It defines the desired state of the ConfigMap created from the data in your App Configuration store with the following behavior:

    • The ConfigMap will fail to be created if a ConfigMap with the same name already exists in the same namespace.
    • The ConfigMap will be reset based on the present data in your App Configuration store if it's deleted or modified by any other means.
    • The ConfigMap will be deleted if the App Configuration Kubernetes Provider is uninstalled.
  4. Follow the instructions to use the workload identity to authenticate with your App Configuration store. Update the appConfigurationProvider.yaml file by replacing the serviceAccountName field with the name of the service account you created. For more information on other authentication methods, refer to the examples in the Authentication section.

  5. Update the deployment.yaml file in the Deployment directory to use the ConfigMap configmap-created-by-appconfig-provider as a mounted data volume. It is important to ensure that the volumeMounts.mountPath matches the WORKDIR specified in your Dockerfile and the config directory created before.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: aspnetapp-demo
      labels:
        app: aspnetapp-demo
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: aspnetapp-demo
      template:
        metadata:
          labels:
            app: aspnetapp-demo
        spec:
          containers:
          - name: aspnetapp
            image: myregistry.azurecr.io/aspnetapp:v1
            ports:
            - containerPort: 80
            volumeMounts:
            - name: config-volume
              mountPath: /app/config
          volumes:
          - name: config-volume 
            configMap: 
              name: configmap-created-by-appconfig-provider
    
  6. Run the following command to deploy the changes. Replace the namespace if you are using your existing AKS application.

    kubectl apply -f ./Deployment -n appconfig-demo
    
  7. Refresh the browser. The page shows updated content.

    Screenshot showing Kubernetes Provider after using configMap.

Troubleshooting

If you don't see your application picking up the data from your App Configuration store, run the following command to validate that the ConfigMap is created properly.

kubectl get configmap configmap-created-by-appconfig-provider -n appconfig-demo

If the ConfigMap is not created, run the following command to get the data retrieval status.

kubectl get AzureAppConfigurationProvider appconfigurationprovider-sample -n appconfig-demo -o yaml

If the Azure App Configuration Kubernetes Provider retrieved data from your App Configuration store successfully, the phase property under the status section of the output should be COMPLETE, as shown in the following example.

$ kubectl get AzureAppConfigurationProvider appconfigurationprovider-sample -n appconfig-demo -o yaml

apiVersion: azconfig.io/v1
kind: AzureAppConfigurationProvider
  ... ... ...
status:
  lastReconcileTime: "2023-04-06T06:17:06Z"
  lastSyncTime: "2023-04-06T06:17:06Z"
  message: Complete sync settings to ConfigMap or Secret
  phase: COMPLETE

If the phase is not COMPLETE, the data isn't downloaded from your App Configuration store properly. Run the following command to show the logs of the Azure App Configuration Kubernetes Provider.

kubectl logs deployment/az-appconfig-k8s-provider -n azappconfig-system

Use the logs for further troubleshooting. Refer to the FAQ section for common issues.

FAQ

Why isn’t the ConfigMap or Secret being generated?

You can follow the steps in the Troubleshooting guide to collect logs for detailed error information. Here are some common causes.

  • RESPONSE 403: 403 Forbidden: The configured identity lacks the necessary permissions to access the App Configuration store. Refer to the Authentication section for examples that match the identity you are using.
  • A Key Vault reference is found in App Configuration, but 'spec.secret' was not configured: One or more Key Vault references are included in the selected key-values, but the authentication information for Key Vaults is not provided. To maintain the integrity of the configuration, the entire configuration fails to load. Configure the spec.secret section to provide the necessary authentication information. For examples and more information, see Key Vault reference .

Why does the generated ConfigMap not contain the expected data?

Ensure that you specify the correct key-value selectors to match the expected data. If no selectors are specified, all key-values without a label will be downloaded from your App Configuration store. When using a key filter, verify that it matches the prefix of your expected key-values. If your key-values have labels, make sure to specify the label filter in the selectors. For more examples, refer to the key-value selection documentation.

How can I customize the installation of the Azure App Configuration Kubernetes Provider?

You can customize the installation by providing additional Helm values when installing the Azure App Configuration Kubernetes Provider. For example, you can set the log level, configure the provider to run on a specific node, or disable the workload identity. Refer to the installation guide for more information.

How to trigger on-demand refresh of ConfigMap and Secret

While you can set up automatic data refresh, there are times when you might want to trigger an on-demand refresh to get the latest data from App Configuration and Key Vault. To do this, you can restart the deployment of the Azure App Configuration Kubernetes provider controller. The Kubernetes provider will then reconcile and update the ConfigMap and Secret with the latest data from your App Configuration store and Key Vault.

It is not recommended to delete or modify the ConfigMap and Secret generated by the Kubernetes provider. Although new ones will be generated from the latest data, this could cause downtime for your applications in the event of any failures.

Why am I unable to authenticate with Azure App Configuration using workload identity after upgrading the provider to version 2.0.0?

Starting with version 2.0.0, a user-provided service account is required for authenticating with Azure App Configuration using workload identity. This change enhances security through namespace isolation. Previously, a Kubernetes provider’s service account was used for all namespaces. For updated instructions, see the documentation on using workload identity. If you need time to migrate when upgrading to version 2.0.0, you can temporarily set workloadIdentity.globalServiceAccountEnabled=true during provider installation. Please note that support for using the provider’s service account will be deprecated in a future release.

Clean up resources

Uninstall the App Configuration Kubernetes Provider from your AKS cluster if you want to keep the AKS cluster.

helm uninstall azureappconfiguration.kubernetesprovider --namespace azappconfig-system

If you don't want to continue using the resources created in this article, delete the resource group you created here to avoid charges.

Important

Deleting a resource group is irreversible. The resource group and all the resources in it are permanently deleted. Ensure that you don't accidentally delete the wrong resource group or resources. If you created the resources for this article inside a resource group that contains other resources you want to keep, delete each resource individually from its respective pane instead of deleting the resource group.

  1. Sign in to the Azure portal, and select Resource groups.
  2. In the Filter by name box, enter the name of your resource group.
  3. In the result list, select the resource group name to see an overview.
  4. Select Delete resource group.
  5. You're asked to confirm the deletion of the resource group. Enter the name of your resource group to confirm, and select Delete.

After a few moments, the resource group and all its resources are deleted.

Note

If you use the Azure Developer CLI to set up the resources, you can run the azd down command to delete all resources created by the azure-appconfig-aks template.

Next steps

In this quickstart, you:

  • Created an application running in Azure Kubernetes Service (AKS).
  • Connected your AKS cluster to your App Configuration store using the App Configuration Kubernetes Provider.
  • Created a ConfigMap with data from your App Configuration store.
  • Ran the application with configuration from your App Configuration store without changing your application code.

To learn how to update your AKS workloads to dynamically refresh configuration, continue to the next tutorial.

To learn more about the Azure App Configuration Kubernetes Provider, see Azure App Configuration Kubernetes Provider reference.