Skip to content

Conversation

@aaronburtle
Copy link
Contributor

Why make this change?

Closes #2748

What is this change?

Adds the option to use a local .akv file instead of Azure Key Vault for @akv('') replacement in the config file during deserialization. Similar to how we handle .env files.

How was this tested?

A new test was added that verifies we are able to do the replacement and get the correct resultant configuration.

Copilot AI review requested due to automatic review settings November 6, 2025 23:13
@aaronburtle aaronburtle changed the base branch from main to dev/aaronburtle/AKVReplacement November 6, 2025 23:16
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the configuration deserialization variable replacement mechanism and adds Azure Key Vault (AKV) variable replacement support. The changes replace boolean parameters with a structured DeserializationVariableReplacementSettings object that supports both environment variable and Azure Key Vault variable replacement, including local .akv file support.

Key changes:

  • Introduced DeserializationVariableReplacementSettings class to encapsulate variable replacement logic
  • Added AzureKeyVaultOptionsConverterFactory for proper AKV configuration deserialization
  • Updated AzureKeyVaultOptions with constructor and user-provided flags for proper serialization
  • Replaced replaceEnvVar boolean parameters with replacementSettings throughout the codebase

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/Config/DeserializationVariableReplacementSettings.cs New class implementing variable replacement logic for both environment variables and Azure Key Vault secrets
src/Config/RuntimeConfigLoader.cs Updated method signatures to use new settings object; added two-pass parsing for AKV options extraction
src/Config/ObjectModel/AzureKeyVaultOptions.cs Added constructor and user-provided flags to control serialization behavior
src/Config/Converters/StringJsonConverterFactory.cs Refactored to use replacement settings object and apply multiple replacement strategies
src/Config/Converters/AzureKeyVaultOptionsConverterFactory.cs New converter factory for proper AKV options deserialization with variable replacement
src/Config/FileSystemRuntimeConfigLoader.cs Updated to use replacement settings with backward compatibility support
src/Core/Configurations/RuntimeConfigProvider.cs Updated Initialize method signature to accept replacement settings
src/Service/Controllers/ConfigurationController.cs Updated to instantiate replacement settings with explicit parameters
src/Directory.Packages.props Added Azure.Security.KeyVault.Secrets package dependency
Multiple converter files Updated to accept and use replacement settings instead of boolean flag
Multiple test files Updated to use new API with explicit or default-constructed replacement settings
src/Service.Tests/UnitTests/RuntimeConfigLoaderJsonDeserializerTests.cs Added new test for AKV variable replacement from local file; removed unused import
src/Cli/ConfigGenerator.cs Updated AKV options construction to use new constructors with proper flag setting
Comments suppressed due to low confidence (5)

src/Service.Tests/UnitTests/RuntimeConfigLoaderJsonDeserializerTests.cs:92

  • Setting doReplaceAkvVar: true without providing azureKeyVaultOptions is inconsistent. When azureKeyVaultOptions is null, AKV replacement won't occur regardless of the flag (see line 72 of DeserializationVariableReplacementSettings.cs). Consider setting doReplaceAkvVar: false for clarity, or add a comment explaining why this is intentional.
                    GetModifiedJsonString(repKeys, @"""@env('enumVarName')"""), out RuntimeConfig actualConfig, replacementSettings: new DeserializationVariableReplacementSettings(azureKeyVaultOptions: null, doReplaceEnvVar: replaceEnvVar, doReplaceAkvVar: true)),

src/Service.Tests/UnitTests/RuntimeConfigLoaderJsonDeserializerTests.cs:132

  • Setting doReplaceAkvVar: true without providing azureKeyVaultOptions is inconsistent. When azureKeyVaultOptions is null, AKV replacement won't occur regardless of the flag (see line 72 of DeserializationVariableReplacementSettings.cs). Consider setting doReplaceAkvVar: false for clarity.
              configWithEnvVar, out RuntimeConfig runtimeConfig, replacementSettings: new DeserializationVariableReplacementSettings(azureKeyVaultOptions: null, doReplaceEnvVar: replaceEnvVar, doReplaceAkvVar: true));

