Azure Static Web App - Function App API - How to load IOptions? - azure

Everything is working locally still using storage in Azure. The local settings file to load the IOptions are:
"StorageOptions": {
"ConnectionString": "...xxx..."
}
The static web app is hitting the API and getting a 500 error due to not being able to load the connection string settings from the application settings. Other API calls that do not use Azure storage are working as expected.
I am unable to save the static web app settings in the normal manner of StorageOptions:ConnectionString with the specified value.
Can API settings for Azure static web apps use the IOptions pattern? If yes, how should the application settings be added in Azure to load the IOptions properly?
The static web app is hitting the API and getting a 500 error due to not being able to load the connection string settings from the application settings.

Application settings for the static web app does not allow for ":" in the setting name. So, instead of using "StorageOptions:ConnectionString" it would be "StorageOptions__ConnectionString" for the hierarchical data binding.
Noted here in step 4 of "Configure app settings": https://learn.microsoft.com/en-us/azure/app-service/configure-common?tabs=portal

If yes, how should the application settings be added in Azure to load the IOptions properly?
I found an issue in the SO 70461295 where user #HariKrishna and #GaryChan given that the Application Settings are available only for the Azure Static Web App associated backend APIs.
If using dependency injection for configuring the application settings through Azure Static Web Apps - Azure Functions Context, then Option pattern is available which is returned when the functionality is required.
Your given format of Application Settings:
"StorageOptions": {
"ConnectionString": "...xxx..."
}
Then, you have to configure inside the Startup.Configure method such as:
builder.Services.AddOptions<StorageOptions>()
.Configure<IConfiguration>((settings, configuration) =>
{
configuration.GetSection("StorageOptions").Bind(settings):
});
Updated Answer:
 As #BretOoten mentioned that the hierarchical data binding in azure static web apps configuration is possible with double underscore (__), even in the azure functions the nested objects/configuration from local.settings.json file is called with the double underscore (__) as mentioned in this MS Doc.
 For example:  
"WebApp1": {
"Storage1": {
"ConnString": value
}
}  
configuration will be like: 
WebApp1__Storage1__ConnString

Related

Where do Azure WebJobs read configuration settings from?

I’m developing an Azure WebJob with Visual Studio 2019, with Microsoft.NETCore.App v5.0.0 framework. I need to read values from configuration, but I don’t understand where I should put them to finally overwrite them in the Azure WebJob’s page in the Azure portal. So far, I’ve created the following appsettings.json:
{
"ConnectionStrings": {
"AzureWebJobsStorage": "..."
},
"firstValue": "...",
"secondValue": "..."
}
The following public method
public static async Task Example(
[BlobTrigger("%firstValue%/{blobName}")] Stream blobReceived
[Blob("%secondValue%/{blobName}", FileAccess.Write)] Stream blobToWrite,
ILogger logger)
Correctly reads the values of firstValue and secondValue from appsettings.json. That said, I see other projects that use app.config files, whose values are then retrieved with something like:
ConfigurationManager.AppSettings["..."];
ConfigurationManager.ConnectionStrings["..."].ConnectionString;
Should I use app.config instead of appsettings.json? How do I read values I put in the appsettings.json file when we speak about Azure WebJobs?
You cannot access the app settings from Azure WebJobs directly, but you could consider using rest API to access the AppSettings in the Azure portal.
Actually, WebJobs are console app, which uses the environment variables stored in the system, which is different from the AppSettings in the Azure portal. AppSettings stored in IIS can only be invoked from this specific web app.

How to use Azure App Settings in a Blazor WebAssembly Client side application at runtime as appsettings.json configuration?

I'm Working on Blazor WebAssembly Client/Server project (directory structure as above)
Have some application settings in both client and server projects.
The projects are hosted in Azure.
The problem is in the Client side with the appsettings.json
In the client side, the appsettings.json is within the wwwroot directory. It is okay to access the file within the app, However, the settings cannot be overwritten by Azure Portal Application Settings of the App service.
It means, that after the app is deployed in Azure portal on a Web App Service, my configuration settings do not work with the application settings' variables.
This is the code in the Progam.cs, which works fine and read the configuration from the file, but ignores the configuration settings of the Web App Service on Azure.
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
//Add a named httpClient and set base Address and Default Request Headers
builder.Services.AddHttpClient("SOME_WEB_URL", client => // SOME_WEB_URL is defined in the appsettings.json or in the Azure App Service configuration (Application Settings)
{
client.BaseAddress = new Uri(builder.Configuration["sbformsapi"]);
});
//Add a named httpClient and set base Address and Default Request Headers
builder.Services.AddHttpClient("WEB_APP_API", client => // WEB_APP_API is defined in the
{
client.BaseAddress = new Uri(builder.Configuration["sbwebappapi"]);
});
builder.Services.AddAuthorizationCore();
....
await builder.Build().RunAsync();
}
Could someone please guide how can I either
set the appsettings.json file outside the wwwroot and read it from there?
OR
inject/use the values from Azure App Service configuration's Application settings at runtime?
I am talking about the application settings here (as in the pic)...
Currently application settings are only available for the backend API associated with your Blazor App (assuming using Static App?).
https://learn.microsoft.com/en-gb/azure/static-web-apps/application-settings
So, looking at the Blazor docs, I don't think it is possible to load Azure App Settings directly in a WebAssembly. You can look for yourself
https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/configuration?view=aspnetcore-6.0
I suggest instead to put the backend URL in the appsettings.json and then use a backend service to load the configuration information from there.

