question

JoelPalmerJLPM-3215 avatar image
0 Votes"
JoelPalmerJLPM-3215 asked JoelPalmerJLPM-3215 commented

Windows Service with Azure Configuration Service

I posted the program.cs code below in Exhibit 1 which creates the host. Note, that I ".UseWindowsService" and I "AddAzureAppConfiguration". The problem is that my build guy says that the install doesn't work if there is no internet access and this is unacceptable. Huh?

I believe I know the answer to this but thought I'd throw it out to the crowd. Is there a way to pull in the AzureAppConfiguration values after the service is up and running. That said, let me partially answer my question by showing Exhibit 2. This does seem to work but I don't know how to tie it back into the Default Builder once it grabs the values.

But then, to go back to the original question/requirement... will this allow the service to start and not fail on install when there is no internet access? Another way of asking is... can the service start up completely having only a base set of configuration values then be updated after it is running?


Exhibit 1:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.CaptureStartupErrors(true);
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
logging.AddEventSourceLogger();
logging.AddNLog();
});
webBuilder.ConfigureKestrel(options =>
{
options.Listen(IPAddress.Loopback, 8080);
});
webBuilder.ConfigureAppConfiguration((context, config) =>
{
var builtConfig = config.Build();

                     config.AddAzureAppConfiguration(options =>
                     {
                         options.Connect(builtConfig[$"AppConfigEndpoint_{appSettings.Environment}"]
                             .Decrypt(EncryptionHelper.UniqueId))
                                 .Select(KeyFilter.Any, "Deployed")
                                 .Select(KeyFilter.Any, "Upload");
                     });
                 });
             });

Exhibit 2:
string env = configuration.GetValue<string>($"CurrentEnvironment");
string endPoint = configuration.GetValue<string>($"AppConfigEndpoint_{env}");
IConfigurationBuilder configBuilder = new ConfigurationBuilder();
configBuilder.AddAzureAppConfiguration(options =>
{
options.Connect(endPoint);
options.Select(KeyFilter.Any, "Deployed")
.Select(KeyFilter.Any, "Upload");
});

         configuration = configBuilder.Build();
windows-serverdotnet-runtimedotnet-aspnet-core-webapiazure-app-configuration
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

JoelPalmerJLPM-3215 avatar image
1 Vote"
JoelPalmerJLPM-3215 answered JoelPalmerJLPM-3215 commented

I figured it out… all the pieces were there I just needed to glue them together.

  1.  Create a new Project
    
  2.  Define it as a Windows Service
    
  3.  Do not define it to pull configuration values from Azure.
    
  4.  Create a class (as shown) that will pull from Azure on demand
    

a. Make it a singleton
b. Start up with a timer.
c. Once configuration values are captured delete the timer.
d. Pass the singleton around everywhere that needs config values.
5. Map values pulled from Azure to local properties.



     public bool Refresh()
     {
         bool result = false;

         try
         {
             string env = configuration.GetValue<string>($"CurrentEnvironment");
             string endPoint = configuration.GetValue<string>($"AppConfigEndpoint_{env}");

             IConfigurationBuilder configBuilder = new ConfigurationBuilder();
             configBuilder.AddAzureAppConfiguration(options =>
             {
                 options.Connect(endPoint.Decrypt())
                     .Select(KeyFilter.Any, "Deployed")
                     .Select(KeyFilter.Any, "Upload");
             });

             IConfiguration configs = configBuilder.Build();

             foreach (var item in configs.GetChildren())
             {
                 // map values to properties

                 Console.WriteLine($"{item.Key}: {item.Value}");
             }

             result = true;
         }
         catch (Exception ex)
         {
             Exception = ex;
         }

         return result;
     }


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Code formatting sucks in this environment

0 Votes 0 ·
JoelPalmerJLPM-3215 avatar image
0 Votes"
JoelPalmerJLPM-3215 answered

Not sure why this post took some of my code and formatted it while it left the rest... nonetheless. Oop, there it is.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Bruce-SqlWork avatar image
0 Votes"
Bruce-SqlWork answered JoelPalmerJLPM-3215 commented

it is common for servers to have internet access blocked. this means without firewall rules, your service can not access azure app setting. you could conditionally add the azure configuration based on a setting in the appsetting.json or a command line switch.


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

That is one other scenario where it'd be good to have a solution. Could you talk more about your solution? What would a command line switch look like?

Also note, that we aren't able to run using elevated privileges. Would the command line switch help to get around that, also?

0 Votes 0 ·
Bruce-SqlWork avatar image
0 Votes"
Bruce-SqlWork answered

a command line switch is an alternative to local app setting. a command line provider is in the default config. see command line instructions. if you are running the service from the command line this will work. if using the services template, they all not work.

to elevated privileges you need to start a new process with the runas option. you should give the service account the permission you need.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.