to StackOverflow
to StackOverflow

Reputation: 124794

How can applications running in AWS know their environment?

I have applications of different kinds running on different types of AWS hosts, including:

  1. Running on EC2 instances (Windows and Linux)
  2. Running on auto-scaled EC2 instances
  3. Running on ElasticBeanstalk (ASP.NET and ASP.NET Core)
  4. Running in Linux Docker containers on Fargate
  5. Lambda functions

I want my applications to be able to detect the environment they are running in (Development, Staging, Production) so they can load the appropriate configuration on startup, e.g. from an environment-specific folder in a Parameter Store hierarchy.

Ideally a simple API that I can call (something like GetCurrentEnvironment()).

What's the best way to achieve this in a way that's common to all of the above host types?

All my AWS resources are tagged with the environment name. Is there an API that can be called from all of the above host types that would return the tag value for the current host?

Otherwise I guess a solution would be to set an environment variable "CurrentEnvironment" or similar during creation of the host.

I guess this is a common requirement so I'd be interested to know how others do it.

Upvotes: 2

Views: 462

Answers (2)

Matt D
Matt D

Reputation: 3506

Tagging is the most widely supported method.

However there are more natively supported methods in each type of environment.


In ElasticBeanstalk you can set Environment Properties for the Application Environment that can be read from Web.config appSettings in the .NET Application.

ElasticBeanstalk > [Application Name] > [Environment Name] > Configuration > Software

Add an Application Property with a Name and Value, for example:

  • Name = ReleaseEnvironment; Value = Staging
  • Name = EnvironmentSecretKey; Value = SomeSecureKeyThatGainsAccessToASecureParameterStore

When Elastic Beanstalk deploys the Application to the instances, it adds this to the Web.config file in the <appSettings> section.

So within the Application use the following code to read the value:

var environmentName = ConfigurationManager.AppSettings["ReleaseEnvironment"];

Then you can get your environment specific properties from your Parameter Store using that value. You could also pass numerous values that way and avoid the parameter store if its more appropriate.

Other EB Deployed languages are also supported through Environment Variables: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environments-cfg-softwaresettings.html


In Lambda, you can set Environment Variables in the config and read them in the Lambda Container: https://docs.aws.amazon.com/lambda/latest/dg/env_variables.html


In ECS/Fargate, you can pass the environment properties and read them within the container using describe-task-definition.


In EC2, you need to use the metadata service to read the user-data:

user_data=`curl http://169.254.169.254/latest/user-data/`

See: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

Upvotes: 1

Yogesh_D
Yogesh_D

Reputation: 18809

There is no silver bullet for retrieving the metadata for these services. As the nature of the services itself is quite different.

For EC2 based deployments can use the metadata service or corresponding sdks.

Autoscaled EC2 instances are no different that regular EC2 instances.

For Beanstalk, as technically a ec2 is used you can use the metadata service. However, I would rather recommend that you set the relevant items are configurations in EBS. Example say you have a application that you want to setup woth 4GB of heapspace for a Prod type of deployment and 1GB for Dev Type. You can do that during deployment.

The same goes for Lambda and containers. Lambda does have a way to get some metadata, however, even for a lambda you will know of the config/sizing of the lambda during deployment and can use that to set relevant env variables.

So you can have the deployment scripts/jobs of these elements look at the parameter store and configure the relevant services during deployment. This will ensure that you have simpler apps and the CI/CD pipelines that you have do their share of work in setting up apps.

Tag in my opinion should be used for created metadata that you understand, what service this resource belongs to, what is its use etc.

Upvotes: 1

Related Questions