src/Service.Tests/UnitTests/RuntimeConfigLoaderJsonDeserializerTests.cs:180

  • Setting doReplaceAkvVar: true without providing azureKeyVaultOptions is inconsistent. When azureKeyVaultOptions is null, AKV replacement won't occur regardless of the flag (see line 72 of DeserializationVariableReplacementSettings.cs). Consider setting doReplaceAkvVar: false for clarity.
              configWithEnvVar, out RuntimeConfig runtimeConfig, replacementSettings: new DeserializationVariableReplacementSettings(azureKeyVaultOptions: null, doReplaceEnvVar: true, doReplaceAkvVar: true));

src/Config/DeserializationVariableReplacementSettings.cs:148

  • Both branches of this 'if' statement return - consider using '?' to express intent better.
            if (EnvFailureMode is EnvironmentVariableReplacementFailureMode.Throw)
            {
                return value is not null ? value :
                    throw new DataApiBuilderException(
                        message: $"Environmental Variable, {name}, not found.",
                        statusCode: System.Net.HttpStatusCode.ServiceUnavailable,
                        subStatusCode: DataApiBuilderException.SubStatusCodes.ErrorInInitialization);
            }
            else
            {
                return value ?? match.Value;
            }

src/Config/DeserializationVariableReplacementSettings.cs:166

  • Both branches of this 'if' statement return - consider using '?' to express intent better.
            if (EnvFailureMode == EnvironmentVariableReplacementFailureMode.Throw)
            {
                return value is not null ? value :
                    throw new DataApiBuilderException(message: $"Azure Key Vault Variable, '{name}', not found.",
                                                   statusCode: System.Net.HttpStatusCode.ServiceUnavailable,
                                                   subStatusCode: DataApiBuilderException.SubStatusCodes.ErrorInInitialization);
            }
            else
            {
                return value ?? match.Value;
            }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@aaronburtle aaronburtle changed the title A support for .akv files to AKV variable replacement. Support for .akv files to AKV variable replacement. Nov 6, 2025
@anushakolan
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 6 pipeline(s).

souvikghosh04
souvikghosh04 previously approved these changes Nov 19, 2025
Copy link
Contributor

@souvikghosh04 souvikghosh04 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Base automatically changed from dev/aaronburtle/AKVReplacement to main November 20, 2025 00:06
@aaronburtle aaronburtle dismissed souvikghosh04’s stale review November 20, 2025 00:06

The base branch was changed.

@aaronburtle
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 6 pipeline(s).

@aaronburtle aaronburtle force-pushed the dev/aaronburtle/AKVReplacementFileSupport branch from 1e10826 to 64658cb Compare November 20, 2025 22:04
@aaronburtle
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 6 pipeline(s).

@aaronburtle
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 6 pipeline(s).

@aaronburtle aaronburtle added this to the Nov 2025 milestone Nov 25, 2025
@github-project-automation github-project-automation bot moved this from Todo to Review In Progress in Data API builder Nov 25, 2025
Copy link
Collaborator

@Aniruddh25 Aniruddh25 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, left a few suggestions.

@aaronburtle
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 6 pipeline(s).

Copy link
Contributor

@souvikghosh04 souvikghosh04 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added couple of comments but those are easily addressable. Approving this as the rest all looks good.

@aaronburtle
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 6 pipeline(s).

@aaronburtle aaronburtle enabled auto-merge (squash) November 26, 2025 21:48
@aaronburtle aaronburtle merged commit 499cd24 into main Nov 26, 2025
11 checks passed
@aaronburtle aaronburtle deleted the dev/aaronburtle/AKVReplacementFileSupport branch November 26, 2025 22:08
@github-project-automation github-project-automation bot moved this from Review In Progress to Done in Data API builder Nov 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Support .akv files just like .env files.

6 participants