dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
34.59k stars 9.79k forks source link

Enable web.config transforms for AspNetCore projects in VS #2019

Closed oliverjanik closed 5 years ago

oliverjanik commented 7 years ago

Let me prefix this by saying that I'm no fan of web.config but experience of publishing AspNetCore apps to IIS is really poor.

The configuration system of AspNetCore revolves around ASPNETCORE_ENVIRONMENT variable based on which different configs can be loaded and applied.

Setting this variable for specific deployments is a nightmare and there seems to be a lot of confusion how to go about this:

The crux of the problem seems to boil down to 2 problems:

1) web.config transforms as we know them are not supported in ASP.NET Core projects in VS 2) the only reasonable way to change ASPNETCORE_ENVIRONMENT is using web.config

Setting a global ASPNETCORE_ENVIRONMENT is not an option as that sets it for every site on a single server. web.config used to be self contained configuration. This dependency on a global env variable is no good in IIS use case.

All in all, I believe the IIS publish story should be of concern as many dev such as myself who are transitioning to AspNetCore want to use their existing infrastructure for deployments and take it step by step. Currently this story is overly complicated and not complete.

Another example where I need web.config transforms: https://github.com/aspnet/Home/issues/1701#issuecomment-298273962

davidfowl commented 7 years ago

FWIW, I agree. We just need to be clear that it's for IIS settings. The other thing is the fact that we've moved away from having a default web.config in the template so that would need to be figured out.

/cc @sayedihashimi

mindingdata commented 7 years ago

Is this just for IIS though? I think the crux of the issue is the use of ASPNETCORE_ENVIRONMENT variable fullstop to let a website know which environment it is in.

I think a pretty common scenario is for various staging/QA environments to be hosted on the same box in the same IIS instance. There might be 3 teams all with their own "environments" that they can deploy to to test their code (Say deploy a particular branch), but they are all using the same box.

If we take some example code for how appsettings.json is switched per environment :

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
        .AddEnvironmentVariables();
    Configuration = builder.Build();
}

The scenario above is not going to work because the environment variable is system wide. It could be IIS, nginix etc sitting infront of it and the swapping of configuration is not going to work.

Most times I have seen the above come up, suggestions have come up to use Docker, or use something like Puppet/Chef to manage app configuration so there is no appsettings.{env}.json, but I think that makes the path from full framework MVC that much harder.

davidfowl commented 7 years ago

@mindingdata You can actually control the logic that determines where the environment comes from in your Program.cs. The environment variable is just one way to declare that (the main way). If you want to do something else based on some magic file or time of day then call UseEnvironment(environmentName) on the WebHostBuidler

oliverjanik commented 7 years ago

Just to clarify, this is absolutely just for IIS config. Current JSON config system for app settings is quite good and I fully recommend it.

dkent600 commented 6 years ago

To muddy things further: I find that when I use web.config to try to override the system environment setting, it simply doesn't work. When my system environment setting is set to "Development" and I try to set it to "Production" using the web.config (as below), the application still thinks it is running in Development. (ASP.NET Core app running in IIS).

<environmentVariables>
      <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" />
</environmentVariables>
martinRocks commented 6 years ago

I think this is the right place. I build a N-tier demo and I can't seem to figure out how to inject IHostingEnvironment in to my data access layer project. That project is where I access my database and the only way I got the connection string to that layer was to override the OnConfiguring method with a magic string of the config file.

I also looked at slow-cheetah, but that seems like going around the current method of either "Debug, Release" or "Development, Production" depending on if you are using the VS method or the environment variables.

There must be information that I'm missing. MS can't want everyone to build single tier apps.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
           var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json");

            var config = builder.Build();
            var connstr = config.GetConnectionString("connStr");            
            optionsBuilder.UseSqlServer(connstr);
        }
TheBeardedLlama commented 6 years ago

so has there been any progress on this?

we should be able to set the env in the config for an app without resorting to magic

DaleMckeown commented 6 years ago

Yeah I'd like some progress on this too. Currently have no idea how I'm supposed to publish seperate projects to the same box using different environment variables.

