Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding secrets to a vault container at startup

I am trying to find some guidance on what's the best method to add secrets to a vault container (running in dev mode) at startup. I came up with one way of doing it, albeit not very clean. So, I'm looking for some suggestions on better ways to implement this.

I took the Vault parent image, and created a shell script to call the parent image's entrypoint first, then add a loop to wait for vault to come up, initialize it, add secrets to it. If I leave the script at this point, the container simply stops and exits, so I also added a loop to keep a timer going as long as vault is up and running.

FROM vault

# Install Curl
RUN apk add --no-cache curl

# Instal jq
ADD https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 /usr/bin/jq
RUN chmod 755 /usr/bin/jq

ENV MYSQL_URL default
ENV MYSQL_USERNAME default
ENV MYSQL_PASSWORD default
ENV VAULT_DEV_ROOT_TOKEN_ID 0000

EXPOSE 8200
ADD vault-init.sh /

RUN chmod 755 vault-init.sh

ENTRYPOINT exec "./vault-init.sh"

Here's the vault-init.sh referenced above.

echo "Staring Vault..."
docker-entrypoint.sh server -dev &
echo "Sleeping 10..."
sleep 10
echo "Vault Started."

echo "Exporting address"
export VAULT_ADDR="http://localhost:8200"

echo "Authenticate into Vault"
# Authenticate to Vault
vault login $VAULT_DEV_ROOT_TOKEN_ID

echo "Adding secrets to Vault..."
vault kv put secret/fruit-basket mysql.username=$MYSQL_USERNAME mysql.password=$MYSQL_PASSWORD mysql.url=$MYSQL_URL

while [ "$(curl -XGET --insecure --silent -H "X-Vault-Token: $VAULT_DEV_ROOT_TOKEN_ID" http://localhost:8200/v1/sys/health | jq '.initialized')" == "true" ] 
do
    sleep 2
done
like image 248
Niranjan Sathindran Avatar asked Oct 20 '25 05:10

Niranjan Sathindran


1 Answers

Thanks @David for your input. What I ended up doing was a little different. I think this was a much more elegant solution. I created two different vault container images, one that is the actual vault image running to do its job as vault, and the second that loads the secret (called vault-secret). In the vault-secret image, I rewrote the above unix script to wait for vault to come up, and then load the secrets in. Since I overrided the parent image's (vault in this case) ENTRYPOINT in my script, vault only comes up on the image thats called vault and the vault-secret container stops and exits since it has no process running after loading the secrets (much like a Kubernetes Job). Here's my new Dockerfile and the unix script.

FROM vault

# Install Curl
RUN apk add --no-cache curl

# Instal jq
ADD https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 /usr/bin/jq
RUN chmod 755 /usr/bin/jq

ENV MYSQL_URL default
ENV MYSQL_USERNAME default
ENV MYSQL_PASSWORD default
ENV VAULT_DEV_ROOT_TOKEN_ID 0000

EXPOSE 8200
ADD vault-init.sh /

RUN chmod 755 vault-init.sh

ENTRYPOINT exec "./vault-init.sh"

vault-init.sh from above

echo "Waiting for Vault..."
while [ "$(curl -XGET --insecure --silent -H "X-Vault-Token: $VAULT_TOKEN" $VAULT_ADDR/v1/sys/health | jq '.initialized')" != "true" ] 
do
    echo 'Vault is Initializing...'
    sleep 2
done

echo "Vault Started."

echo "Authenticate into Vault"
# Authenticate to Vault
vault login $VAULT_TOKEN

echo "Adding secrets to Vault..."
vault kv put secret/fruit-basket mysql.username=$MYSQL_USERNAME mysql.password=$MYSQL_PASSWORD mysql.url=$MYSQL_URL

In the above solution I use the vault base image to run the "load secrets" job. Thats just so I can use the vault command line tool to load the secrets. If you were to replace that with curl, you could move to using alpine or even busybox reducing the container footprint.

Thanks for reading!

like image 110
Niranjan Sathindran Avatar answered Oct 21 '25 20:10

Niranjan Sathindran



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!