amazon-elastic-beanstalkaws-parameter-store

Using SSM Parameter store in AWS Elastic Beanstalk


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


Solution

  • 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