DaleMckeown commented 6 years ago

I ended coming up with a fairly simple solution. In the main appsettings.json file, I specify my desired environment:

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "ActiveEnvironment": "Development"
}

In Program.CS, I then build an IConfiguration, and set the environment name to the value of the 'ActiveEnvironment', before loading the environment specific configuration file.

public static void Main(string[] args)
{
    WebHost.CreateDefaultBuilder()
    .ConfigureAppConfiguration((hostingContext, config) =>
    {
        // Get the environment from our hostContext.
        var env = hostingContext.HostingEnvironment;
        config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

        // Build an initial configuration.
        IConfiguration Configuration = config.Build();

        // Set the environment name.
        env.EnvironmentName = Configuration.GetSection("ActiveEnvironment").Value;

        // Load the configuration file for our specific environment.
        config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: false, reloadOnChange: true)
        .AddEnvironmentVariables();
    })
    .UseStartup<Startup>()
    .Build()
    .Run();
}

Obviously, when publishing to different environments, the 'ActiveEnvironment' needs to be changed accordingly.

Swazimodo commented 6 years ago

@DaleMckeown I was going to do something similar but I had a question about your implementation. I see you are using the Microsoft.AspNetCore.WebHost to create the default configuration. Does this approach still apply for a console application with no web components?

DaleMckeown commented 6 years ago

@Swazimodo I haven't tried this solution int the context of a console application, so I'm not sure. Best bet its to see if there is an alternative way to setting the environment variables for console applications.

gsmits commented 6 years ago

We took care of this in a different way. We setup our build agent to take the environment specific settings file and overwrite the root settings file with it. Our build makes a separate zip file for each environment that we deploy to.

On Thu, Oct 26, 2017 at 12:48 PM, Dale Mckeown notifications@github.com wrote:

@Swazimodo https://github.com/swazimodo I haven't tried this solution int the context of a console application, so I'm not sure. Best bet its to see if there is an alternative way to setting the environment variables for console applications.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/aspnet/Home/issues/2019#issuecomment-339728441, or mute the thread https://github.com/notifications/unsubscribe-auth/AAx4bT20JSb0XSzNBIAiiubq9mTVKbW5ks5swLf6gaJpZM4NMx25 .

ThisNoName commented 6 years ago

It seems all solutions require some kind of post build/publish tweaking? I ended up dropping an empty text file in the app root and pass that in as environment. Did I miss anything?

evil-shrike commented 6 years ago

Totally agree with the first post. It's by design pretty flexible but at the end it's turned out to be very hard to automate. For example I have an app which I publish to IIS on another server. Also it runs on local IIS (via folder publish). So I set Development environment in web.config. But then I need to change it onto Production or whatever during publishing. Pretty common task I guess. I believe it's impossible, right? I have to manually edit web.config on remote servers.

Ideally setting Environment should be supported via "dotnet publish" (for any publish target):

dotnet publish ... -environment=Production

dotnet publish could search for web.%Enviroment%.config (Web.Production.config, Web.Development.config) files and merge (transform) it with web.config. At the end we'd have correct value of ASPNETCORE_ENVIRONMENT:

    <environmentVariables>
        <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="value passed to publish" />
    </environmentVariables>         
nil4 commented 6 years ago

@evil-shrike have a look at https://github.com/nil4/dotnet-transform-xdt for build/publish time config transforms.

jeremycook commented 6 years ago

A use case, perhaps. I need logs to be written to .\App_Data because my application runner has read/write access to everything under .\App_Data, but can only read everything else under .\ . I use web deploy, and would like to be able to deploy a web.config like this one with the logs folder under App_Data:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath=".\<assembly>.exe" stdoutLogEnabled="true" stdoutLogFile=".\App_Data\logs\stdout" />
  </system.webServer>
</configuration>

You might ask, why not just put those settings in a web.config file instead of web.release.config? Well processPath=".\<executable>.exe" is not where the executable lives when I'm developing locally against IIS Express. So I get the good ol' "HTTP Error 502.5 - Process Failure" error.

