AWS Elastic Beanstalk environment variables in ASP.NET Core 1.0

后端 未结 9 2003
误落风尘
误落风尘 2020-12-01 02:59

How do I get environment variables from elastic beanstalk into an asp.net core mvc application? I have added a .ebextensions folder with app.config file in it with the follo

相关标签:
9条回答
  • 2020-12-01 03:17

    I just implemented a slightly other solution which injects the beanstalk environment variables to the program so that you may access them by Environment.GetEnvironmentVariable():

    private static void SetEbConfig()
    {
        var tempConfigBuilder = new ConfigurationBuilder();
    
        tempConfigBuilder.AddJsonFile(
            @"C:\Program Files\Amazon\ElasticBeanstalk\config\containerconfiguration",
            optional: true,
            reloadOnChange: true
        );
    
        var configuration = tempConfigBuilder.Build();
    
        var ebEnv =
            configuration.GetSection("iis:env")
                .GetChildren()
                .Select(pair => pair.Value.Split(new[] { '=' }, 2))
                .ToDictionary(keypair => keypair[0], keypair => keypair[1]);
    
        foreach (var keyVal in ebEnv)
        {
            Environment.SetEnvironmentVariable(keyVal.Key, keyVal.Value);
        }
    }
    

    Simply call SetEbConfig(); before building your webhost. With this solution, also AWS SDK does read it's settings like AWS_ACCESS_KEY_ID correctly.

    0 讨论(0)
  • 2020-12-01 03:22

    Above solution doesnt helped me to load config file based on enviroment settings. So here is my solution AWS ElasticBeansTalk "hack"

        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{GetEnvVariableAWSBeansTalkHack(env)}.json", optional: true)
                .AddEnvironmentVariables();
    
            Configuration = builder.Build();
        }
    
        private static string GetEnvVariableAWSBeansTalkHack(IHostingEnvironment env)
        {
            var config = new ConfigurationBuilder()
               .AddJsonFile(@"C:\Program Files\Amazon\ElasticBeanstalk\config\containerconfiguration", optional: true, reloadOnChange: true).Build();
    
            Dictionary<string, string> dict = new Dictionary<string, string>();
            foreach (IConfigurationSection pair in config.GetSection("iis:env").GetChildren())
            {
                string[] keypair = pair.Value.Split(new[] { '=' }, 2);
                dict.Add(keypair[0], keypair[1]);
            }
    
            return dict.ContainsKey("ASPNETCORE_ENVIRONMENT") 
                    ? dict["ASPNETCORE_ENVIRONMENT"] 
                    : env.EnvironmentName;
        }
    
    0 讨论(0)
  • 2020-12-01 03:24

    Had the same problem, and just received a reply from AWS support about this issue. Apparently environment variables are not properly injected into ASP.NET Core applications in elastic beanstalk.

    As far as I know, they're working to fix the problem.

    The workaround is to parse C:\Program Files\Amazon\ElasticBeanstalk\config\containerconfiguration into the configuration builder. This file is part of your elastic beanstalk environment and should be accessible upon deploying your project.

    First add the file:

    var builder = new ConfigurationBuilder()
        .SetBasePath("C:\\Program Files\\Amazon\\ElasticBeanstalk\\config")
        .AddJsonFile("containerconfiguration", optional: true, reloadOnChange: true);
    

    Then access the values:

    var env = Configuration.GetSection("iis:env").GetChildren();
    
    foreach (var envKeyValue in env)
    {
        var splitKeyValue = envKeyValue.Value.Split('=');
        var envKey = splitKeyValue[0];
        var envValue = splitKeyValue[1];
        if (envKey == "HelloWorld")
        {
            // use envValue here
        }
    }
    

    Courtesy of G.P. from Amazon Web Services

    0 讨论(0)
  • 2020-12-01 03:24

    Instead of having to parse the containerconfiguration you can leverage the ebextensions options to set the variable as part of your deploy process:

    commands:
      set_environment: 
        command: setx ASPNETCORE_ENVIRONMENT "Development" /M
    

    This will set a global environment variable as part of your application deployment. This variable use-case is officially supported and documented by Microsoft.

    After deploying your app you can verify the setting is set correctly in the EC2 instance:

    0 讨论(0)
  • 2020-12-01 03:25

    .NET Core 2 + posrgresql RDS

    Further to @sebastian's great answer above, I found that the settings were in a different part of the file, viz. plugins:rds:env.

    Also there was no need to split on =, so the parsing code I have is:

    private static void SetEbConfig()
            {
                var tempConfigBuilder = new ConfigurationBuilder();
    
                tempConfigBuilder.AddJsonFile(
                    @"C:\Program Files\Amazon\ElasticBeanstalk\config\containerconfiguration",
                    optional: true,
                    reloadOnChange: true
                );
    
                var configuration = tempConfigBuilder.Build();
    
                var ebEnv = configuration.GetSection("plugins:rds:env")
                                            .GetChildren()
                                            .ToDictionary(child => child.Key, child => child.Value);
    
                foreach (var keyVal in ebEnv)
                {
                    Environment.SetEnvironmentVariable(keyVal.Key, keyVal.Value);
                }
            }
    

    The relevant (and redacted ;-)) JSON is as follows:

    {
        "plugins": {
            "rds": {
                "Description": "RDS Environment variables",
                "env": {
                    "RDS_PORT": "....",
                    "RDS_HOSTNAME": "....",
                    "RDS_USERNAME": "....",
                    "RDS_DB_NAME": "....",
                    "RDS_PASSWORD": "...."
                }
            }
        }
    }
    

    (This reply is separate since I don't have rep to comment...)

    0 讨论(0)
  • 2020-12-01 03:27

    You can create an implementation of Microsoft.Extensions.Configuration.

    Also available at https://gist.github.com/skarllot/11e94ed8901a9ddabdf05c0e5c08dbc5.

    using Microsoft.Extensions.Configuration;
    using Newtonsoft.Json.Linq;
    using System.IO;
    using System.Linq;
    
    namespace Microsoft.Extensions.Configuration.AWS
    {
        public class AmazonEBConfigurationProvider : ConfigurationProvider
        {
            private const string ConfigurationFilename = @"C:\Program Files\Amazon\ElasticBeanstalk\config\containerconfiguration";
    
            public override void Load()
            {
                if (!File.Exists(ConfigurationFilename))
                    return;
    
                string configJson;
                try
                {
                    configJson = File.ReadAllText(ConfigurationFilename);
                }
                catch
                {
                    return;
                }
    
                var config = JObject.Parse(configJson);
                var env = (JArray)config["iis"]["env"];
    
                if (env.Count == 0)
                    return;
    
                foreach (var item in env.Select(i => (string)i))
                {
                    int eqIndex = item.IndexOf('=');
                    Data[item.Substring(0, eqIndex)] = item.Substring(eqIndex + 1);
                }
            }
        }
    
        public class AmazonEBConfigurationSource : IConfigurationSource
        {
            public IConfigurationProvider Build(IConfigurationBuilder builder)
            {
                return new AmazonEBConfigurationProvider();
            }
        }
    
        public static class AmazonEBExtensions
        {
            public static IConfigurationBuilder AddAmazonElasticBeanstalk(this IConfigurationBuilder configurationBuilder)
            {
                configurationBuilder.Add(new AmazonEBConfigurationSource());
                return configurationBuilder;
            }
        }
    }
    

    Then use with your ConfigurationBuilder:

    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", true, true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true)
        .AddAmazonElasticBeanstalk()    // <-- Merge with other sources
        .AddEnvironmentVariables();
    
    0 讨论(0)
提交回复
热议问题