How can i pass secrets as build_args to plugins/docker [drone 0.8]?

Hi,

I need to pass ssh key to clone private Bitbucket repo as npm module.

I added a secret to drone.io using:

drone secret add --image=* --repository octocat --value SSH_KEY

Dockerfile looks like this:

FROM node:latest

ARG SSH_KEY

RUN mkdir /root/.ssh && \
    echo $SSH_KEY | cut -d "\"" -f 2 > /root/.ssh/id_rsa && \
    chmod 0600 /root/.ssh/id_rsa && \
    eval `ssh-agent -s` && \
    ssh-add /root/.ssh/id_rsa && \
    echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config

RUN mkdir /app
WORKDIR /app

COPY . /app

RUN npm install

EXPOSE 3001

CMD ["npm", "start"]

and drone.yml

pipeline:
  run-tests:
    image: node:6
    commands:
      - export PATH=$PATH:./node_modules/.bin
      - mkdir -p ~/.ssh
      - touch ~/.ssh/known_hosts
      - ssh-keyscan bitbucket.org >> ~/.ssh/known_hosts
      - eval $(ssh-agent)
      - echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config
      - echo $SSH_KEY | base64 -d > ~/.ssh/id_rsa
      - chmod 600 ~/.ssh/id_rsa
      - npm install
      - npm install --only=dev
      - npm test
    secrets: [ ssh_key ]

  publish:
    image: plugins/docker
    secrets: [ docker_username, docker_password, ssh_key ]
    repo: my-app
    build_args:
      - SSH_KEY=${SSH_KEY}

Secrets are injected into run-test step, but i have no idea how can I pass them to publish step.

Drone injects secrets as environment variables. There is a parameter you can use to source build arguments from environment variables. You can therefore do this:

pipeline:
  publish:
    image: plugins/docker
    secrets: [ ssh_key, docker_username, docker_password ]
    build_args_from_env: [ ssh_key ]

This does not work because secrets cannot be interpolated.

1 Like

Thanks for quick answer. Works like a charm.

However http://plugins.drone.io/drone-plugins/drone-docker/ doesn’t mention about build_args_from_env.
I know it’s a fresh addition.
I can update docs if you tell me where I can find them.

1 Like

This looks great and seems to be working. Couple questions though

  • If I try to execute my build locally with drone exec then I can’t use the ssh key, because only the part until the first space gets into the id_rsa file (-----BEGIN) - on our drone server though the whole key is in the file. Is this a know issue with the cli?
  • with the build running on the server the logs include the whole key as part of the docker build command’s --build-arg parameter value. I saw there is a conceal feature, but not sure how to make that work. Any thoughts on this?

Thank you!

The conceal feature does not work for multi-line secrets. I presume the key is to clone private dependencies? You could always clone your dependencies outside of your Dockerfile and include using the ADD directive.

Alternatively you can always fork the Docker plugin and customize it. Plugins are intentionally easy to fork, customize and then substitute in your yaml file.

pipeline:
  publish:
-   image: plugins/docker
+   image: peetasan/my-drone-docker-plugin
    repo: foo/bar

This is VERY helpful!

How come it’s not documented?

I’ve built a plugin dedicated to the injection of secrets as environment variables to services

In the newer syntax, I ended up doing something like this:

kind: pipeline
name: production
steps:
- name: docker  
  image: plugins/docker
  environment:
    SSH_KEY:
      from_secret: SSH_KEY
    PLUGIN_DOCKERFILE:
      Dockerfile.Build
    PLUGIN_REPO:
      vwxyzjn/portwarden-server-prod
    PLUGIN_TARGET:
      production
    PLUGIN_AUTO_TAG:
      true
    PLUGIN_USERNAME:
      from_secret: docker_username
    PLUGIN_PASSWORD:
      from_secret: docker_password
    PLUGIN_BUILD_ARGS:
      SSH_KEY=$SSH_KEY