I have 5 service fabric stateless services. I have to get these service fabric settings.xml values in a class library based on Section Name of each file. I am going to create a common class which will take SectionName as a parameter and have to get all configuration values.
you can use this as a starting point:
internal sealed class YourService: StatelessService
{
public YourService(StatelessServiceContext context)
: base(context)
{
var configurationPackage = Context.CodePackageActivationContext.GetConfigurationPackageObject("Config");
var sectionParams = configurationPackage.Settings.Sections["sectionname"].Parameters;
// You can now iterate through these parameters (e.g. get count and access by index)
//sectionParams.Count;
//sectionParams[0].Name;
//sectionParams[0].Value;
I am not sure if there is a way for a library to find the ServiceContext of other Services. Please also be aware that not all services might be deployed to the same nodes. This might affect configuration availability.
You might need to create a central service or actor that collects the configuration values of all other services.
Related
I am using Workbook in Azure Monitor and trying to create a dashboard.
My All resources data goes into 1 Application Insights resource.
I have resources like storage, Azure Functions, VPN, Web App etc created in this azure account.
One subscription i am using.
I am trying to run query on requests table
I want to create dashboard for a particular WebApp say namely "ABC"
OR
I want to create 1 dashboard for resources WebApp, Azure Function, Storage say of name containing "XYZ"
requests table does not contain resourceid column. Which other Table i should use to get resource type and resource id, name
I had like the same question while logging into a common app insights resource.
From what I saw, there was no common property across all the different logging applications, I could have been using to determine the telemetry-source.
What I ended up with was to add a custom property to all telemetry using a telemetry initializer (which can be added during the startup e.g. within Azure Functions, as well as AppService). For the Storage, I don't know whether this can be also done.
// C# sample for the initializer
public class ComponentNameTelemetryInitializer : ITelemetryInitializer
{
private readonly string _ComponentName;
public ComponentNameTelemetryInitializer(string assemblyName)
{
_ComponentName = assemblyName;
}
public void Initialize(ITelemetry telemetry)
{
if (telemetry is ISupportProperties propTelemetry)
{
propTelemetry.Properties["ComponentName"] = _ComponentName;
}
}
}
That way I can just filter the log for the custom dimension ComponentName and I get all entries from a specific application.
Alright, so we have multiple signalR services and what we want to do is when our code is deployed, we want the connection string to be picked from our custom configuration file instead of the function App settings.
This is the negotiate function. See the "SignalRConnectionInfo" attribute.
[FunctionName("negotiate")]
public IActionResult negotiate(
[HttpTrigger(AuthorizationLevel.Function, "post")]
HttpRequest req,
[SignalRConnectionInfo(HubName = HubName, ConnectionStringSetting = **"Cannot pass dynamic connection string here as it requies a constant"**)]
SignalRConnectionInfo connectionInfo )
{
}
we tried adding it in Startup.cs
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
IConfigurationRoot config;
builder.Services.AddSignalR().AddAzureSignalR(config["SignalrConnectionString"]);
}
}
and it does not work this way. as it gives an error
Invalid host services. Microsoft.Azure.WebJobs.Script.WebHost: The following service registrations did not match the expected services:
[Invalid] ServiceType: Microsoft.Extensions.Hosting.IHostedService, Lifetime: Singleton, ImplementationType: Microsoft.Azure.SignalR.HeartBeat
Value cannot be null.
Parameter name: provider
So, is there any other way to use it in the function?
If you want to pick connection strings from custom configuration files, you should first add the configuration files as configuration sources.
See
https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection#customizing-configuration-sources
The SignalR Function extension would pick the connection from a fixed location, by default AzureSignalRConnectionString, and you can customize it via ConnectionStringSetting.
If you have multiple SignalR service instances, you might want to use multiple endpoints support. Currently only Persistent service transport type supports multiple SignalR instances, that is, function would establish WebSocket connections with all the SignalR instances and you could customize the routing logic. This behaviour is different to picking one instance at the function startup. See https://github.com/Azure/azure-functions-signalrservice-extension/blob/dev/docs/sharding.md .
If you don't want to connect to all the SignalR instances, you can configure each connection string in one file, and pick one file as the configuration source that would be added at function startup.
My question has two parts but they are both about secure credential storage. The background is that I am using a basic hosting service with ftp to deploy my .net core 3.1 site. I don't have directory access beyond the root folder of where I deploy my files. I am using sql server and a few other third party services that require me to use API keys.
For development, all the documentation from the different third parties have me either use the windows credential storage or put a file somewhere on the file system outside of the solution folder. But that is not an option for deployment.
So my questions are, For deployment to this hosting service...
1. Is it safe to use appsettings.json to store my API keys?
2. Also, is it save to just put a flat text file in the root of my site so it's not reachable by the public and then just pull that in at runtime?
1.Is it safe to use appsettings.json to store my API keys?
NO
If you are using third party hosting service using FTP to a folder, it not safe to assume only you can see your deployment files.
Also, is it save to just put a flat text file in the root of my site so it's not reachable by the public and then just pull that in at runtime?
It is same as using appsettings.json to store API keys since appsettings files should not be exposed publicly too.
What I can suggest is to either use some third party secure tool like Azure Vault or Hashi Vault to store secrets(they are encrypted there) & consume in your application.
If you don't want to use third party service, you can create custom Configuration Builder where you can encrypt the secrets before saving & decrypt before using.
public class CustomConfigProvider : ConfigurationProvider
{
public CustomConfigProvider() { }
public override void Load()
{
Data = MyEncryptUtils.DecryptConfiguration();
}
}
public class CustomConfigurationSource : IConfigurationSource
{
public CustomConfigurationSource() { }
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new CustomConfigProvider();
}
}
public class CustomConfigurationSource : IConfigurationSource
{
public CustomConfigurationSource() { }
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new CustomConfigProvider();
}
}
Call in startup
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddCustomConfiguration()
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
Source: https://stormpath.com/blog/store-protect-sensitive-data-dotnet-core
Also there is alternate approach using bridge pattern & encryption by Steve here:
https://stevetalkscode.co.uk/configuration-bridging-part-4
When working with azure sdk I see ListByResourceGroup(), GetByResourceGroup() return the same value. What is the difference between them? If I want to get all information of vm in my subcriptions, what function should I use?
T GetByResourceGroup(string resourceGroupName, string name)
IEnumerable<T> ListByResourceGroup(string resourceGroupName)
So, if you use GetByResourceGroup, you need to provide 2 parameters. One is the resource group name, the other is the name for the VM. And you will only get the target VM.
However, ListByResourceGroup only reqiure for the resource group name. And you will be able to get all the VMs in the resource group.
If you want to get all the VMs, you can use the following as a sample:
static void Main(string[] args)
{
IAzure azure = Azure.Authenticate("path_to_auth_file").WithDefaultSubscription();
var vms = azure.VirtualMachines.List();
foreach( var vm in vms)
{
Console.WriteLine(vm.Name);
}
}
I just simply output the VM's name, you can do what you want in the foreach.
Just to add to existing answer, in Azure SDK LIST always gets all resources from subscription or resource group (usually all resources of the same type), whereas GET is used to retrieve a specific resource (if it exists), hence you need to specify the resourceGroup AND the resource name.
I'd be inclined to think this is universal. If you think about it for a second those verbs in english are meant exactly for that.
I'm trying to get a more user-friendly component name in Application Insights Application Map. I found examples but not for Service Fabric specifically.
How do you integrate that with the FabricTelemetryInitializer that is part of the Kestrel WebHostBuilder?
If you are not using the Application Insights Service Fabric nuget package, then you should use it to set your cloud role.
https://www.nuget.org/packages/Microsoft.ApplicationInsights.ServiceFabric
https://www.nuget.org/packages/Microsoft.ApplicationInsights.ServiceFabric.Native
Microsoft.ApplicationInsights.ServiceFabric.Native should be used if your application has references to service fabric runtime since this library is relevant to concepts like ServiceContext, Service Remoting, etc. Microsoft.ApplicationInsights.ServiceFabric should be used if your application runs in service fabric but has no reference to service fabric runtime.
Since you mentioned FabricTelemetryInitializer, I assume you are using these nuget packages already. You can see how FabricyTelemetryInitializer can be hooked up here:
https://github.com/microsoft/applicationinsights-servicefabric#net-core-1
If you don't have a service context object, then don't pass in one to the constructor and FabricTelemetryInitializer will just rely on environment variables.
See here for the actual logic:
https://github.com/Microsoft/ApplicationInsights-ServiceFabric/blob/master/src/ApplicationInsights.ServiceFabric/Shared/FabricTelemetryInitializer.cs#L81
I think you can use this code:
[DebuggerStepThrough]
public class ServiceNameInitializer : ITelemetryInitializer
{
/// <inheritdoc />
public void Initialize(ITelemetry telemetry)
{
telemetry.Context.Cloud.RoleName = "ServiceA";
}
}
And in ConfigureServices add:
services.AddSingleton<ITelemetryInitializer, ServiceNameInitializer>();