Reputation: 13
In my company there's an application repository that we would want to deploy to multiple clients. Each client have different application configuration values (appsettings.json) and this settings may change overtime depending on the clients. That is why, we create different git branches for each client in order to do CICD. There are multiple TeamCity Servers located in each client server (on premise) which are listening to their git branch for changes. Our concern is these number of clients will grow. The number of git branches will also increase and we do not want that to happen.
Note: Each client have their own staging and production environment. So we created the branch name as "clientA-staging", "clientA-production", "clientB-staging", "clientB-production". Another reason why we did this is because, if there is a changes in a client configuration. We just want to deploy this changes to that client only.
Are there any ways that we can improve this? What we want to achieve are:-
Upvotes: 0
Views: 971
Reputation: 13
I've managed to solve this by setting a comment filter in TeamCity (git commit message). By configuring the filter with for example "[clientA]", the deployment will only trigger if git comments matches the filter. In this case, it will only deploy to Client A.
Upvotes: 0
Reputation: 14472
We had the same issue you faced, with one branch per customer, but that proved really painful as our customer base started to grow.
What we ended up doing was having a single branch for all customers (dev, staging, prod), and create an appsettings.json
hierarchy:
appsettings.json * config for all customers
appsettings.Development.json * config for all customers, for dev environment
appsettings.Production.json * config for all customers, for prod environment
appsettings.client.json * dummy file, just to have a proper hierarchy in VS
appsettings.client.Customer1.json
appsettings.client.Customer1.Development.json
appsettings.client.Customer1.Production.json
appsettings.client.Customer2.json
appsettings.client.Customer2.Development.json
appsettings.client.Customer2.Production.json
To load the proper appsettings for each customer, we use an environment variable, called ASPNETCORE_CustomerName
(any variable prefixed with ASPNETCORE_
will be loaded as an environment variable by the default web host builder) that we read when building the web host (in Program.cs
):
public static class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host
.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
// read the customer name from the env variable
// (note that the ASPNETCORE_ prefix is removed)
var customer = hostingContext.Configuration.GetValue<string>("CustomerName");
// only add our custom hierarchy,
// the default json files are already loaded
config
.AddJsonFile($"appsettings.client.{customer}.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.client.{customer}.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
;
})
.UseStaticWebAssets()
.UseStartup<Startup>();
});
}
}
Finally, we have one CI/CD pipeline per customer, and each customer webapp has its own ASPNETCORE_CustomerName
variable set via the Azure portal.
Upvotes: 0