0
votes

I'm deploying several Web Apps to Azure: one to a development/test environment, and one to production.

I tried determining the appsettings to load based on the environment computer name, because my understanding is that Core is different in that you can't publish for a specific environment. I didn't realize that the computer name changes in Azure, so when I tried deploying an older application to the Test environment earlier today, it started using Production settings.

        public static void Main(string[] args)
        {
            string environmentName;
            if (args.Length > 0)
            {
                environmentName = args[0];

                if (environmentName != "Local" && environmentName != "Test" && environmentName != "Production")
                {
                    Console.WriteLine("Invalid environment. Please choose between Local, Test, or Production.");
                    environmentName = Console.ReadLine();
                }
            }
            else
            {
                Console.WriteLine("Application was started without arguments.");

                if (Environment.GetEnvironmentVariable("COMPUTERNAME").Contains("dev"))
                {
                    environmentName = "Local";
                }
                else if (Environment.GetEnvironmentVariable("COMPUTERNAME").Contains([Azure name]))
                {
                    environmentName = "Test";
                }
                else
                {
                    environmentName = "Production";
                }
            }
        }
 public static IHostBuilder CreateHostBuilder(string[] args, string environment) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration(configApp =>
                {
                    var path = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
                    configApp.SetBasePath(path);
                    configApp.AddJsonFile($"appsettings.{environment}.json", false, true);
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                })
                .UseSerilog();

What can I do to make sure that my test Azure uses the test environment, and my production uses production?

1
Is there a reason why you are using those files and not the Configuration blade of the App service in the Azure Portal? Are you deploying using CI/CD? If so, which?Martín La Rosa
@MartínLaRosa I was storing configs in the appsettings that get bound to classes in the application. So a class like "AWSConfig" has properties for multiple things like "IsLogging" and "BucketName," and "AzureStorage" has settings for others like "FileSAS." I'm not sure if I know how to save those in the Configurations blade. I don't have CI/CD yet, but it would be from DevOps.secretclean

1 Answers

3
votes

Your code shouldn't be aware of the name of the environment much less the computer name, otherwise you'd need to recompile if one day you need to set up environment test2 for example.

You shouldn't be deploying all settings files to all environments. Dev or testing shouldn't have your production settings for example, even if it doesn't use them. Main concern: security.

I would make the deployment process to set the appropriate settings in environment variables to the server when deploying. Ideally through an automated pipeline, but you can also do this by hand modifying the settings in the configuration blade in the azure app service.

If you still want to use the files:

  1. Delete the if statements that pick the current environment.
  2. Set the environment name in an environment variable: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-5.0
  3. The default configuration of CreateDefaultBuilder will automatically try to find a file called appSettings.{envname}.json and load it.

Remember that this loads every source configured and some things overrides others. If you have a variable in the environment specific file, this will take precedence over the general appsettings.json variable. If you have something in the general file and not in the environment specific file, you'll get the general value. That's useful for thing that don't change per environment.

Then if you have environment variables or variables in the Configuration blade in the azure portal (which I understand are the same things) these take precedence over the content of the file. (I jsut went this route and make the pipeline insert the environment variables into the target machine and don't bother with the files since it's easier to manage secrets in the pipeline)