I am using AWS Elastic beanstalk and want to configure different ENV var for different environment. The only way which I found was using ebextensions but ENVIRONMENT variables once set in ebextension cannot be overridden if I am deploying the same packet to multiple environments. Heard about SSM Parameter store but was not able to find a way to use is with Elastic Beanstalk.
From what I found was that SSM Parameter store can do it for EC2 instances. I don't want to restart the EC2 instance every time I update one environment variable. Also thought of writing a script which takes the value from SSM and updates environment variables in ebextentsions. But that only seems to be a hack and not the proper solution and will take to check the scenarios where it might fail
I found a solution using hooks, I created two hooks, the first one inside the hooks folder and the other one in hooksconfig (please see the attached image). The reason I added the same bash script in both folders is simple, we want to get the env variables during a new deployment and we also need to get these variables if the configuration->software environment variables are updated (we can add environment variables in both places, the Parameter Store and the EB configuration).
This code was inspired by this article. https://www.fullstackerconsulting.com/2021/09/09/how-can-i-use-the-aws-systems-manager-parameter-store-with-an-aws-elastic-beanstalk-instance-to-manage-environment-variables/
map_parameters_to_env_vars.sh
Here is the code (the same for both files)
#!/usr/bin/env bash
## https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/platforms-linux-extend.html
readarray eb_env_vars < /opt/elasticbeanstalk/deployment/env
# Check if parameter_store_path is an environment variable and get its value.
for i in ${eb_env_vars[@]}
do
if [[ $i == *"parameter_store_path"* ]]; then
parameter_store_path=$(echo $i | grep -Po "([^\=]*$)")
fi
done
if [ -z ${parameter_store_path+x} ]; then
echo "Error: parameter_store_path is unset on the Elastic Beanstalk environment properties.";
echo "You must add a property named parameter_store_path with the path prefix to your SSM parameters.";
else
echo "Success: parameter_store_path is set to '$parameter_store_path'";
TOKEN=`curl -X PUT http://169.254.169.254/latest/api/token -H "X-aws-ec2-metadata-token-ttl-seconds:21600"`
AWS_DEFAULT_REGION=`curl -H "X-aws-ec2-metadata-token:$TOKEN" -v http://169.254.169.254/latest/meta-data/placement/region`
export AWS_DEFAULT_REGION
#Create a copy of the environment variable file.
cp /opt/elasticbeanstalk/deployment/env /opt/elasticbeanstalk/deployment/custom_env_var
# Add values to the custom file
echo "AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION" >> /opt/elasticbeanstalk/deployment/custom_env_var
**## Change the region with the one you added your parameters.**
aws ssm get-parameters-by-path \
--path $parameter_store_path \
--with-decryption \
--region **eu-west-2** \
| jq --arg path "$parameter_store_path" \
-r '.Parameters | .[] | "\(.Name | sub($path; ""))=\(.Value)"' >> /opt/elasticbeanstalk/deployment/custom_env_var
cp /opt/elasticbeanstalk/deployment/custom_env_var /opt/elasticbeanstalk/deployment/env
#Remove temporary working file.
rm -f /opt/elasticbeanstalk/deployment/custom_env_var
#Remove duplicate files upon deployment.
rm -f /opt/elasticbeanstalk/deployment/*.bak
fi
We also need to add only one environment variable to the configuration->software in our EB environment.