Azure Function Flex Consumption Plan and Key Vault

When we use the Azure Functions Flex Consumption plan, the platform dynamically manages the underlying infrastructure. This means the outbound IP addresses are not static or predictable in the same way they are with dedicated plan like App Service Environment.

The Private IP Address (172.25.1.187) is an internal, virtual network address within the Azure infrastructure and not a public, internet-routable IP address. Key vault’s firewall is designed to filter based on public IP addresses or specific virtual network rules. It wouldn’t accept, non-routable IP address in its allow list.

The correct way to solve this is to use a Virtual Network (VNet) service Endpoint or an Azure Private Endpoint. This method allows your Azure Function to securely connect to the Key Vault over the Azure backbone network without using Public IP addresses.

The Solution

The correct way to solve this is to use a Virtual Network (VNet) Service Endpoint or an Azure Private Endpoint. This method allows your Azure Function to securely connect to the Key Vault over the Azure backbone network without using public IP addresses.

Here’s how you can implement this:

  1. Integrate Your Azure Function with a Virtual Network
    First, you need to integrate your Azure Function App with a virtual network. This feature allows your function to access resources within a VNet. Since your function app is on a Flex Consumption plan, you’ll need to use the Regional VNet Integration feature.
  2. Configure a VNet Service Endpoint for Key Vault
    Once your function app is integrated into a VNet, you can configure a VNet Service Endpoint on your Key Vault. This feature extends the VNet’s private address space and identity to the Azure Key Vault. When a resource (like your function app) in that VNet attempts to access the Key Vault, the traffic stays on the Azure backbone network instead of going over the public internet.

Steps to configure the VNet Service Endpoint:

  • Go to your Azure Key Vault.
  • Navigate to the Networking blade.
  • Under the Firewalls and virtual networks tab, select Allow public access from specific virtual networks and IP addresses.
  • Click + Add existing virtual networks.
  • Select the virtual network and the subnet that your Azure Function is integrated with.
  • Enable the Service endpoint for Microsoft.KeyVault on the subnet.

