0
votes

I am a bit confused as to how to specify - then utilise - the environment variable for a .NET Core worker service (e.g. Development, Production etc).

Here is my current startup for the service, which executes as a docker container:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.IO;
using System.Reflection;
using Amazon.SQS;
using Amazon.Extensions.NETCore.Setup;
using Microsoft.Extensions.Configuration;

namespace WorkerServiceDocker
{
    public class Program
    {
        protected static IHostEnvironment Env { get; }

        public static void Main(string[] args)
        {
            Session.InstanceGuid = Guid.NewGuid().ToString();
            Session.AwsAccessKey = Environment.GetEnvironmentVariable("AWS_ACCESS_KEY_ID");
            Session.AwsSecretKey = Environment.GetEnvironmentVariable("AWS_SECRET_ACCESS_KEY");

            File.Create("init.log").Close();
            var logWriter = new StreamWriter("init.log");
            logWriter.WriteLine("Assembly Path: " + Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));          
            logWriter.WriteLine($"Session Guid: {Session.InstanceGuid}");
            logWriter.WriteLine($"Container DateTime: {DateTime.Now}");
            logWriter.WriteLine($"Access: {Session.AwsAccessKey}");
            logWriter.WriteLine($"Secret: {Session.AwsSecretKey}");
            if (Env.IsEnvironment("development"))
            {
                logWriter.WriteLine($"DEV ENVIRONMENT");
            }
            else if (Env.IsEnvironment("production"))
            {
                logWriter.WriteLine($"PRODUCTION ENVIRONMENT");
            }
            logWriter.Dispose(); 
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    //var options = hostContext.Configuration.GetAWSOptions();
                    services.AddDefaultAWSOptions(hostContext.Configuration.GetAWSOptions());
                    services.AddHostedService<Worker>();
                    services.AddSingleton<ILogger, Logger>(); // Using my own basic wrapper around NLog for the moment, pumped to CloudWatch.
                    services.AddAWSService<IAmazonSQS>();
                });
    }
}

When run, I get 'value cannot be null' at this line:

        if (Env.IsEnvironment("development"))

I get the same 'value cannot be null' if I try Env.IsDevelopment() and so on. I was under the impression that the environment variable is set using ASPNETCORE_ENVIRONMENT so I've tried setting this the following ways:

In a settings.env file as ASPNETCORE_ENVIRONMENT=Development. As you can see, the variable is picked up at run time:

enter image description here

I have also tried setting it within the Debug configuration of the project:

enter image description here

I have even tried adding the variable as an ENV variable to the DockerFile directly. Nothing seems to work. Clearly I am not understanding how to set this properly and would appreciate some advice. I want to use the environment variable to control whether or not to use AWS Access and Secret key when launching. If in Development, use them, if in production don't and simply rely on the IAM role.

1

1 Answers

1
votes

When you run the docker container using docker run ... you specify environment variables as follows -e ASPNETCORE_ENVIRONMENT=$environment.

You can then exec into your container to see if the environment variable has been set correctly e.g.

docker exec -it container_name /bin/bash

and then echo $ASPNETCORE_ENVIRONMENT

In your dotnet app you can get the environment variable using Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")

--Follow up edit--

You can set debug environment variables in the project properties window, under Debug. enter image description here

This updates Properties/launchSettings.json enter image description here

As for the second question, I'm not too familiar with Env.IsEnvironment, but there's some documentation here. Interestingly the documentation is not using the static Env from HostingEnvironmentExtensions, but rather a function parameter in Startup Configure.

If you're having some issues; here's the steps I'd do:

  1. Confirm that the the environment variable is being set in the container correctly by exec'ing into the container.
  2. Use Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") in dotnet core.
  3. Switch to Env.IsEnvironment.