jefraim commented 6 years ago

We automate our builds using Jenkins and our existing way of doing vars configuration per environment in NetFramework projects is through web.config transforms. So we thought we will be able to do it in dotnet as well.

It turns out that msbuild is still compatible with aspnet core csproj for doing web.config transforms!

We can add the TransformXml publishing task in the Asp.Net Core csproj:

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll" />

Add the specific transform targets:

<Target Name="ConfigDev">
    <TransformXml Source="web.config" Transform="web.dev.config" Destination="web.config" /></Target>

Do some transformations, for example on the ASPNETCORE_ENVIRONMENT variable in the web.dev.config:

<system.webServer>
    <aspNetCore processPath="dotnet" arguments=".\Test.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" >
      <environmentVariables>
        <environmentVariable xdt:Locator="Match(name)" name="ASPNETCORE_ENVIRONMENT" value="dev" xdt:Transform="SetAttributes" />
      </environmentVariables>
    </aspNetCore>
</system.webServer>

Transform web.config using msbuild before running publish:

msbuild Test.csproj /t:ConfigDev
MikeInSwitzerland commented 6 years ago

"Let me prefix this by saying that I'm no fan of web.config but experience of publishing AspNetCore apps to IIS is really poor."

I couldn't agree more with this thread.

After the simplicity of config transformations in regular ASP.Net, this whole dependency on a machine-wide ASPNETCORE_ENVIRONMENT variable stinks.

Even Microsoft's own examples say we can use, say, an appsettings.Production.json file, just by adding this line...

            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

...but it pays no attention to the NAME of the configuration we've chosen. So even when I have chosen my Production configuration, it'll still try to open appsettings.development.json. And no, I don't want to have to manually edit the ASPNETCORE_ENVIRONMENT variable myself each time I publish to a different environment. That's just asking for trouble.

I've yet to see a simple, working example of using appsettings.XXXX.json files. I can't wait for this stuff to finally be finished. (Sigh...)

willapp commented 6 years ago

Yes, please fix this!!

I have just deployed my first production dotnet core site, and now face the issue that I can't easily have a staging instance on the same server because I don't know how to publish my app onto the same box without it picking up the production settings.

I think I'm going to try @DaleMckeown solution for now, I think it will work but it does feel like a workaround rather than a solution. Environment variables are great but ONLY if you have a 1-1 ratio of servers to environments, and outside of enterprise I doubt that happens often.

DaleMckeown commented 6 years ago

@willapp My suggestion is definitely a workaround. But it does work - I've had multiple versions of the same app running on the same server for a while now and haven't had any issues.

Just remember to change the 'ActiveEnvironment' setting before you publish and you should be fine.

zinczinc commented 6 years ago

I am facing exactly what dkent600 mentioned:

<environmentVariables>
      <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" />
</environmentVariables> 

does not work on production server. The application keeps using "appsettings.Development.json" values, which, ultimately defeats the benefits of xml transformation when publishing.

I will try the workaround suggested by DaleMckeown.

ThisNoName commented 6 years ago

the only reasonable way to change ASPNETCORE_ENVIRONMENT is using web.config

Not really. If you need to run multiple instances of the same site on the same machine, here's a much simpler way

Point your IIS app to bin and in program.cs

.UseEnvironment(ReadEnvExtensionFromParentFolder())

That's it. You can have as many sites as you want, deploy into bin without worrying about transform, and even switch environment by renaming env.Whenver.

olivierr91 commented 6 years ago

I upvote this. I have URL rewrites configured for production server that do not work in the test environment. I have not found a way for publish to select the right web.config file for deployment, I have to copy it manually.

nil4 commented 6 years ago

Have a look at https://github.com/nil4/xdt-samples/, and the CLI tool for applying transforms at publish time.

svallis commented 6 years ago

Is there any progress on this? It has been 13 months since the initial report, 2.1.0 is here now, and things are still pretty poor with traditional IIS hosting. Things work wonderfully if you're using Azure, but that's not currently an option for a large portion of the sites I'm hosting.

