Sustainment.Extensions.Configuration.Amazon
1.0.0-ci-20250706-014624
dotnet add package Sustainment.Extensions.Configuration.Amazon --version 1.0.0-ci-20250706-014624
NuGet\Install-Package Sustainment.Extensions.Configuration.Amazon -Version 1.0.0-ci-20250706-014624
<PackageReference Include="Sustainment.Extensions.Configuration.Amazon" Version="1.0.0-ci-20250706-014624" />
<PackageVersion Include="Sustainment.Extensions.Configuration.Amazon" Version="1.0.0-ci-20250706-014624" />
<PackageReference Include="Sustainment.Extensions.Configuration.Amazon" />
paket add Sustainment.Extensions.Configuration.Amazon --version 1.0.0-ci-20250706-014624
#r "nuget: Sustainment.Extensions.Configuration.Amazon, 1.0.0-ci-20250706-014624"
#addin nuget:?package=Sustainment.Extensions.Configuration.Amazon&version=1.0.0-ci-20250706-014624&prerelease
#tool nuget:?package=Sustainment.Extensions.Configuration.Amazon&version=1.0.0-ci-20250706-014624&prerelease
AWS EC2 Metadata Configuration Provider
A powerful .NET ConfigurationProvider that seamlessly integrates AWS EC2 metadata and Elastic Beanstalk environment information into your application's IConfiguration.
Brought to you by Sustainment.com - Making American Manufacturing Great Again!
🚀 Features
- Smart Detection: Automatically detects if running on AWS Beanstalk with multiple fallback strategies
- Multi-Framework Support: Targets .NET 8, 9, and 10
- Lazy Loading: Efficient resource usage with lazy initialization of AWS clients
- IMDSv2 Compatible: Works with both enabled and disabled IMDSv2 endpoints
- Environment-Aware: Supports local development with bypass mechanisms
- Zero Configuration: Works out-of-the-box with sensible defaults
- Resilient: Multiple detection methods ensure reliability across different AWS configurations
📦 Installation
Install via NuGet Package Manager:
dotnet add package Sustainment.Extensions.Configuration.Amazon
Or via Package Manager Console:
Install-Package Sustainment.Extensions.Configuration.Amazon
🔧 Quick Start
Recommended Usage with Dependency Injection
using Sustainment.Extensions.Configuration.Amazon;
var builder = WebApplication.CreateBuilder(args);
// Add AWS Beanstalk configuration provider
builder.Configuration.AddEC2Metadata();
// Register strongly-typed EnvironmentDetails in DI container
builder.Services.AddBeanstalkEnvironmentDetails(builder.Configuration);
var app = builder.Build();
⚡ Performance Optimization for Beanstalk Deployments
For fastest startup times, set this environment variable in your Beanstalk environment:
elasticbeanstalk_environment_name=your-environment-name
This enables instant detection (microseconds vs seconds) and eliminates network calls during startup. Without this variable, the provider falls back to slower AWS API calls.
Advanced Configuration with DI
using Amazon;
using Sustainment.Extensions.Configuration.Amazon;
var builder = WebApplication.CreateBuilder(args);
// Configure with specific AWS region
builder.Configuration.AddEC2Metadata(config =>
{
config.Region = RegionEndpoint.USEast1;
config.UseInstanceProbing = true; // Enable for large AWS accounts (slower)
});
// Register strongly-typed EnvironmentDetails
builder.Services.AddBeanstalkEnvironmentDetails(builder.Configuration);
var app = builder.Build();
Web Host Builder Integration
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
// Only add if actually running on Beanstalk
if (EC2MetadataConfigurationProvider.IsRunningOnBeanstalk())
{
webBuilder.AddBeanstalkConfigurationProvider();
}
})
.ConfigureServices((context, services) =>
{
// Register strongly-typed EnvironmentDetails
services.AddBeanstalkEnvironmentDetails(context.Configuration);
});
🛠 How It Works
The configuration provider uses a hierarchical detection strategy to determine if it's running on AWS Beanstalk:
Detection Flow
Environment Variables (Instant - Recommended for Production)
- Checks
elasticbeanstalk_environment_islocal
for local bypass - ⚡ FAST PATH: Looks for
elasticbeanstalk_environment_name
explicit setting - Scans for Beanstalk-specific variables (
EB_NODE_COMMAND
,EB_CONFIG_APP_CURRENT
, etc.)
- Checks
AWS API Call (3-second timeout - Fallback)
- Attempts
DescribeRegions
API call using IAM roles - Works even when IMDSv2 is disabled for security
- Attempts
IMDSv2 Fallback (2-second timeout - Last Resort)
- Last resort check of EC2 metadata endpoint
- Gracefully handles disabled metadata service
🚀 Performance Impact
Detection Method | Startup Time | Reliability | Recommendation |
---|---|---|---|
elasticbeanstalk_environment_name set |
~1ms | 100% | ✅ Use in Production |
AWS API fallback | ~3 seconds | 95% | ⚠️ Backup method |
IMDSv2 fallback | ~2 seconds | 80% | ⚠️ Last resort |
Data Collection
When running on Beanstalk, the provider collects:
- Instance Information: Instance ID, region, tags
- Environment Details: Application name, environment name, version label
- Beanstalk Metadata: CNAME, platform ARN, solution stack
- Resource Information: Load balancer, auto-scaling groups
📋 Configuration Keys
All configuration keys are prefixed with elasticbeanstalk:
:
Key | Description | Example |
---|---|---|
elasticbeanstalk:application-name |
Beanstalk application name | my-web-app |
elasticbeanstalk:environment-name |
Environment name | production |
elasticbeanstalk:instance-id |
EC2 instance ID | i-1234567890abcdef0 |
elasticbeanstalk:environment-arn |
Environment ARN | arn:aws:elasticbeanstalk:... |
elasticbeanstalk:cname |
Environment CNAME | myapp.us-west-2.elasticbeanstalk.com |
elasticbeanstalk:version-label |
Application version | v1.2.3 |
elasticbeanstalk:platform-arn |
Platform ARN | arn:aws:elasticbeanstalk:... |
🌍 Environment Variables
Control the provider's behavior with these environment variables:
Variable | Purpose | Performance Impact | Values |
---|---|---|---|
elasticbeanstalk_environment_name |
🚀 FASTEST: Explicit environment name | ~1ms startup | Environment name string |
elasticbeanstalk_environment_islocal |
Skip AWS detection for local dev | ~1ms startup | true /false |
🚀 Production Deployment (Recommended)
Set this in your Beanstalk environment configuration:
# Enables instant detection - critical for fast startup times
elasticbeanstalk_environment_name=your-production-environment-name
How to set in Beanstalk:
- Go to your Beanstalk environment
- Configuration → Software → Environment properties
- Add:
elasticbeanstalk_environment_name
=your-environment-name
🏠 Local Development Setup
# Skip AWS detection during local development
export elasticbeanstalk_environment_islocal=true
# Or specify environment name directly for testing
export elasticbeanstalk_environment_name=my-test-environment
⚠️ Without Environment Variables
If neither variable is set, the provider will:
- Try AWS API calls (adds ~3 seconds to startup)
- Fall back to IMDSv2 check (adds ~2 seconds to startup)
- Cache the result for subsequent calls
🔍 Usage Examples
Strongly-Typed EnvironmentDetails via Dependency Injection (Recommended)
[ApiController]
[Route("[controller]")]
public class InfoController : ControllerBase
{
private readonly EnvironmentDetails _environmentDetails;
public InfoController(EnvironmentDetails environmentDetails)
{
_environmentDetails = environmentDetails;
}
[HttpGet]
public IActionResult GetEnvironmentInfo()
{
if (!_environmentDetails.IsBeanstalkEnvironment)
{
return Ok(new { Message = "Not running on Beanstalk" });
}
var info = new
{
ApplicationName = _environmentDetails.ApplicationName,
EnvironmentName = _environmentDetails.EnvironmentName,
InstanceId = _environmentDetails.InstanceId,
Version = _environmentDetails.VersionLabel,
EnvironmentArn = _environmentDetails.EnvironmentArn,
PlatformArn = _environmentDetails.PlatformArn,
Health = _environmentDetails.Health.ToString(),
Status = _environmentDetails.Status.ToString()
};
return Ok(info);
}
}
Using EnvironmentDetails in Services
public interface IDeploymentService
{
string GetCurrentDeployment();
bool IsProduction();
}
public class DeploymentService : IDeploymentService
{
private readonly EnvironmentDetails _environmentDetails;
public DeploymentService(EnvironmentDetails environmentDetails)
{
_environmentDetails = environmentDetails;
}
public string GetCurrentDeployment()
{
if (!_environmentDetails.IsBeanstalkEnvironment)
return "local-development";
return $"{_environmentDetails.ApplicationName}-{_environmentDetails.EnvironmentName}-{_environmentDetails.VersionLabel}";
}
public bool IsProduction()
{
return _environmentDetails.EnvironmentName?.ToLower().Contains("prod") == true;
}
}
// Register in DI
builder.Services.AddScoped<IDeploymentService, DeploymentService>();
Alternative: Traditional Configuration Access
[ApiController]
[Route("[controller]")]
public class LegacyController : ControllerBase
{
private readonly IConfiguration _configuration;
public LegacyController(IConfiguration configuration)
{
_configuration = configuration;
}
[HttpGet]
public IActionResult GetEnvironmentInfo()
{
var info = new
{
ApplicationName = _configuration["elasticbeanstalk:application-name"],
EnvironmentName = _configuration["elasticbeanstalk:environment-name"],
InstanceId = _configuration["elasticbeanstalk:instance-id"],
Version = _configuration["elasticbeanstalk:version-label"]
};
return Ok(info);
}
}
Conditional Logic Based on Environment
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// First register the EnvironmentDetails
services.AddBeanstalkEnvironmentDetails(Configuration);
// Use a factory pattern to conditionally register services
services.AddScoped<IEmailService>(provider =>
{
var environmentDetails = provider.GetRequiredService<EnvironmentDetails>();
if (environmentDetails.IsBeanstalkEnvironment &&
environmentDetails.EnvironmentName?.ToLower().Contains("prod") == true)
{
return new ProductionEmailService();
}
return new DevelopmentEmailService();
});
}
}
Logging with EnvironmentDetails
public class OrderService
{
private readonly ILogger<OrderService> _logger;
private readonly EnvironmentDetails _environmentDetails;
public OrderService(ILogger<OrderService> logger, EnvironmentDetails environmentDetails)
{
_logger = logger;
_environmentDetails = environmentDetails;
}
public async Task ProcessOrder(Order order)
{
using var scope = _logger.BeginScope(new Dictionary<string, object>
{
["ApplicationName"] = _environmentDetails.ApplicationName,
["EnvironmentName"] = _environmentDetails.EnvironmentName,
["InstanceId"] = _environmentDetails.InstanceId,
["Version"] = _environmentDetails.VersionLabel
});
_logger.LogInformation("Processing order {OrderId}", order.Id);
// Process order...
}
}
🏗 Advanced Scenarios
Instance Probing for Large Accounts
For AWS accounts with many Beanstalk environments, enable instance probing:
builder.Configuration.AddEC2Metadata(config =>
{
config.UseInstanceProbing = true; // Slower but more thorough
});
Note: This iterates through all environments to find the current instance. Use only when environment name tags are not available.
Custom AWS Region
using Amazon;
builder.Configuration.AddEC2Metadata(config =>
{
config.Region = RegionEndpoint.EUWest1;
});
Conditional Registration
// Only register when actually needed
if (EC2MetadataConfigurationProvider.IsRunningOnBeanstalk())
{
builder.Configuration.AddEC2Metadata();
// Register the strongly-typed EnvironmentDetails
builder.Services.AddBeanstalkEnvironmentDetails(builder.Configuration);
// Also register AWS-specific services
builder.Services.AddAWSParameterStore();
}
else
{
// For local development, register an empty EnvironmentDetails
builder.Services.AddSingleton(new EnvironmentDetails());
}
EnvironmentDetails Properties
The EnvironmentDetails
object provides these properties:
public class EnvironmentDetails
{
public string ApplicationName { get; set; }
public string Cname { get; set; }
public DateTimeOffset DateCreated { get; set; }
public DateTimeOffset DateUpdated { get; set; }
public string Description { get; set; }
public string EndpointUrl { get; set; }
public string EnvironmentArn { get; set; }
public string EnvironmentId { get; set; }
public string EnvironmentName { get; set; }
public EnvironmentHealth Health { get; set; }
public EnvironmentHealthStatus HealthStatus { get; set; }
public string InstanceId { get; set; }
public string PlatformArn { get; set; }
public EnvironmentResourcesDescription Resources { get; set; }
public string SolutionStackName { get; set; }
public EnvironmentStatus Status { get; set; }
public string TemplateName { get; set; }
public string VersionLabel { get; set; }
// Convenience property
public bool IsBeanstalkEnvironment => !string.IsNullOrWhiteSpace(EnvironmentArn);
}
🚦 Build Status
Branch | Status | Version |
---|---|---|
Main | ||
Develop |
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Development Setup
- Clone the repository
- Ensure you have .NET 8+ SDK installed
- Run
dotnet restore
in the src directory - Build with
dotnet build
- Run tests with
dotnet test
Running Locally
Set the local bypass environment variable:
export elasticbeanstalk_environment_islocal=true
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙋♂️ Support
If you encounter any issues or have questions:
- Check the Issues page
- Create a new issue with detailed information
- For urgent matters, contact the maintainers
🔗 Related Projects
⭐ If this project helped you, please consider giving it a star!
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- AWSSDK.EC2 (>= 3.7.456)
- AWSSDK.ElasticBeanstalk (>= 3.7.400.173)
- EasyAF.Configuration (>= 3.0.1-CI-20250630-230212)
- Microsoft.Extensions.Configuration (>= 8.0.0)
-
net8.0
- AWSSDK.EC2 (>= 3.7.456)
- AWSSDK.ElasticBeanstalk (>= 3.7.400.173)
- EasyAF.Configuration (>= 3.0.1-CI-20250630-230212)
- Microsoft.Extensions.Configuration (>= 8.0.0)
-
net9.0
- AWSSDK.EC2 (>= 3.7.456)
- AWSSDK.ElasticBeanstalk (>= 3.7.400.173)
- EasyAF.Configuration (>= 3.0.1-CI-20250630-230212)
- Microsoft.Extensions.Configuration (>= 8.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Sustainment.Extensions.Configuration.Amazon:
Package | Downloads |
---|---|
Serilog.Enrichers.Amazon
A Serilog Enricher to add AWS Beanstalk runtime metadata to your logs. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
1.0.0-ci-20250706-014624 | 42 | 7/6/2025 |