Application insights not generated for .Net core app deployed on service fabric Linux cluster

I have a .Net core application that is deployed on service fabric Linux cluster. Application insights are configured in the app.
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
ApplicationInsights.AspNetCore.Extensions.ApplicationInsightsServiceOptions aiOptions
= new ApplicationInsights.AspNetCore.Extensions.ApplicationInsightsServiceOptions
{
EnableAdaptiveSampling = false,
EnableQuickPulseMetricStream = false,
InstrumentationKey = "xxx"
};
services.AddApplicationInsightsTelemetry(aiOptions);
I have a controller class that has some action methods and logs the information.
[HttpPost]
public ActionResult actionMethod(...)
{
TraceLine("------------------------------------");
//some code
}
private static void TraceLine(string msg)
{
msg = $">> {DateTime.UtcNow.ToString("o")}: {msg}";
Log.Information(msg);
}
I am using Serilog, configured in appsettings.json & Program.cs
When I hit action method directly from local (without hosting it on even local sf cluster), via Postman, I see app insights getting generated and pushed to azure.
azure app insights snapshot
But when I hit the action method that is deployed on Azure service fabric I don't see any insight getting generated.
What am I missing here?
Any help is much appreciated!
Well, we need to check a few things here:
1) The app insights URL and the instrumentation key in the deployment parameter files for cluster hosted on cloud (Cloud.xml)
2) After checking the Cloud.xml, the best way is to access the log files and check what is the actual problem.
There's a description here which explains how to discover where the log files are stored.
You can use RDP to access the machine, which is explained here.
I was able to solve the issue by using Microsoft.ApplicationInsights.ServiceFabric.Native SDK in my application to log app insights.
Refer .NetCore section in ApplicationInsights-ServiceFabric on how to configure insights for service fabric application.

How can I connect my azure function with my azure sql

