asp.net mvc - Variables de entorno AWS Elastic Beanstalk en ASP.NET Core 1.0
asp.net-mvc asp.net-core (5)
Tuve el mismo problema, y acabo de recibir una respuesta del soporte de AWS sobre este tema. Aparentemente, las variables de entorno no se inyectan correctamente en las aplicaciones ASP.NET Core en beanstalk elástico.
Por lo que sé, están trabajando para solucionar el problema.
La solución consiste en analizar C:/Program Files/Amazon/ElasticBeanstalk/config/containerconfiguration
en el constructor de configuración. Este archivo es parte de su entorno elástico Beanstalk y debe ser accesible al implementar su proyecto.
Primero agrega el archivo:
var builder = new ConfigurationBuilder()
.SetBasePath("C://Program Files//Amazon//ElasticBeanstalk//config")
.AddJsonFile("containerconfiguration", optional: true, reloadOnChange: true);
Luego acceda a los valores:
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
}
}
Cortesía de GP de Amazon Web Services
¿Cómo obtengo variables de entorno del beanstalk elástico en una aplicación asp.net core mvc? He agregado una carpeta .ebextensions con el archivo app.config con lo siguiente:
option_settings:
- option_name: HelloWorld
value: placeholder
- option_name: ASPNETCORE_ENVIRONMENT
value: placeholder
La carpeta .ebextensions está incluida en el paquete de publicación.
En la implementación, ambas variables son visibles en la consola de aws elástico en la configuración> Configuración de software> Variables de entorno
Sin embargo, cuando intento leer las variables en la aplicación, ninguna de las siguientes opciones funciona:
Environment.GetEnvironmentVariable("HelloWorld") // In controller
Configuration["HelloWorld"] // In startup.cs
¿Alguna idea sobre lo que podría estar perdiendo? Gracias.
La solución anterior no me ayudó a cargar el archivo de configuración en función de la configuración del entorno. Así que aquí está mi solución AWS ElasticBeansTalk "hackear"
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;
}
Implementé la otra respuesta para crear una solución conveniente para cargar las propiedades del entorno de Elastic Beanstalk directamente en la configuración de la aplicación ASP.NET Core.
Para ASP.NET Core 2.0: edite su Program.cs
Tenga en cuenta que esta compilación de WebHost se tomó del código fuente de 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]);
}
}
}
Para 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;
}
Puede crear una implementación de Microsoft.Extensions.Configuration
.
También disponible en 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;
}
}
}
Luego use con su 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();
Acabo de implementar una solución ligeramente diferente que inyecta las variables de entorno beanstalk al programa para que pueda acceder a ellas por 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);
}
}
Simplemente llame a SetEbConfig();
antes de construir tu webhost. Con esta solución, AWS SDK también lee su configuración como AWS_ACCESS_KEY_ID correctamente.