阅读背景:

AWS弹性豆茎环境变量在ASP。1.0网络核心

来源:互联网 

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 following:

如何从弹性beanstalk获得环境变量到asp.net核心mvc应用程序?我在里面添加了一个. ebextense文件夹,里面有app.config文件,下面是这样的:

option_settings:
- option_name: HelloWorld
  value: placeholder

- option_name: ASPNETCORE_ENVIRONMENT
  value: placeholder

The .ebextensions folder is included in the publish package.

在发布包中包含. ebex文件夹。

On deployment, both the variables are visible in the aws elasticbeanstalk console at Configuration > Software Configuration > Environment Variables

在部署时,两个变量都可以在配置>软件配置>环境变量的aws elasticbeanstalk控制台中看到

However, when I try to read the variables in the application, none of the below options are working:

然而,当我尝试阅读应用程序中的变量时,以下选项都没有起作用:

Environment.GetEnvironmentVariable("HelloWorld") // In controller
Configuration["HelloWorld"] // In startup.cs

Any ideas on what I could be missing? Thanks.

有什么想法吗?谢谢。

7 个解决方案

#1


15  

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.

有同样的问题,刚刚收到AWS支持的回复。显然,环境变量没有正确地注入到ASP中。NET核心应用在弹性豆茎。

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.

解决方法是解析C:\Program Files\Amazon\ ElasticBeanstalk \ config \ containerconfiguration配置构建器。该文件是您的弹性beanstalk环境的一部分,在部署您的项目时应该可以访问。

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

来自Amazon Web Services的G.P.。

#2


8  

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():

我刚刚实现了另一个解决方案,它将beanstalk环境变量注入到程序中,以便您可以通过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.

简单地调用SetEbConfig();在构建高手写了。有了这个解决方案,AWS SDK也可以正确读取AWS_ACCESS_KEY_ID之类的设置。

#3


7  

I implemented the other answer to create a convenient workaround to load the environment properties from Elastic Beanstalk directly into your ASP.NET Core app configuration.

我实现了另一个答案,以创建一个方便的工作区,将环境属性从弹性Beanstalk直接加载到您的ASP中。网络核心应用程序配置。

For ASP.NET Core 2.0 - edit your Program.cs

ASP。NET核心2.0 -编辑你的程序。

Note that this WebHost build was taken from the source code of WebHostBuilder.CreateDefaultBuilder()

注意,这个WebHost构建是从WebHostBuilder.CreateDefaultBuilder()的源代码中获取的。

https://github.com/aspnet/MetaPackages/blob/dev/src/Microsoft.AspNetCore/WebHost.cs

https://github.com/aspnet/MetaPackages/blob/dev/src/Microsoft.AspNetCore/WebHost.cs

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace NightSpotAdm
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args)
        {
            // TEMP CONFIG BUILDER TO GET THE VALUES IN THE ELASTIC BEANSTALK CONFIG
            IConfigurationBuilder tempConfigBuilder = new ConfigurationBuilder();

            tempConfigBuilder.AddJsonFile(
                @"C:\Program Files\Amazon\ElasticBeanstalk\config\containerconfiguration",
                optional: true,
                reloadOnChange: true
            );

            IConfigurationRoot tempConfig = tempConfigBuilder.Build();

            Dictionary<string, string> ebConfig = ElasticBeanstalk.GetConfig(tempConfig);

            // START WEB HOST BUILDER
            IWebHostBuilder builder = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory());

            // CHECK IF EBCONFIG HAS ENVIRONMENT KEY IN IT
            // IF SO THEN CHANGE THE BUILDERS ENVIRONMENT
            const string envKey = "ASPNETCORE_ENVIRONMENT";

            if (ebConfig.ContainsKey(envKey))
            {
                string ebEnvironment = ebConfig[envKey];
                builder.UseEnvironment(ebEnvironment);
            }

            // CONTINUE WITH WEB HOST BUILDER AS NORMAL
            builder.ConfigureAppConfiguration((hostingContext, config) =>
                {
                    IHostingEnvironment env = hostingContext.HostingEnvironment;

                    // ADD THE ELASTIC BEANSTALK CONFIG DICTIONARY
                    config.AddJsonFile(
                            "appsettings.json",
                            optional: true,
                            reloadOnChange: true
                        )
                        .AddJsonFile(
                            $"appsettings.{env.EnvironmentName}.json",
                            optional: true,
                            reloadOnChange: true
                        )
                        .AddInMemoryCollection(ebConfig);

                    if (env.IsDevelopment())
                    {
                        Assembly appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
                        if (appAssembly != null)
                        {
                            config.AddUserSecrets(appAssembly, optional: true);
                        }
                    }

                    config.AddEnvironmentVariables();

                    if (args != null)
                    {
                        config.AddCommandLine(args);
                    }
                })
                .ConfigureLogging((hostingContext, logging) =>
                {
                    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                    logging.AddConsole();
                    logging.AddDebug();
                })
                .UseIISIntegration()
                .UseDefaultServiceProvider(
                    (context, options) => { options.ValidateScopes = context.HostingEnvironment.IsDevelopment(); })
                .ConfigureServices(
                    services =>
                    {
                        services.AddTransient<IConfigureOptions<KestrelServerOptions>, KestrelServerOptionsSetup>();
                    });

            return builder.UseStartup<Startup>().Build();
        }
    }

    public static class ElasticBeanstalk
    {
        public static Dictionary<string, string> GetConfig(IConfiguration configuration)
        {
            return
                configuration.GetSection("iis:env")
                    .GetChildren()
                    .Select(pair => pair.Value.Split(new[] { '=' }, 2))
                    .ToDictionary(keypair => keypair[0], keypair => keypair[1]);
        }
    }
}

For ASP.NET Core 1.0

ASP。1.0网络核心

    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)
            .AddJsonFile(@"C:\Program Files\Amazon\ElasticBeanstalk\config\containerconfiguration", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables();

        var config = builder.Build();

        builder.AddInMemoryCollection(GetEbConfig(config));

        Configuration = builder.Build();
    }

    private static Dictionary<string, string> GetEbConfig(IConfiguration configuration)
    {
        Dictionary<string, string> dict = new Dictionary<string, string>();

        foreach (IConfigurationSection pair in configuration.GetSection("iis:env").GetChildren())
        {
            string[] keypair = pair.Value.Split(new [] {'='}, 2);
            dict.Add(keypair[0], keypair[1]);
        }

        return dict;
    }

#4


1  

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

上面的解决方案并不能帮助我根据环境设置加载配置文件。这是我的解决方案AWS弹性豆茎"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;
    }

#5


0  

.NET Core 2 + posrgresql RDS

.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.

继@sebastian的伟大回答之后,我发现这些设置位于文件的不同部分,即插件: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:

相关的(已编校的;-)JSON如下:

{
    "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...)

(这个回复是分开的,因为我没有代表评论…)

#6


0  

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

不必解析containerconfiguration,您可以利用ebextense选项将变量设置为部署过程的一部分:

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.

这将设置一个全局环境变量作为应用程序部署的一部分。这个变量用例得到了Microsoft的正式支持和文档化。

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

在部署应用程序后,您可以在EC2实例中对设置进行正确的设置:

#7


-1  

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

您可以创建Microsoft.Extensions.Configuration的实现。

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

也可从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:

然后与你的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();

分享到: