Using SSM Parameter store in AWS Elastic Beanstalk
Asked Answered
D

3

7

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

Dicks answered 7/8, 2019 at 5:29 Comment(1)
Hi @Amol, I am facing the same problem, did you find a solution?Swot
T
1

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).

enter image description here

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.

enter image description here

Trinetta answered 31/10, 2022 at 5:19 Comment(0)
G
2

I wouldn't consider the solution you proposed a hack. We have multiple services following a similar pattern and it's very effective.

Take a look at ssm-env. You should use this tool in your ebextensions instead of trying to rebuild the functionality.

Gloomy answered 9/8, 2019 at 9:47 Comment(0)
T
1

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).

enter image description here

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.

enter image description here

Trinetta answered 31/10, 2022 at 5:19 Comment(0)
A
1

Values from the Systems Manager (SSM) Parameter Store can be used in .ebextensions (and CloudFormation templates) with the help of dynamic references.

Here's an example showing how to get a value from SSM Parameter Store in an .ebextensions/options.config file:

option_settings:
  aws:elasticbeanstalk:application:environment:
    # some value from the SSM Parameter Store
    MY_SSM_PARAMETER: '{{resolve:ssm:/my/parameter/name}}'
    # BONUS: name of the *current* elastic beanstalk environment
    # (not SSM, but useful when dealing with multiple environments)
    MY_ENV_NAME: '`{ "Ref" : "AWSEBEnvironmentName" }`'

For contrast, this example also gets the current environment name, using Elastic Beanstalk resources instead of SSM. This could be useful in the OP's case.

The OP's statement is not entirely true:

... but ENVIRONMENT variables once set in ebextension cannot be overridden ...

Environment properties defined in .ebextensions can be overridden, as explained in configuration-options-precedence.

For example, if the value of one of these environment properties is modified using the Elastic Beanstalk web-console or aws cli, that modified value will take precedence during subsequent deployments.

Autobahn answered 2/7 at 11:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.