We write Dockerfile for packaging our application into Docker images. Dockerfile is a set of plaintext instructions with predeclared environment variables. These environment variable contains sensitive information such as username, password, remote database URL, bastion host IP etc. When secret variables will be visible in source code repository then code repository members can see them easily. Obviosuly, we need to tackle this situation! In this post, I will discuss on keeping these values secret in AWS, fetching and using them in docker runtime.
There is a way of protecting environment variable which is creating separate file with environment variable and pointing the path in Dockerfile. But still it reamins the same. However, you can also use HaschiCorp’s Vault to mange Docker secrets which is also very popular. But you need to manage that on your own. Now, lets focus on AWS Parameter Store service and see its advantages:
AWS Parameter Store service can be found under System Management Tools in EC2 dashboard. In this example, I am not going to write an entire Dockerfile instead I will use a portion in my example.
1
2
3
4
5
6
7
8
9
10
FROM phusion/baseimage:master
MAINTAINER Shudarshon Chaki <sdrsn.chaki@gmail.com>
ENV SONAR_VERSION=7.1 \
SONARQUBE_HOME=/opt/sonarqube \
SONARQUBE_JDBC_USERNAME=sonaruser \
SONARQUBE_JDBC_PASSWORD=sonarpassword \
SONARQUBE_JDBC_URL=jdbc:postgresql://db.endpoint.com/sonar \
JAVA_HOME=/usr/lib/jvm/java-8-oracle \
PATH=$JAVA_HOME/bin:$PATH
First we will create an IAM role with AmazonEC2RoleforSSM
policy attached. We will bind this role with EC2 instance where Docker will be running.
Next, create an EC2 instance with above IAM role and install awscli
. Next, use aws configure
command and configure only the region where we are going to save secrets in Parameter Store. In this example, EC2 and Parameter store services are of same region.
Next, put secrets in Parameter store in following way,
1
2
3
$ aws ssm put-parameter --name "SONARQUBE_JDBC_USERNAME" --type "String" --value "actualusername"
$ aws ssm put-parameter --name "SONARQUBE_JDBC_PASSWORD" --type "String" --value "actualpassword"
$ aws ssm put-parameter --name "SONARQUBE_JDBC_URL" --type "String" --value "jdbc:postgresql://original.db.endpoint.com/sonar"
Now, these parameters are safe. We will use it in the build server which can be ephemeral like a Docker container or any Jenkins slave.
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
$(aws ssm get-parameters --names "SONARQUBE_JDBC_USERNAME" | jq -r '.Parameters| .[] | "export " + .Name + "=" + .Value + ""')
$(aws ssm get-parameters --names "SONARQUBE_JDBC_PASSWORD" | jq -r '.Parameters| .[] | "export " + .Name + "=" + .Value + ""')
$(aws ssm get-parameters --names "SONARQUBE_JDBC_URL" | jq -r '.Parameters| .[] | "export " + .Name + "=" + .Value + ""')
sed -i "s#SONARQUBE_JDBC_USERNAME=[^ ]*#SONARQUBE_JDBC_USERNAME=${SONARQUBE_JDBC_USERNAME}#" Dockerfile
sed -i "s#SONARQUBE_JDBC_PASSWORD=[^ ]*#SONARQUBE_JDBC_PASSWORD=${SONARQUBE_JDBC_PASSWORD}#" Dockerfile
sed -i "s#SONARQUBE_JDBC_URL=[^ ]*#SONARQUBE_JDBC_URL=${SONARQUBE_JDBC_URL}#" Dockerfile
docker build -t app .
docker run -d --name sonarqube -p 9000:9000 -p 9092:9092 --restart unless-stopped app
If you find any issue or want more feature/new tutorials then mail me at sdrsn.chaki@gmail.com
Comments