I developed a cron trigger azure fuction who needs to search for soe data in my database.
Localy i can connect whit sql server, so i change the connection string in loca.settings.json to connect in azure sql and published the function, but the function cant connect with database.
I need to do something more than configure the local.settings.json?
The local.settings.json is only used for local testing. It's not even exported to azure.
You need to create a connection string in your application settings.
In Azure Functions - click Platform features and then Configuration.
Set the connection string
A function app hosts the execution of your functions in Azure. As a best security practice, store connection strings and other secrets in your function app settings. Using application settings prevents accidental disclosure of the connection string with your code. You can access app settings for your function app right from Visual Studio.
You must have previously published your app to Azure. If you haven't already done so, Publish your function app to Azure.
In Solution Explorer, right-click the function app project and choose Publish > Manage application settings.... Select Add setting, in New app setting name, type sqldb_connection, and select OK.
Application settings for the function app.
In the new sqldb_connection setting, paste the connection string you copied in the previous section into the Local field and replace {your_username} and {your_password} placeholders with real values. Select Insert value from local to copy the updated value into the Remote field, and then select OK.
Add SQL connection string setting.
The connection strings are stored encrypted in Azure (Remote). To prevent leaking secrets, the local.settings.json project file (Local) should be excluded from source control, such as by using a .gitignore file.
https://learn.microsoft.com/en-us/azure/azure-functions/functions-scenario-database-table-cleanup
If you are using entity framework core to make a connection, Other Way of connection to SQL is by using dependency injection from .netcore library.
You can keep the connection string in Azure Key-vault or the config file from there you can read the same using azure function startup class. which need below code setup in your function app.
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof( TEST.Startup))]
namespace TEST
{
internal class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
Contract.Requires(builder != null);
builder.Services.AddHttpClient();
var configBuilder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddAzureKeyVault($"https://XYZkv.vault.azure.net/");
var configuration = configBuilder.Build();
var conn = configuration["connectionString"];
builder.Services.AddDbContext<yourDBContext>(
options => options.UseSqlServer(configuration["connectionString"]));
}
}
}
after that where ever you are injecting this dbcontext, with context object you can do all CRUD operations by following microsoft's entity framework core library documentation.
Having just dealt with this beast (using a custom handler with Linux), I believe the simple way is to upgrade your App to premium-plan, allowing you to access the "Networking" page from "App Service plans". This should allow you to put both sql-server and app in the same virtual network, which probably makes it easier. (but what do I know?)
Instead, if you don't have the extra cash laying around, you can try what I did, and set up a private endpoint, and use the proxy connection setting for your database:
Create a virtual network
I used Address space: 10.1.0.0/16 (default I think)
Add subnet 10.1.0.0/24 with any name (adding a subnet is required)
Go to "Private link center" and create a private endpoint.
any name, resource-group you fancy
use resource type "Microsoft.Sql/Server" and you should be able to select your sql-server (which I assume you have created already) and also set target sub-resource to "sqlServer" (the only option)
In the next step your virtual network and submask should be auto-selected
set Private DNS integration to yes (or suffer later).
Update your firewall by going to Sql Databases, select your database and click "Set Server Firewall" from the overview tab.
Set Connection Policy to proxy. (You either do this, or upgrade to premium!)
Add existing virtual network (rule with any name)
Whitelist IPs
There probably is some other way, but the azure-cli makes it easy to get all possible IP's your app might use: az functionapp show --resource-group <group_name> --name <app_name> --query possibleOutboundIpAddresses
https://learn.microsoft.com/en-us/azure/app-service/overview-inbound-outbound-ips
whitelist them all! (copy paste exercise)
Find your FQDN from Private link center > Private Endpoints > DNS Configuration. It's probably something like yourdb.privatelink.database.windows.net
Update your app to use this url. You just update your sql server connection string and replace the domain, for example as ADO string: Server=tcp:yourdb.privatelink.database.windows.net,1433;Initial Catalog=somedbname;Persist Security Info=False;User ID=someuser;Password=abc123;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;
Also note that I at some point during all of this I switched to TrustServerCertificate=True and now I can't bother to figure out if it does a difference or not. So I left it as an exercise to the reader to find out.
So what we have done here...?
We have forced your function app to go outside the "azure-sphere" by connecting to the private endpoint. I think that if you bounce between azure-services directly, then you'll need some sort of authentication (like logging in to your DB using AD), and in my case, using custom handler and linux base for my app, I think that means you need some trust negotiation (kerberos perhaps?). I couldn't figure that out, so I came up with this instead.

How can I view the final appSettings values on an Azure App Service web app?

I have an ASP.NET MVC app deployed to Microsoft Azure App Service and am having some trouble with the appSettings and connectionStrings values.
I have some values set in the web.config and some values overriding them in the Application Settings tab of the App Service. I want to quickly and easily view the final values to check that the settings are being picked up correctly.
How can I do this?
Note: I've tried using az webapp config appsettings list but this only seems to bring back what is configured in the Application Settings of the App Service and not the merged results of combining with web.config.
No Azure API will return values that include settings that come from your web.config file.
The only way to get this is to ask the config system within your own runtime. e.g. Use code along these lines:
foreach (string name in ConfigurationManager.AppSettings)
{
string val = ConfigurationManager.AppSettings[name];
...
}
foreach (ConnectionStringSettings settings in ConfigurationManager.ConnectionStrings)
{
string connStr = settings.ConnectionString;
string provider = settings.ProviderName;
...
}
This will give you the effective values that are applied to your app.
You may also use the following blades in Azure Portal (under Development Tools section):
Console
In order to see the file, you may use type command, e.g.:
type web.config
Advanced Tools
This points to the Kudu service.
You may see files deployed when navigating to Debug Console > Choose either CMD or PowerShell. Then navigate to your config directory (e.g. site/wwwroot) and choose to either download or edit file.
App Service Editor
App Service Editor is a relatively new tool in Azure toolset. Default view is a list of files, so you can browse all hosted files, including configuration ones.
You can view all of your runtime appSettings, connection strings and environment variables (and more..) using azure KUDU SCM. if your application address is "https://app_name.azurewebsites.net" you can access it in the address "https://app_name.scm.azurewebsites.net" or from azure portal
With kudo REST API, you can get the settings, delete or post them in this address https://app_name.scm.azurewebsites.net/api/settings
kudo wiki

Resources