How do I set dynamic environment variables for Docker multi-stage builds in Elastic Beanstalk?

5 minuto de leitura
0

I want to set dynamic environment variables for Docker multi-stage builds in AWS Elastic Beanstalk.

Short description

You can set hardcoded or static variables in the Dockerfile only in build stages. For example, use the ENV key to set static variables. Other containers in the Dockerfile that you build in earlier stages can't access Elastic Beanstalk variables. To set dynamic environment variables during a multi-stage build, use the AWS Systems Manager AWS::SSM::Parameter resource or an Elastic Beanstalk variable. Because you're required to set the variable only one time, it's a best practice to use the SSM parameter.

Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshoot AWS CLI errors. Also, make sure that you're using the most recent AWS CLI version.

Resolution

Note: In the following example, a React application is installed on Alpine Linux. You can use any distribution package manager to build your container and install the required packages.

Use an SSM parameter

Note: To allow the Amazon Elastic Compute Cloud (Amazon EC2) Linux instance to get the SSM parameter, your EC2 Linux instance profile must have the ssm:GetParameters permission.

1.    Use the Systems Manager console to create the SSM parameter. Or, run the put-parameter AWS CLI command:

aws ssm put-parameter --name PRODURL_SSM --value http://myproddomain.com --type String

2.    Use the following Dockerfile to deploy your application. The Dockerfile gets the SSM parameter value that's inside the temporary or build container, and then exports the variable during the build.

# Build environment
FROM node:13.12.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm install react-scripts@3.4.1
COPY . ./
## Install the required packages for awscli, curl, and jq. ##
RUN apk -v --no-cache add \
        py-pip \
        curl \
        jq \
        && \
        pip install awscli --upgrade --user
## Export the region dynamically retrieving it from the instance metadata, and then retrieve the SSM parameter value using awscli. Then, place the parameter in a text file, and export the variable using the value from the text file. Finally, run the build. ##
RUN TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && export REGION=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region)&& /root/.local/bin/aws ssm get-parameters --names PRODURL_SSM --region $REGION | grep Value | cut -d '"' -f4 >> /tmp/SSMParameter.txt && export DYNAMIC_SSM_VAR=$(cat /tmp/SSMParameter.txt) && npm run build
# Production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
## Copy the text file that has the SSM parameter value from the build container to the production container to confirm the variable was retrieved successfully. ##COPY --from=build /tmp/SSMParameter.txt /tmp
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

3.    To confirm that the deployment is successful, check that the file you copied includes the value of the SSM parameter variable.

Example:

# docker exec -it <Container-Id> sh# cat /tmp/SSMParameter.txt 
http://myproddomain.com

Use an Elastic Beanstalk variable

Note: To allow the instance profile into the environment, your instance profile must have the elasticbeanstalk:DescribeConfigurationSettings AWS Identity and Access Management (IAM) permission.

1.    Copy the config.yml file that the Elastic Beanstalk Command Line Interface (EB CLI) uses to the project root directory.

Example:

cp .elasticbeanstalk/config.yml .

2.    To set the Elastic Beanstalk variable with the EB CLI, run the following command to update or deploy to an existing environment:

eb setenv PRODURL_EB=http://myproddomain.com

3.    To create a new Elastic Beanstalk environment, add the new environment name in the config.yml file in the project root directory. Then, run the following command:

eb create --envvars PRODURL_EB=http://myproddomain.com

4.    Use the following Dockerfile to deploy your application. The Dockerfile gets the value of the Elastic Beanstalk variable that's inside the build container, and then exports the variable during the build.

# Build environmentFROM node:13.12.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm install react-scripts@3.4.1
COPY . ./
## Create an .elasticbeanstalk directory to place the config.yml file in, so that the eb cli can interact with the Elastic Beanstalk environment. ##
RUN mkdir .elasticbeanstalk
## Copy config.yml to /app/.elasticbeanstalk inside the build container as it will be used by eb cli ##
COPY config.yml /app/.elasticbeanstalk
## Install required packages for awsebcli ##
RUN apk -v --no-cache add \
        gcc \
        musl-dev \
        openssl \
        openssl-dev \
        make \
        py-pip \
        libffi-dev \
        python \
        python-dev \
        && \
        pip install awsebcli --upgrade --user 
## Retrieve the Elastic Beanstalk variable using awsebcli and place it in a text file. Then, export the desired variable using the value from the text file, then run the build. ##
RUN /root/.local/bin/eb printenv | grep PRODURL_EB | awk '{print $3}' >> /tmp/EBVar.txt && export DYNAMIC_EB_VAR=$(cat /tmp/EBVar.txt) && npm run build
# Production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
## Copy the text file that has the Elastic Beanstalk variable value from the build container to the production container to confirm the variable was retrieved successfully ##
COPY --from=build /tmp/EBVar.txt /tmp
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

5.    To confirm that the deployment worked, check that the file you copied includes the value of the Elastic Beanstalk variable.

# docker exec -it <Container-Id> sh# cat /tmp/EBVar.txt 
http://myproddomain.com

Related information

Instance identity documents

get-parameters

AWS OFICIAL
AWS OFICIALAtualizada há 5 meses