(Alternative) Use a Private Endpoint
A more secure and private alternative is to use an Azure Private Endpoint. This creates a private network interface for your Key Vault in your VNet, assigning it a private IP address from your VNet’s address space. This makes the Key Vault accessible only from within your VNet.

    Steps to configure the Private Endpoint:

    • Go to your Azure Key Vault.
    • Navigate to the Networking blade.
    • Select the Private endpoint connections tab.
    • Click + Private endpoint.
    • Follow the wizard to create the private endpoint, linking it to your VNet and a specific subnet.
    • Update your function app’s code or configuration to use the private endpoint DNS name for the Key Vault.

    Recommendation: The VNet Service Endpoint approach is generally simpler to implement and is the standard solution for this scenario. The Private Endpoint offers a higher level of network isolation and is often preferred for more sensitive applications.

    This approach resolves the issue by bypassing the public IP address limitation of the Key Vault firewall and establishing a secure, private connection between your Azure Function and the Key Vault.

    Natural Language AI-Powered Smart UI

    Looking for real-world AI examples is a challenge and part of this challenge comes from Generative AI (GenAI) news dominating the media. It feels like every AI demo involves chatting with GenAI to produce content. The obligatory chat completion demo has started to become the to-do list of AI demo apps, and, to make matters worse, it’s selling AI short. GenAIs rely on large language models (LLMs), which are the brain behind natural language processing tasks. In this article, I’ll explore the opportunities presented by LLMs using a real-world research-and-development experiment. This experiment is part of on-going research into AI-enabled user interface components (aka .NET Smart Components) by Progress Software and Microsoft.

    Read more on code site

    How to run SonarQube Analysis in Visual Studio Console

    To generate a SonarQube token (required for authentication when running analyses from the command line or CI/CD pipelines), follow these steps:


    Steps to Generate a SonarQube Token

    1. Log in to your SonarQube server (e.g., http://localhost:9000 for local setups).
    2. Click your profile icon (top-right corner) → “My Account”.
    3. Go to the “Security” tab.
    4. Under “Tokens”, enter a name for your token (e.g., vs-console-token).
    5. Click “Generate”.
    6. Copy the token immediately (it won’t be shown again!).
      Example token format: sqp_1234567890abcdef

    How to Use the Token

    • In dotnet-sonarscanner commands, pass the token via:shCopyDownloaddotnet sonarscanner begin /k:”your-project-key” /d:sonar.host.url=”http://localhost:9000″ /d:sonar.login=”sqp_1234567890abcdef”
    • For security, never hardcode the token in scripts. Use:
      • Environment variables (e.g., SONAR_TOKEN).
      • Secret management tools (e.g., Azure Key Vault, GitHub Secrets).

    Important Notes

    • 🔒 Treat tokens like passwords (they grant access to your SonarQube projects).
    • 🔄 Regenerate tokens periodically or revoke old ones (under “Security”).
    • 🚫 No token? You’ll get errors like Not authorized or Authentication failed.

    Example Workflow

    # Set token as an environment variable (optional)
    set SONAR_TOKEN=sqp_1234567890abcdef
    
    # Run analysis (Windows CMD)
    dotnet sonarscanner begin /k:"my-project" /d:sonar.host.url="http://localhost:9000" /d:sonar.login="%SONAR_TOKEN%"
    dotnet build
    dotnet sonarscanner end /d:sonar.login="%SONAR_TOKEN%"

    Get the SonarQube Project URL

    The project URL is the web address of your project in SonarQube. It typically follows this format:

    http://<sonarqube-server-url>/dashboard?id=<project-key>
    • <sonarqube-server-url>: The host where SonarQube is running (e.g., http://localhost:9000 if running locally).
    • <project-key>: The unique key assigned to your project in SonarQube.

    How to Find the Project Key?

    1. Log in to your SonarQube server.
    2. Navigate to your project.
    3. Check the URL in the browser’s address bar (e.g., http://localhost:9000/dashboard?id=my-project-key).
    4. Alternatively, go to Project Settings → General Settings → Key.

    2. Run SonarQube Analysis in Visual Studio Console

    To analyze a .NET project in Visual Studio Developer Command Prompt (or terminal), use the SonarScanner for .NET (dotnet-sonarscanner).

    Prerequisites

    • Install Java (required for SonarQube scanner).
    • Install SonarScanner for .NET:shCopyDownloaddotnet tool install –global dotnet-sonarscanner

    Steps to Run Analysis

    1. Start the SonarQube Analysis:shCopyDownloaddotnet sonarscanner begin /k:”” /d:sonar.host.url=”” /d:sonar.login=”
      • Replace:
        • <project-key> with your SonarQube project key.
        • <sonarqube-server-url> with your SonarQube server URL (e.g., http://localhost:9000).
        • <token> with a SonarQube user token.
    2. Build Your Project:shCopyDownloaddotnet build
    3. Complete & Publish Results to SonarQube:shCopyDownloaddotnet sonarscanner end /d:sonar.login=”<token>”
    4. Check Results:
      • Open the SonarQube project URL (e.g., http://localhost:9000/dashboard?id=my-project-key) in a browser.

    Example

    # Start analysis
    dotnet sonarscanner begin /k:"my-dotnet-app" /d:sonar.host.url="http://localhost:9000" /d:sonar.login="sqp_1234567890abcdef"
    
    # Build the project
    dotnet build
    
    # End analysis & upload results
    dotnet sonarscanner end /d:sonar.login="sqp_1234567890abcdef"

    After running these commands, your analysis results will appear in the SonarQube dashboard.

    Azure AppInsights integration in Blazor WASM

    Integrating Azure Application Insights in a Blazor WebAssembly (WASM) app is possible, though it requires special handling since Blazor WASM runs entirely in the browser, and you can’t use the full .NET SDK for Application Insights like you can in server-side apps.

    Here’s how you can set it up using JavaScript SDK (since Blazor WASM ultimately runs in the browser):


    ✅ Step-by-Step Guide

    1. Create Application Insights Resource (if not done)

    • Go to Azure Portal → Create a resource → Application Insights.
    • Choose GeneralApplication Insights, select region, etc.
    • After creation, copy the Instrumentation Key or Connection String.

    2. Add the Application Insights JavaScript SDK

    In your Blazor WebAssembly project:

    Modify wwwroot/index.html (for standalone Blazor WASM)

    htmlCopyEdit<!-- Application Insights JavaScript SDK -->
    <script type="text/javascript">
      var appInsights = window.appInsights || function (config) {
        function r(config) {
          t[config] = function () {
            var i = arguments;
            t.queue.push(function () { t[config].apply(t, i); })
          }
        }
        var t = { config: config }, u = document, e = window, o = "script", s = u.createElement(o), i, f;
        for (s.src = config.url || "https://az416426.vo.msecnd.net/scripts/a/ai.0.js", u.getElementsByTagName(o)[0].parentNode.appendChild(s), t.cookie = u.cookie, t.queue = [], i = ["Event", "Exception", "Metric", "PageView", "Trace", "Dependency"]; i.length;)
          r("track" + i.pop());
        return r("setAuthenticatedUserContext"), r("clearAuthenticatedUserContext"), r("flush"), config.disableExceptionTracking || (i = "onerror", r("_" + i), f = e[i], e[i] = function (config, r, u, e, o) {
          var s = f && f(config, r, u, e, o);
          return s !== !0 && t["_" + i](config, r, u, e, o), s
        }), t
      }({
        instrumentationKey: "YOUR_INSTRUMENTATION_KEY"
      });
    
      window.appInsights = appInsights;
      appInsights.trackPageView();
    </script>
    

    3. Call App Insights from C# Code

    You can invoke JavaScript from your Blazor C# code like this:

    Create a service to interact with JS (e.g., AppInsightsService.cs):

    csharpCopyEditusing Microsoft.JSInterop;
    using System.Threading.Tasks;
    
    public class AppInsightsService
    {
        private readonly IJSRuntime _jsRuntime;
    
        public AppInsightsService(IJSRuntime jsRuntime)
        {
            _jsRuntime = jsRuntime;
        }
    
        public async Task TrackEventAsync(string eventName)
        {
            await _jsRuntime.InvokeVoidAsync("appInsights.trackEvent", new { name = eventName });
        }
    
        public async Task TrackExceptionAsync(string errorMessage)
        {
            await _jsRuntime.InvokeVoidAsync("appInsights.trackException", new
            {
                exception = new { message = errorMessage }
            });
        }
    
        public async Task TrackPageViewAsync(string pageName)
        {
            await _jsRuntime.InvokeVoidAsync("appInsights.trackPageView", new { name = pageName });
        }
    }
    

    4. Register the Service

    In Program.cs:

    csharpCopyEditbuilder.Services.AddScoped<AppInsightsService>();
    

    5. Use in Your Components

    razorCopyEdit@inject AppInsightsService AppInsights
    
    <button @onclick="TrackEvent">Track Event</button>
    
    @code {
        private async Task TrackEvent()
        {
            await AppInsights.TrackEventAsync("ButtonClicked");
        }
    }
    

    🧠 Notes

    • Only client-side telemetry will be captured (JS-side) — no automatic dependency tracking, for example.
    • If you need full telemetry, consider combining it with Blazor WASM hosted model and using Application Insights server SDK in the backend.

    When to use ConfigureAwait(true/false)

    ConfigureAwait(false) is a C# feature used with async and await to control how the continuation of an async method is scheduled after an awaited operation completes.

    Here’s a breakdown of when and why you might need to call ConfigureAwait(false):

    Understanding Synchronization Context

    • What it is: A synchronization context (System.Threading.SynchronizationContext) represents a way to queue work (continuations) to a specific thread or threads.
      • UI Applications (WinForms, WPF, Xamarin, old ASP.NET on .NET Framework): These have a UI thread. Operations that update the UI must run on this specific UI thread. The synchronization context ensures that continuations after an await (if it wasn’t configured otherwise) are posted back to this UI thread.
      • ASP.NET Core: By default, ASP.NET Core does not have a synchronization context that behaves like the UI one. It uses a more efficient internal mechanism for managing requests.
      • Console Apps / Library Code (typically): Often have no special synchronization context, or they use the default thread pool context.
    • How await uses it: When you await a Task, by default (without ConfigureAwait(false)), the runtime captures the current SynchronizationContext (if one exists) and the current TaskScheduler. When the awaited task completes, it attempts to post the remainder of the async method (the continuation) back to that captured context or scheduler.

    When You SHOULD GENERALLY Use ConfigureAwait(false)

    1. Library Code (Most Common and Important Case):
      • If you are writing a general-purpose library (e.g., a NuGet package, a shared business logic layer, a data access layer) that is not specific to any UI framework or ASP.NET Core.Reason: Your library code doesn’t know what kind of application will call it. If it’s called from an application with a restrictive synchronization context (like a UI app), and your library’s async methods always try to resume on that captured context, it can lead to:
        • Performance Issues: Unnecessary context switching back to the UI thread for non-UI work.Deadlocks: Especially if the calling code is blocking on the async method (e.g., using .Result or .Wait(), which is an anti-pattern but can happen). The UI thread might be blocked waiting for your library method to complete, while your library method is waiting to get back onto the UI thread to complete. This is a classic deadlock.
        Solution: Use ConfigureAwait(false) on all (or almost all) await calls within your library. This tells the runtime, “I don’t need to resume on the original context; any available thread pool thread is fine.”
    // In a library
    public async Task<string> GetDataAsync()
    {
        // _httpClient is an HttpClient instance
        var response = await _httpClient.GetStringAsync("some_api_endpoint")
                                      .ConfigureAwait(false); // Don't need original context
    
        // Process the response (doesn't need original context)
        var processedData = Process(response); 
    
        await Task.Delay(100).ConfigureAwait(false); // Another example
    
        return processedData;
    }
    }

    When You MIGHT NOT NEED ConfigureAwait(false) (or when ConfigureAwait(true) is implied/desired)

    1. Application-Level Code in UI Applications (e.g., event handlers, view models directly interacting with UI):
      • If the code after an await needs to interact directly with UI elements (e.g., update a label, change a button’s state).Reason: You want the continuation to run on the UI thread’s synchronization context. This is the default behavior, so explicitly using ConfigureAwait(true) is redundant but not harmful. Omitting ConfigureAwait achieves the same.
    // In a UI event handler (e.g., WPF, WinForms)
    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        MyButton.IsEnabled = false; // UI update
        var data = await _myService.FetchDataAsync(); // This service call might use ConfigureAwait(false) internally
        // The continuation here will be back on the UI thread by default
        MyLabel.Text = data; // UI update
        MyButton.IsEnabled = true; // UI update
    }

    1. Application-Level Code in ASP.NET Core (e.g., Controllers, Razor Pages, Middleware):
      • Generally, not strictly needed: ASP.NET Core doesn’t have a SynchronizationContext that causes the same deadlock problems as UI frameworks or older ASP.NET. HttpContext and related services are accessible without needing to be on a specific “request thread” in the same way UI elements need the UI thread.
      • However, some developers still apply ConfigureAwait(false) out of habit or for consistency if their codebase also includes library projects where it is critical. It typically doesn’t hurt in ASP.NET Core and might offer a micro-optimization by avoiding an unnecessary check for a context.
      • If you do rely on HttpContext (e.g., HttpContext.User) after an await, ensure your understanding of its flow. In ASP.NET Core, HttpContext is generally available to continuations regardless of ConfigureAwait, but being explicit about context requirements is never a bad idea.
    2. Console Applications:
      • Usually, console applications don’t have a restrictive SynchronizationContext (they use the thread pool context). So, ConfigureAwait(false) is often not strictly necessary for preventing deadlocks.
      • However, if the console app uses libraries that might install a custom SynchronizationContext, or if you are writing code that might be reused in other contexts, using ConfigureAwait(false) can still be a good defensive measure.

    Summary Table:

    ContextRecommendation for ConfigureAwait(false)Reason
    General-Purpose Library CodeStrongly Recommended (Use it)Prevent deadlocks, improve performance when called from context-sensitive environments (e.g., UI).
    UI Application Code (Event Handlers, VMs)Generally Not Needed (Default is fine)You often need to return to the UI thread for UI updates.
    ASP.NET Core Application CodeOptional / Good PracticeNo UI-like SynchronizationContext causing deadlocks. Can be a micro-optimization or for consistency.
    Console Application CodeOptional / Good PracticeUsually no restrictive context, but good for reusability or if custom contexts are involved.

    Export to Sheets

    Key Takeaway:

    The most critical place to use ConfigureAwait(false) is in library code to make it robust and performant regardless of the calling application’s environment. In application-level code, the necessity depends on whether you need to return to a specific context (like the UI thread).

    As of current date (May 16, 2025), this guidance remains standard practice in the .NET ecosystem.