Environments File Settings

Settings for scaffolding out multiple environments in your Web API.

Multiple Environments

Wrapt templates are configured with Development (StartupDevelopment) and Production (Startup) environments by default, with the ability to add as many additional environments as you'd like.

The project will run StartupDevelopment locally by default using an in-memory database. This environment should generally not be connected to a live database to ensure that devs will be able to clone your API down and run the solution without needing to go through additional database set up.

Additional environments can be add added using an Environments list in your initial build file. This will use a multiple startup approach as described in the aspnetcore docs. This means that there will be a Startup{EnvironmentName}.cs class, and appsettings.{environment}.json file, and a launchsettings.json profile added for each environment.

Environment Properties

NameRequiredDescriptionDefault
EnvironmentNameYesThe name of the environment that will set ASPNETCORE_ENVIRONMENT, the suffix of your Startup.cs etc. Note that Development and Startup are reserved strings for the in memory and production environments respectively. Startup can be used to add settings to the production environment.None
ConnectionStringYesThe connection string for the database. The connection string will just be added in between quotes and treated like a string, so will need to be valid in that format. Backslashes will automatically be escaped for you.None
ProfileNameNoThe name of the profile that is added into your launchsettings.json to run this environment.SOLUTIONNAME (Development)
AuthorityNoThe authority url for the auth server.None
AudienceNoThe unique id of the audience for an issued token (Identified in a JWT aud claim). In this case, this is usually going to be the identifier given to your API on your Authorization Server.None
AuthorizationUrlNoThe url to the authentication server to authenticate yourself and get an authorization code or access token.None
TokenUrlNoThe url to the authentication server to refresh your access token.None
ClientIdNoThe client id of the client as configured on your authorization server.None
ClientSecretNoThe client secret known only to your application and authorization server. If your client is configured for a PKCE-enhanced authorization code flow on your Authorization Sever, this is not needed.None
BrokerSettingsNoThe settings for the message broker, if you are adding one.None

Broker Settings

NameRequiredDescriptionDefault
HostYesThe host for the broker connectionlocalhost
VirtualHostYesThe virtual host of the broker. This provides a way to segregate applications using the same RabbitMQ instance./
UsernameYesThe username for the broker connectionguest
PasswordYesThe password for the broker connection.guest

IMPORTANT

Note that the connection strings, broker passwords, and client secrets will currently be added to appsettings.{environment}.json, so they will be committed to source control. You should NOT be adding anything with credentials in here.

There are plans to support secret manager and integration with external secret managers in AWS, Azure, etc. in the future.

Example Setting Up Multiple Environments

In this example, we are setting up QA, Staging, and Local environments in addition to the default Startup and Development environments. Development does not have to be specified here, but we can use Startup to specify our production settings, as we are in this case.

Note that the Local environment here would be using a local db stored on my computer which is separate from the Development environment which will use an in memory database.

Environments:
  - EnvironmentName: Startup
    ConnectionString: "Data Source=prodserver;Initial Catalog=MyDbName;Integrated Security=True;Encrypt=True;TrustServerCertificate=True;"
    ProfileName: Prod
  - EnvironmentName: Qa
    ConnectionString: "Data Source=qaserver;Initial Catalog=MyDbName;Integrated Security=True;Encrypt=True;TrustServerCertificate=True;"
    ProfileName: Qa
  - EnvironmentName: Staging
    ConnectionString: "Data Source=stagingserver;Initial Catalog=MyDbName;Integrated Security=True;Encrypt=True;TrustServerCertificate=True;"
    ProfileName: Staging
  - EnvironmentName: Local
    ConnectionString: "Data Source=localhost\SqlExpress;Initial Catalog=MyDbName;Integrated Security=True;Encrypt=True;TrustServerCertificate=True;"
    ProfileName: Local

Example with Auth

In this example, we are not adding any new environments, but adding auth info for Development (our local, in memory project) and Startup to act as our production environment.

Environments:
  - EnvironmentName: Development
    ProfileName: Development
    Authority: https://localhost:5010
    Audience: patients
  - EnvironmentName: Startup
    ConnectionString: "Data Source=prodserver;Initial Catalog=MyDbName;Integrated Security=True;Encrypt=True;TrustServerCertificate=True;"
    ProfileName: Prod
    Authority: https://myprod.auth0.com/
    Audience: patients

Additional Auth Resources

Example with Broker Settings

In this example, we are not adding any new environments, but adding auth info for Development (our local, in memory project) and Startup to act as our production environment.

  Environments:
  - EnvironmentName: Development
    Authority: https://localhost:5010
    Audience: patients
    AuthorizationUrl: https://localhost:5010/connect/authorize
    TokenUrl: https://localhost:5010/connect/token
    ClientId: swagger
    BrokerSettings:
      Host: localhost
      VirtualHost: /
      Username: guest
      Password: guest
  - EnvironmentName: Production
    BrokerSettings:
      Host: rmqlocalprod
      VirtualHost: dashprod
      Username: testprod
      Password: testprod

At the moment, if you are connecting to anything outside of development, you may need to make some tweaks to include SSL and a port. For example, this CloudAMQP connection:

cfg.Host("baboon.rmq.cloudamqp.com", 8983, "kalvak", h =>
{
    h.Username("kalvak:kalvak");
    h.Password("supersecretpassword");

    h.UseSsl(s =>
    {
        s.Protocol = SslProtocols.Tls12;
    });
});