skip to Main Content

In AWS ECS, when SECRET is defined in the ECS task definition, the $SECRET variable ends up in the container as a json string.

SECRET={"secret1":"value1","secret2":"value2"}

I’m able to parse out and export the json string to individual environment variables when I run this command directly in the container using this command:

eval export $(echo "$SECRET" | jq -r 'to_entries|map(""(.key)=(.value|tostring)"")|.[]' )

But, the variables don’t get set properly when I run the same command from the ‘entrypoint.sh’ script, on container run, when the container starts.
["entrypoint.sh"]

["entrypoint.sh"]

#!/usr/bin/env bash

if [ $# -gt 0 ];then
    ## If we passed a command in docker run, run it
    exec "$@"
else
    eval export $(echo "$SECRET" | jq -r 'to_entries|map(""(.key)=(.value|tostring)"")|.[]' ) 
 
    "${BUILD_DIR}"/run.sh
fi

Is it possible to parse the json string and export environment variables in an entrypoint script so that the show up in printenv?

Any guidance would be appreciated.

2

Answers


  1. I tried to reproduce this problem but your code appears to work just fine. With the following Dockerfile:

    FROM ubuntu:20.04
    
    RUN apt-get update; apt-get -y install jq; apt-get clean all
    COPY entrypoint.sh /entrypoint.sh
    ENTRYPOINT ["/entrypoint.sh"]
    

    And a slightly modified entrypoint.sh:

    #!/usr/bin/env bash
    
    if [ $# -gt 0 ];then
        ## If we passed a command in docker run, run it
        exec "$@"
    elif [ -n "$SECRET" ]; then
        eval export $(echo "$SECRET" | jq -r 'to_entries|map(""(.key)=(.value|tostring)"")|.[]' ) 
    fi
    
    echo "Extracted environment variables:"
    env | grep '^secret'
    

    If I run it like this:

    docker build -t myimage .
    docker run --rm -e 'SECRET={"secret1":"value1","secret2":"value2"}'
    myimage
    

    I get this output:

    Extracted environment variables:
    secret2=value3
    secret1=value1
    

    Your code seems to correctly extract and export to the environment the
    variables encoded in the SECRET variable.


    With respect to your comment, this works identically:

    FROM ubuntu:20.04
    
    ENV SECRET='{"secret1":"value1","secret2":"value2"}'
    RUN apt-get update; apt-get -y install jq; apt-get clean all
    COPY entrypoint.sh /entrypoint.sh
    ENTRYPOINT ["/entrypoint.sh"]
    

    And then:

    $ docker run --rm myimage
    Extracted environment variables:
    secret2=value2
    secret1=value1
    
    Login or Signup to reply.
  2. The sort of complex variable manipulation you’re describing is hard to do in a shell script, but much more straightforward in other languages. There’s really only two requirements around an entrypoint wrapper script: it must be executable given the language runtime and libraries in the image, and it must execute the command passed to it as parameters.

    So you could imagine writing a Python entrypoint wrapper script, for example. Modifying os.environ modifies the environment in the same way as the shell export built-in; os.execvp() replaces the current process with a new one, like the shell exec built-in. If you’re doing this already then you can use the standard json library for JSON parsing.

    This leads to a script like:

    #!/usr/bin/env python3
    # entrypoint.py
    
    import json
    import os
    
    # Set arbitrary environment variables from a JSON-encoded
    # $SECRET environment variable
    if 'SECRET' in os.environ:
      for k, v in json.loads(os.environ['SECRET']).items():
        os.environ[k] = v
    
    # Get the command to run from command-line arguments
    cmd = sys.argv[1:]
    if len(cmd) == 0:
      cmd = [os.path.join(os.environ['BUILD_DIR']), "run.sh"]
    
    # Replace this script with that command.
    os.execvp(cmd[0], cmd)
    

    So long as your image already has a Python interpreter and you mark this script as executable, you can use it as an ENTRYPOINT ["./entrypoint.py"] the same way you do your existing shell script.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search