I'm currently trying to use the launchSettings.json file to manage the environment variables of the application, so my Setup.cs file can manage the environments in the way of env.IsDevelopmentEnvironment(), etc.
In VSTS, how do I go about setting the environment variable ASPNETCORE_ENVIRONMENT on an Azure Deployment task? Or should it get in the dotnet publish task I've got in my build steps?
Because ASPNETCORE_ENVIRONMENT is an environment variable, you can just specify it on Azure.
See the Stack Overflow answer on How and where to define an environment variable on Azure.
If you want to keep your deployment process idempotent, I'd suggest using this deployment step to set on the Azure Web App.
https://marketplace.visualstudio.com/items?itemName=pascalnaber.PascalNaber-Xpirit-WebAppConfiguration
Technically it adds release settings to the web.config as well, which isn't necessary for a core app, but importantly, it also sets the Environment Variables for the Azure host.
Provided you have specified to use environment variables in your Startup.cs:
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables(); //override settings with environment variables
var config = builder.Build();
Configuration = config;
}
So if you have a release variable: appsetting.ASPNETCORE_ENVIRONMENT = Release, you will find that $env:ASPNETCORE_ENVIRONMENT will indeed be "Release" if you're checking via the PowerShell console on Kudu.
I'm actualy using this extension to override all of my appsettings.json variables as well as ASPNETCORE_ENVIRONMENT at release-time instead of tokenzing some appsettings.{environment}.json file. I can just override with environment variables by using the right naming convention in my VSTS Release Variable names.
For example, if my appsettings.json has this structure:
{
settings: {
secret: {
foo: "bar"
}
}
}
I can override with a release variable such as:
appsetting.settings:secret:foo = "bar"
Then go check $env:settings:secret:foo on the Azure Web App after deployment
Without doing anything additional in my source or uzipping a web deployment package, tokenizing a config file and then re-zipping prior to msdeploy, I've got enviornment-specific configurations.
You can install the Replace Token extension and then add a Replace Token task in your build/release definition. This task could replace the strings in a file with the variable value you added in the build/release definition.
Related
I am deploying an Asp.Net Core application via Azure DevOps' Pipelines option and trying to set an environment variable on each of the target machines. Each deployment environment has its own settings file (for example "appsettings.Development.json") that the Asp.Net app chooses from when it starts up by reading the ASPNETCORE_ENVIRONMENT environment variable. I am using a Deploy Group to deploy the artifact to our on-site servers and that is working perfectly until it comes to setting the correct appsettings file to use.
I tried unsuccessfully to use a PowerShell task that has this inline script:
$Env:ASPNETCORE_ENVIRONMENT="$(EnvironmentName)"
All the pipeline tasks are executed successfully but the environment variable doesn't actually get applied on the target machine.
How can I set an environment variable on the target machines in a Deploy Group?
The above inline script of yours $Env:ASPNETCORE_ENVIRONMENT="$(EnvironmentName)" only set the variable in the current terminal window opened by the powershell task. The terminal window will be shut down after the powershell task is complete. We usually use below solutions to set environment variables in the pipeline.
If you want to set an environment variable on the target machines in the release pipeline. You can directly set a variable ASPNETCORE_ENVIRONMENT in the release pipeline Variables tab. See below:
Go to your release Edit page-->Variables tab-->Add new Variable-->Set the stage Scope
There is another way to set the environment variables dynamically using logging commands(Write-Host "##vso[task.setvariable..]) in the pipeline. See below inline script in powershell task:
echo "##vso[task.setvariable variable=ASPNETCORE_ENVIRONMENT]$(EnvironmentName)"
Please check the official document for more information.
Setting an environment variable that way isn't persistent, as you've observed. You'll need to the .NET environment variable methods to accomplish what you want.
[System.Environment]::SetEnvironmentVariable('ASPNETCORE_ENVIRONMENT', '$(EnvironmentName)' [System.EnvironmentVariableTarget]::Machine)
We have an Azure Function project which requires parameters. At the moment, these parameters are stored in Azure Function's application Setting.
To run the azure function locally, we used to do this:
var id = GetEnvironmentVariable("Id");
///var id=12345;
Basically on local machine, we will just uncomment the hard coded line to get the value;
I don't really like it, so I did this:
var config = new ConfigurationBuilder()
.SetBasePath(context.FunctionAppDirectory)
.AddJsonFile("settings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
I put all settings into a settings.json and read it from there.
However, as these settings are already available in azure function's appsetting section, I will have to manually delete them from azure portal (or change the arm template).
What is the preferred way to store settings for azure function? In appsetting section or in a config file like I did? Or maybe some different way?
In fact, as Carlos Alves Jorge says, the function app will read settings from local.settings.json on local by default. And on azure it will read settings from configuration settings by default.
By default, publication neither upload local.settings.json to Azure, nor makes modification on Application settings based on that local file, hence we need to update them manually on Azure portal.
If you are using VS to publish your azure function, there is a easy way to change the settings from local to azure.(edit the publish profile.)
I have just created a "staging" slot in one of my Azure App Services.
In Azure Portal, inside Application Settings for that Slot, I created a new key, as follow:
...and made it a "Slot Setting" as I don't want this value to be swaped.
When I execute my code in a .NET Core project, Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") returns null. Locally it works, as soon as I set this value in my computer environment variables.
Am I missing something?
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") to get the application setting should work on the Azure WebApp. I assume that value is overridden by other codes.
You could debug it with following way.
1.Check the staging kudu(https://yousitename-staging.scm.azurewebsites.net/Env.cshtml) to check environment variable ASPNETCORE_ENVIRONMENT.
2.We also could remote debug slot with VS.
The following is my test steps:
1.Create a .net core project.
2.Create a slot for an existing Webpp and appsetting for slot
3.Check the environment variable with kudu tool
4.Add the following code in the index.chtml.cs file
var appsetting = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
ViewData["appseting"] = appsetting;
5.in the index.chtml file change the title to appsetting value
#page
#model IndexModel
#{
ViewData["Title"] = ViewData["appseting"];
}
6.Publish the WebApp to Azure with debug mode
7.Check the title of the home page.
we also could remote debug to check it.
Not sure where/how you use the Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"), but in my project I retrieve it differently. I retrieve it in the Startup.cs. Could you try something similar and see if you get it this way?
public Startup(IHostingEnvironment env, ILogger<Startup> logger)
{
var envName = env.EnvironmentName;
}
This should give you the env name in the envName variable. If this works I can help you with how you get it other places in your code.
I've written web job as .NET Core Console Application (exe), that has appsettings.json.
How do I configure the WebJob in Azure? Basically I want to share some settings like connection string with the web app, that is configured trough App Service's Application Settings.
The way to get these settings from our ASP.NET Core is accessing to the injected environment variables.
Hence we have to load these environment variables into our Configuration in the Startup.cs file:
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
An example of appsettings.json file would be:
If you want to get the connection string named "Redis" defined in the appsettings.json file we could get it through our Configuration:
Configuration["ConnectionStrings:Redis"].
You could set this Configuration in Appsettings in webapp on azure portal:
Also we can use Configuration.GetConnectionString("Redis") to get a development connection string from our appsettings.json file and override it setting a different one in the Connection String panel of our Web App when the application is deployed and running in Azure.
For more detail, you could refer to this article.
I prefer doing this through setting environment varibles in launchSettings.json in my local project and setting the same ones in Azure App Service settings.
Advantage is that your application always uses environment variables and, more important one, no keys end up in your source control since you don't have to deploy launchSettings.json.
The CloudConfigurationManager class is perfect for this situation as it will read configuration settings from
all environments (the web jobs config and the base app config).
Install-Package Microsoft.WindowsAzure.ConfigurationManager
Then use it like this
var val = CloudConfigurationManager.GetSetting("your_appsetting_key");
The only downside is that it is only possible to read from the appSettings sections and not the connectionstring section with the CloudConfigurationManager.
If you want to share connectionsting between the web job and the base web app, then I would define the connectionstring in the appsetting section of the web app with an unique key.
In my ASP.NET 5 (core, vNext) application I have:
appsettings.test.json
appsettings.development.json
appsettings.staging.json
appsettings.production.json
appsetings.cloud.json
Each of these include different connection strings (for different environments).
Problem
When I publish my application to Azure, it automatically uses the Production environment.
I want to use the Cloud environment, when I publish to Azure.
Note
I am using the one month free trial of Azure, which wont allow me to create deployment slots (I need to upgrade).
Question
So, is there anyways I can publish to Azure in my custom environment (Cloud) by default?
So, is there anyways I can publish to Azure in my custom environment (Cloud) by default?
Yes.
The easiest way is the Azure portal. Go to MyWebApp > Settings > Application Settings > App settings. Set the ASPNET_ENV variable to Cloud.
We can test this with a simple ASP.NET Core application.
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.AddJsonFile($"appsettings.{env.EnvironmentName}.json");
builder.Build();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Run(async (context) =>
{
await context.Response
.WriteAsync("Hello from " + env.EnvironmentName);
});
}
}
It works as expected.
Try setting ASPNET_ENV in your command line. Like set ASPNET_ENV = cloud, you can also change the environemnt in VS by right clicking on your project and selecting properties, then click debug. In the Environment vars you can edit the Hosting Environment. You can also look at this issue for more ways to change the environment.