I have a spring-boot application for which I need to specify graphite server and port (to send metrics). For that to work, I have to install and configure statsd
. I do that using the ebextensions
file.
commands:
01_nodejs_install:
command: sudo yum -y install nodejs npm --enablerepo=epel
ignoreErrors: true
02_mkdir_statsd:
command: mkdir /home/ec2-user/statsd
ignoreErrors: true
03_fetch_statsd:
command: git clone https://github.com/etsy/statsd.git /home/ec2-user/statsd
ignoreErrors: true
04_change_example_config:
command: "cat exampleConfig.js | sed 's/2003/<graphite-port>/g' | sed 's/graphite.example.com/<my-graphite-server>/g' > config.js"
cwd: /home/ec2-user/statsd
05_run_statsd:
command: setsid node stats.js config.js >/dev/null 2>&1 < /dev/null &
cwd: /home/ec2-user/statsd
The problem with this configuration is that I can specify only 1 graphite server here for all environments.
So I decided to move commands 04 and 05 into container_commands
. I am thinking of defining an environment variable called ENV_NAME
using the beanstalk console/UI, and set it to dev
, qa
, or prod
according to the environment. Then I can use test
option of container_commands
to run 04 and 05 commands only for specific environment based on this ENV_NAME
.
So my problem is - how can I use AWS console to define environment variable? I tried using Beanstalk console to define my variable as explained in the documentation here but it did not work. I also found (see the answer with 5 upvotes) that this method sets only JVM properties and not ENV variables.
I cannot define environment variable using ebextensions
because then I'll have the same problem - can't define different env vars for different envs :)
So I need help with either:
ENV_NAME
environment variable using beanstalk UI.Or
ENV_NAME
system property in container_commands
to condition whether or not to run the command based on the value of ENV_NAME
.And in case you know a simpler/better way to specify different Graphite servers for different environments, please feel free to pitch in.
You can add AWS Elastic Beanstalk configuration files ( . ebextensions ) to your web application's source code to configure your environment and customize the AWS resources that it contains. Configuration files are YAML- or JSON-formatted documents with a . config file extension that you place in a folder named .
On AWS, open Elastic Beanstalk. Go to your Application > Environment > Configuration > Software Configuration . Under Environment Properties you will find a list of properties you can configure. These variables will be attached to the process.
The way I resolved this was to define ENV_NAME
as dev
and prod
in dev and prod environments respectively and use the following ebextensions
configuration.
commands:
01_nodejs_install:
command: sudo yum -y install nodejs npm --enablerepo=epel
ignoreErrors: true
02_mkdir_statsd:
command: mkdir /home/ec2-user/statsd
ignoreErrors: true
03_fetch_statsd:
command: git clone https://github.com/etsy/statsd.git /home/ec2-user/statsd
ignoreErrors: true
container_commands:
04a_container_change_example_config:
command: "cat exampleConfig.js | sed 's/2003/<graphite-dev-port>/g' | sed 's/graphite.example.com/<graphite-dev-host>/g' > config.js"
cwd: /home/ec2-user/statsd
test: '[ "${ENV_NAME}" == "dev" ]'
04b_container_change_example_config:
command: "cat exampleConfig.js | sed 's/2003/<graphite-prod-port>/g' | sed 's/graphite.example.com/<graphite-prod-host>/g' > config.js"
cwd: /home/ec2-user/statsd
test: '[ "${ENV_NAME}" == "prod" ]'
05_run_statsd:
command: setsid node stats.js config.js >/dev/null 2>&1 < /dev/null &
cwd: /home/ec2-user/statsd
Using test
I can condition the execution of the container command
on the ENV_NAME
property which I have already defined in the beanstalk environment.
In addition to the answer by @Nik:
Instead of manually adding an environment variable ENV_NAME
, you could also obtain the actual environment name and store that in ENV_NAME
automatically. This is achieved using option_settings
in your ebextensions
config file.
For example:
option_settings:
aws:elasticbeanstalk:application:environment:
ENV_NAME: '`{ "Ref" : "AWSEBEnvironmentName" }`' # assign the actual env name to ENV_NAME
container_commands:
0100_execute_only_in_dev:
command: echo "this is the development environment" # this will turn up in ebactivity.log
test: '[[ $ENV_NAME = "dev" ]]'
A side note, for those who are not so familiar with shell scripting, like me: the spaces in the test expression are important (example).
As of 2021, Amazon Linux 2 is the new standard. Amazon Linux 2 uses platform hooks instead of the container_commands
in .ebextensions
.
Here's a bash script equivalent to the 0100_execute_only_in_dev
container command defined above, that can be used as a platform hook on Amazon Linux 2:
0100_execute_only_in_dev.sh
#!/bin/bash
if [ $ENV_NAME = "dev" ]
# the following output will end up in "/var/log/eb-hooks.log"
then echo "this is the development environment"
fi
The shell script requires execution permission, as described here, and can be placed in any of the subdirectories of .platform/hooks
and/or .platform/confighooks
, in your source bundle, depending on the applicable deployment phase (prebuild
, predeploy
, or postdeploy
). See the deployment workflow for more information. It also helps to inspect /var/log/eb-engine.log
, to see what exactly happens during the deployment.
Note that platform hooks also have access to the EB environment properties.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With