Deploying a production ready Prisma server on AWS Fargate / ECS, how to properly provide environment variables

Frank Sandqvist
Smidyo Codex
Published in
3 min readMar 8, 2019
FARGATE SG1

When we migrated from Azure to AWS, we had to also change a bit of our infrastructure. I researched quite a bit about what was the best way of deploying a Prisma server to a production-ready environment.

Prisma themselves has a tutorial on how to do it, but it’s through CloudFormation — which works fine!

The tutorial is fine — except for one part. Someone at Prisma decided (I’m sure they had their reasons…?) to have the PRISMA_CONFIG environment variable hold everything… in a YAML map! 😱 Try typing that into the single-line env-var input when creating a Task Definition.

It works the first time, since the CloudFormation template itself is YAML, but when you update the Task Definition, it breaks. (Can you even properly type single line YAML? Escaping doesn’t seem to work..)

So we need to use PRISMA_CONFIG_PATH instead. So I went ahead and created a custom Docker container to solve this problem.

Dockerfile first downloads the Prisma image (you’ll have to update this container to update Prisma). Then it sets the envvar PRISMA_CONFIG_PATH to prisma.yml…

FROM prismagraphql/prisma:1.27
ARG PRISMA_CONFIG_PATH
ENV PRISMA_CONFIG_PATH prisma.yml
COPY config.yml config.yml
COPY sub.sh sub.sh
ENTRYPOINT sh sub.sh && sh -c /app/start.sh
EXPOSE 4466

…then we copy the local config.yml file into the container…

port: PORT
managementApiSecret: SECRET
databases:
default:
migrations: true
connector: mysql
host: DATABASE_HOST
port: DATABASE_PORT
user: DATABASE_USER
password: DATABASE_PASSWORD

…which hold placeholders, which are in turn substituted by sub.sh which is also copied over…

[ -z "${PORT}" ] && echo "Not set: PORT";
[ -z "${SECRET}" ] && echo "Not set: SECRET";
[ -z "${DATABASE_HOST}" ] && echo "Not set: DATABASE_HOST";
[ -z "${DATABASE_PORT}" ] && echo "Not set: DATABASE_PORT";
[ -z "${DATABASE_USER}" ] && echo "Not set: DATABASE_USER";
[ -z "${DATABASE_PASSWORD}" ] && echo "Not set: DATABASE_PASSWORD";
cp config.yml prisma.yml
sed -ri 's/port: PORT/port: '$PORT'/g' prisma.yml
sed -ri 's/managementApiSecret: SECRET/managementApiSecret: '$SECRET'/g' prisma.yml
sed -ri 's/host: DATABASE_HOST/host: '$DATABASE_HOST'/g' prisma.yml
sed -ri 's/port: DATABASE_PORT/port: '$DATABASE_PORT'/g' prisma.yml
sed -ri 's/user: DATABASE_USER/user: '$DATABASE_USER'/g' prisma.yml
sed -ri 's/password: DATABASE_PASSWORD/password: '$DATABASE_PASSWORD'/g' prisma.yml

…which then checks that you’ve provided all the necessary env-vars, then makes a copy of the original config.yml named prisma.yml, in which all the placeholders are replaced.

Every time the container is spun up, this shell script is run, and Prisma gets its configuration from the file instead.

Now all you have to do is push your container to Dockerhub or ECR, and create your task definition.

Ah — the variables are all nice and separated. 😊

Pretty basic stuff — but maybe it helps someone!

--

--