It seems that for traditional IIS hosting it would be beneficial to set the desired environment on the command line (as @evil-shrike laid out above), and also within any .pubxml publish profiles. As @davidfowl said, it would need to be clear that this would just work using web.config and IIS, but that surely still covers a substantial part of the install base.

At the moment I have a very brittle solution using Microsoft.DotNet.Xdt.Tools and web.config translation, but it requires a build configuration per environment to get working and has just broken after updating to v2.1.0.

It'd be great to hear if there are any plans in this area and, if so, what they are? If there are no plans, or they are a long way off, then surely there's a better interim solution than the brittle/semi-manual ways we are currently forced to employ? Especially for deploying to QA and staging, I'd really like to be able to just press a button in VS and know the right thing is happening, and not have to depend on head knowledge and manual processes.

davidfowl commented 6 years ago

We don't have any plans currently but this tool https://github.com/nil4/xdt-samples/ by @nil4 looks pretty good.

@svallis have you tried it?

davidfowl commented 6 years ago

Is the main thing people want to set the environment?

svallis commented 5 years ago

@davidfowl Yeah, my current solution is using the tool you linked, but for a project with multiple destinations to publish to it requires a build configuration per environment. You need the different build configurations in order to have something to latch onto in the csproj setup, and for my purposes it's generally a 1 to 1 relationship with your environments. For example:

For latter two, I then have the corresponding web.{Build configuration}.config and appsettings.{Environment}.json, and the web.{Build configuration}.config is literally just a XDT to tell the web.config to end up with the appropriate ASPNETCORE_ENVIRONMENT environment variable. So for example, continuing the example above, web.Release.config looks like this:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <system.webServer>
    <aspNetCore>
      <environmentVariables>
        <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
      </environmentVariables>
    </aspNetCore>
  </system.webServer>
</configuration>

This actually all works pretty well from the command line. Running dotnet publish -c Staging or whatever produces a folder with the correct output and the web.config transformed as required. It does feel like it could be simplified though. If there was an -iisenvironment switch on dotnet publish which did this for us, and then that was exposed as a simple text box in VS publishing, it would remove the need for managing build configurations, XDTs, etc manually for traditional IIS hosting situations.

From within VS it currently seems problematic, though. I won't go into the details yet as I'm still trying to pin down where my issues are exactly, as we're still working through the conversion from v2.0.0 to v2.1.0 and it's possible the problems I'm having are unrelated to this. We're currently unable to publish from within VS at all though, and even when it did work on v2.0.0 we had to manually select the correct build configuration before publishing. We've reverted to publishing via the command line for the time being, but this is far from ideal. Ignore this, the problems I'm having in VS seem unrelated to this, so I'll create a new issue for that if I can reproduce it in a test repo.

DaleMckeown commented 5 years ago

@davidfowl From my perspective, Ideally, I'd like to set the environment as part of the publish profile when using Web Deploy.

willapp commented 5 years ago

I'd second that, an option on publishing would be ideal. I'm not even using the workaround described by @svallis as I prefer to publish via the VS IDE and not command line.

svallis commented 5 years ago

