18

Как получить переменные окружения из эластичного beanstalk в приложение mpc core asp.net? Я добавил папку .ebextensions с app.config файла в нем со следующим:Переменные среды AWS Elastic Beanstalk в ASP.NET Core 1.0

option_settings: 
- option_name: HelloWorld 
    value: placeholder 

- option_name: ASPNETCORE_ENVIRONMENT 
    value: placeholder 

Папка .ebextensions входит в пакет публикации.

На развертывание, как переменные видимы в АМС elasticbeanstalk консоли в разделе Конфигурация> Software Configuration> Переменные среды

Однако, когда я пытаюсь прочитать переменные в приложении, ни один из приведенных ниже вариантов не работают:

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

Любые идеи о том, что я могу пропустить? Благодарю.

+0

Похожая проблема возникает при развертывании приложений .NET Standard с использованием 'aws-windows-deployment-manifest.json': https://serverfault.com/questions/892493/windows-custom-elastic-beanstalk-deployment -missing-environment-variables – andrewf

ответ

13

Была такая же проблема, и только что получил ответ от поддержки AWS по этой проблеме. По-видимому, переменные среды неправильно внедряются в приложения ASP.NET Core в эластичном бобовом стебле.

Насколько я знаю, они работают над устранением проблемы.

Обходным способом является разбор C:\Program Files\Amazon\ElasticBeanstalk\config\containerconfiguration в конструктор конфигурации. Этот файл является частью вашей эластичной основы beanstalk и должен быть доступен при развертывании вашего проекта.

Сначала добавьте файл:

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

Затем доступ к значениям:

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

Любезность Г.П. от Amazon Web Services

+0

На сегодняшний день эта ошибка все еще присутствует. Используя этот обходной путь, вы можете реализовать свой собственный «ConfigurationProvider» и решить эту проблему. – Gabriel

+0

Следует отметить, что утилиты в Amazon.Extensions.NETCore.Setup игнорируют конфигурацию и пытаются напрямую прочитать из среды. Вам придется вручную добавить AWSCredentials, RegionEndpoint и любые сервисы, которые вы потребляете в качестве одиночных. – JeffreyABecker

+8

Тот факт, что это необходимо, смехотворно, и он должен смущать AWS (которого я обычно люблю и уважаю), что он все еще нефиксирован, спустя 12 месяцев после выпуска ASP.NET Core 1.0, несмотря на то, что Amazon [утверждает, что поддерживает ASP.NET Core на Elastic Beanstalk и предложите учебные пособия о том, как развернуть его там] (http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/dotnet-core-tutorial.html). Это * базовая * функциональность, возможно, исправленная через пару дней стажером, и это показывает довольно ужасное качество обслуживания, чтобы оно просто осталось сломанным в течение года. Тем не менее, по крайней мере, этот ответ работает; +1. –

5

Я воспользовался другим ответом, чтобы создать удобное обходное решение для загрузки свойств среды из Elastic Beanstalk непосредственно в конфигурацию вашего приложения ASP.NET Core.

Для ASP.NET 2.0 Ядра - редактировать ваш Program.cs

Обратите внимание, что эта WebHost сборка была взята из исходного кода WebHostBuilder.CreateDefaultBuilder()

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]); 
     } 
    } 
} 

Для ASP.NET Core 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; 
    } 
1

Над solu не помогло мне загрузить файл конфигурации на основе настроек среды. Так вот мое решение AWS ElasticBeansTalk «взломать»

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; 
    } 
-1

Вы можете создать реализацию Microsoft.Extensions.Configuration.

Также доступен на 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; 
     } 
    } 
} 

Затем используйте с 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(); 
4

Я просто реализовал немного другое решение, которое впрыскивает переменные 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); 
    } 
} 

Просто позвоните SetEbConfig(); перед тем, как создать свой веб-хост. С помощью этого решения также AWS SDK корректно считывает его параметры, такие как AWS_ACCESS_KEY_ID.

+0

Очевидно, проблема с эластичным бобовым сундуком еще не установлена. Ваше решение было очень полезно для быстрого развертывания моего кода и быстрой работы! – victorvartan

Смежные вопросы