Brad Urani
Brad Urani

Reputation: 1479

Installing private ssh deploy keys on Heroku

I'm creating a node.js app that serves as a web hook for Github that will automatically deploy a certain private repo when changes are pushed. To make the webhook app as efficient as possible, I want to clone and pull the private repo into a temporary directory in my webhook's Heroku instance when it's deployed, so that when the webhook fires I only need to 'git pull' to get the latest updates and deploy them. It's easy enough to run a shell script when the webhook app is deployed (using package.json or the Procfile), but before I run git commands I have to install the private deploy key. Currently the private and public key are in my webhook repo (I know, I know, once I get it working I'll do better) so I tried installing it by adding this to my shell script (which was suggested here)

mkdir /app/.ssh
cp config/ssh/* /app/.ssh/
mkdir /tmp/repos
git clone --bare ssh://github.com/<username>/<repo>.git /tmp/repos/<repo>

but I'm getting:

Initialized empty Git repository in /tmp/repos/assets/ Host key verification failed. fatal: The remote end hung up unexpectedly

The public key has been added as a deploy key in the repo I'm pulling, so my questions are:

Thanks!

Upvotes: 6

Views: 3569

Answers (2)

alanjds
alanjds

Reputation: 4130

Is possible to use a "pre-compile hook" to put your deployment key on $HOME/.ssh/id_rsa and Heroku's buildpack will happily use it to download your private stuff during their compile phase.

You will need to commit the deployment key and ssh configfile on the app to be pushed, and code the hook to copy it to the right place. One needed caveat is to enable unchecked connections. Example .ssh/config for your app:

StrictHostKeyChecking no

Some buildpacks have an special "pre-compile hook", that runs before the compilation/download of the external packages. Is not documented on Heroku anymore, but is kinda standard to exist. Here are some "alternative" docs: https://deis.com/docs/workflow/applications/using-buildpacks/#compile-hooks. At least Python and NodeJS buildpacks support it in one way or another.

Example of code on bin/pre_compile, commited from the rootdir of an app:

#!/usr/bin/env bash
set -eo pipefail

# The pre_compile hook is run by heroku-buildpack-python
echo "-----> I'm pre-compile hook"

# Work around Heroku bug whereby pylibmc isn't availbale during
# compile phase. See: https://github.com/heroku/heroku-buildpack-python/issues/57
export MEMCACHE_SERVERS='' MEMCACHIER_SERVERS=''

if [ -f bin/set_ssh_key ]; then
    echo "-----> Running set_ssh_key"
    chmod +x bin/set_ssh_key
    bin/set_ssh_key
fi

echo "-----> Pre-compile done"

And for a bin/set_ssh_key:

#!/usr/bin/env bash
set -eo pipefail

if [ -d "$BUILD_DIR/.ssh" ]; then
    echo "-----> Copying $BUILD_DIR/.ssh over $HOME/.ssh..."

    if [ ! -d "$HOME/.ssh" ]; then
        mkdir $HOME/.ssh
    fi

    cp -rv $BUILD_DIR/.ssh/* $HOME/.ssh/
    echo "       done."
fi

Upvotes: 0

Aidan
Aidan

Reputation: 4250

If you want to access private repositories during build time then this buildpack is the best option:

https://github.com/timshadel/heroku-buildpack-github-netrc

This allows you to set an environment variable with a Github Access Token. During the build process, a .netrc file is created with the access token which will give you access to any repositories for that user.

If however you want to access private repositories during build time, e.g. if your web dyno is doing git operations, then you can specify the repository URI in a way that includes your access token:

https://your_user:[email protected]/ABASystems/abas-engineering.git

Both of these methods allow you to access private git repositories without exposing your password.

Upvotes: 4

Related Questions