@willapp The solution I'm using does work in Visual Studio, but I have other issues with the solution I'm testing with that are causing issues in VS (https://github.com/aspnet/Home/issues/3190). Sorry if I didn't make that clear. It's all setup using tools in the csproj, which both the command line and VS should respect.

willapp commented 5 years ago

Finally got around to trying the tool suggested above by @davidfowl and it works! 👍

Just followed the instructions here https://github.com/nil4/dotnet-transform-xdt under the "Project-level tool" section (since I'm not on 2.1.0 yet). I had to create a default Web.config myself as I didn't have it (just copied it from the one VS generates when you deploy), then created a Web.Debug.config with a transform to set ASPNETCORE_ENVIRONMENT to Development, and hey presto! It deploys the transformed config and the site now starts up correctly.

Would be nice if the support for this was made official, but for now this is doing the job.

olivierr91 commented 5 years ago

@davidfowl The link you pointed requires publishing using the command-line. I would like to publish using the VS GUI tool. I do not want my developers to need to install cli tools for publishing the project. There is no point of being able to specify ASPNETCORE_ENVIRONMENT in web.config if transforms are not supported. Seeing how many upvotes this issue has, it should go to the backlog.

svallis commented 5 years ago

@orobert91 VS is just a GUI wrapped around the command line tools. I'm successfully using https://github.com/nil4/xdt-samples/ to transform the web.config during publish from within VS. If you configure it correctly for your project, then it will transform correctly both from the command line and within your IDE.

olivierr91 commented 5 years ago

@svallis Indeed, misread the docs. I have solved my problem with simple copy task:

  <Target Name="CopyFiles" AfterTargets="Publish">  
      <Copy SourceFiles="web.$(Configuration).config" DestinationFiles="web.config" />  
  </Target>   
vijayrkn commented 5 years ago

There is an msbuild property that publish honors for Environment name -

$(EnvironmentName)

(https://github.com/aspnet/websdk/blob/d7d73e75918ec3168bd3e5d519d0decc04675faf/src/Publish/Microsoft.NET.Sdk.Publish.Targets/netstandard1.0/TransformTargets/Microsoft.NET.Sdk.Publish.TransformFiles.targets#L79 ).

Right now, when this property is set, all we do is create appsettings.$(EnvironmentName).json and add the connection string info to that file (if requested).

Going forward, When this property is set during publish, we can also update the published web.config to have the following entry as well:

<environmentVariables>
      <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="$(EnvironmentName)" />
</environmentVariables>

Would this work for most of the scenarios mentioned here?

For the scenarios outside of setting the environmentVariable, we will look at the feasibility of porting the web.config transforms (Xdt) for core projects.

challamzinniagroup commented 5 years ago

I've come up with a solution that seems to cover the scenarios I require - I wanted to post it here in the event it is helpful for anyone else.

In my case I've got my development environment locally and both my staging and production environments on a remote server (same server). I was able to pull the application url from the IApplicationBuilder and use that in a switch statement to set the EnvironmentName value.

It seems much less "workaround-ish" than some of the other solutions offered but certainly comes down to preference.

In Startup.cs:

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            env.DetectAndSet(app);

            ... other config method stuff here ...
        }

The method above is an extension I put together based on the properties collection within the IApplicationBuilder. The extension method (and class) look like so:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Hosting.Server.Features;
using System.Linq;

namespace MyRootNamespace.Common.Extensions
{
    public static class IHostingEnvironmentExtensions
    {
        /// <summary>
        /// Detects the current hosting url and sets the <see cref="IHostingEnvironment.EnvironmentName"/> accordingly.
        /// </summary>
        /// <param name="env">The <see cref="IHostingEnvironment"/> to set.</param>
        /// <param name="app">The <see cref="IApplicationBuilder"/> used to retrieve the current app url.</param>
        public static void DetectAndSet(this IHostingEnvironment env, IApplicationBuilder app)
        {
            var _appUrl = string.Empty;

            try
            {
                _appUrl = ((FeatureCollection)app.Properties["server.Features"]).Get<IServerAddressesFeature>()?.Addresses?.FirstOrDefault();
            }
            catch { }

            switch (_appUrl)
            {
                case "https://www.myurl.com":
                case "http://www.myurl.com":
                    env.EnvironmentName = EnvironmentName.Production;
                    break;
                case "https://staging.myurl.com":
                case "http://staging.myurl.com":
                    env.EnvironmentName = EnvironmentName.Staging;
                    break;
                default:
                    env.EnvironmentName = EnvironmentName.Development;
                    break;
            }
        }
    }
}

I hope this can be of some use to folks (in those cases where a web.config transform is not desirable).

Cheers!

Eilon commented 5 years ago

I'm marking this issue as a discussion because no features/fixes related to this are planned at this time. If people still have specific feature requests, please file issues for those and we will prioritize.

frankhoffy commented 5 years ago

I wasn't really satisfied with the workarounds I saw on this thread, so I took a different approach. I stumbled on this thread Stack Overflow: https://stackoverflow.com/questions/31049152/publish-to-iis-setting-environment-variable/36836533#36836533. It talks about modifying ApplicationHost.config on the server as a place to store the ASPNETCORE_ENVIRONMENT variable.

Our internal IIS servers are managed by our operations team, so the devs in our organization don't create those sites anyway. The operations team uses a PowerShell script to create these sites. I just asked them to modify that script so that it also makes the relevant changes to ApplicationHost.config at the time the site is provisioned. Now I can just deploy there and not worry about managing the .NET Core environment. Worked well for our situation.

I would think that in a true DevOps environment you'd probably be using Azure anyway, which makes it very easy to set the environment variable.

vijayrkn commented 5 years ago

With the latest Sdk, you can just pass the msbuild property $(EnvironmentName) & tooling will take care of setting the ASPNETCORE_ENVIRONMENT to this value.

for e.g: If EnvironmentName is set to staging, then web.config will have the following entry:

      <aspNetCore processPath="dotnet" arguments=".\WebApplication242.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout">
        <environmentVariables>
          <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" />
        </environmentVariables>
      </aspNetCore>

PR with the fix: https://github.com/aspnet/websdk/pull/377

svallis commented 5 years ago

@vijayrkn Looks like a promising start. Will this eventually have support built into VS WebDeploy/publish profiles etc?

vijayrkn commented 5 years ago

Right now we don't have a UI in VS to make this Environment name selection but if this this added to the project file or the pubxml, both publish from VS and commandline will honor it.

We will be looking at adding UI support for this as well.

challamzinniagroup commented 5 years ago

@vijayrkn This is only a solution for those publishing with a web.config file - is that correct?

svallis commented 5 years ago

@vijayrkn Yeah, getting support into the pubxml format would be the moment where this would become useful for our use case. At that point we could drop all the XML transform stuff and just specify the appropriate environment strings in each pubxml. UI support could come at a later date, but that'd just be the icing on the cake.

vijayrkn commented 5 years ago

@challamzinniagroup - No, you don't need a web.config for this functionality. All you need to do is add the following to the pubxml file and publish tooling will take care of the rest.

<EnvironmentName>YourCustomEnvironment</EnvironmentName>

ThisNoName commented 5 years ago

@challamzinniagroup , @vijayrkn

Unless you have some configuration that can only be done in web.config and must be transformed between environment, otherwise, leave web.config alone. With 2 lines of code, you can read environment variables from anywhere. And you don't need any tweaking in publish profile, or published code, just list of matching appsetting.XYZ.json

willapp commented 5 years ago

@ThisNoName

You mean like database connection strings, service endpoints, credentials, or any number of other things that would change from dev->staging->production.

If you are running multiple instances on the same environment (very common outside of cloud), you absolutely need the flexibility of web.config transforms. It's pretty ridiculous that Microsoft didn't cater for this requirement out of the box with dotnet core, they just assumed everyone was hosting in Azure and had a 1-1 relationship between instance and environment.

Environment variables actually suck outside of cloud, since you end up with configuration separate from your app, making it harder to manage deployments full stop.

davidfowl commented 5 years ago

The major change here is that those secrets should never be stored in source control and instead, should be configured on the environment itself. Transforms flies in the face of good practice because it assumes that you understand the deployment target at publish time which isn't always the case (especially when you have multiple environments). Do you really need to re-deploy when you change a configuration setting for one of those N deployments?

Now the unfortunate part is that with IIS, environment variables need to be set up in the configuration file so that the app pool can see them. I don't think we ever intended for people to setup machine wide configuration on target machines (though I've seen people do that).

SIkebe commented 5 years ago

@willapp Why don't you use appsettings.json?

ThisNoName commented 5 years ago

@willapp

M$ has the perfect solution, but most people stuck with the concept of web.config transform.

Here's one way you can have multiple sites side by side. You just need to throw your environment value anywhere outside IIS binary directory, and read/set it from program.cs