How to store private key on Heroku?


Question

I have a flask app hosted on Heroku that needs to run commands on an AWS EC2 instance (Amazon Linux AMI) using boto.cmdshell. A couple of questions:

  1. Is using a key pair to access the EC2 instance the best practice? Or is using username/password better?
  2. If using a key pair is the preferred method, what's the best practice on managing/storing private keys on Heroku? Obviously putting the private key in git is not an option.

Thanks.

1
7
9/6/2013 3:00:56 PM

Accepted Answer

What I was looking for was guidance on how to deal with private keys. Both @DrewV and @yfeldblum pointed me to the right direction. I ended up turning my private key into a string and storing it in a Heroku config variables.

If anyone is looking to do something similar, here's a sample code snippit using paramiko:

import paramiko, base64
import StringIO
import os

key = paramiko.RSAKey.from_private_key(StringIO.StringIO(str(os.environ.get("AWS_PRIVATE_KEY"))))
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(str(os.environ.get("EC2_PUBLIC_DNS")), username='ec2-user', pkey=key)
stdin, stdout, stderr = ssh.exec_command('ps')

for line in stdout:
    print '... ' + line.strip('\n')
ssh.close()

Thanks to @DrewV and @yfeldblum for helping (upvote for both).

4
1/6/2013 4:37:19 AM

Heroku lets you take advantage of config variables to manage your application. Here is an exmaple of my config.py file that lives inside my flask application:

import os

# flask
PORT = int(os.getenv("PORT", 5000))
basedir = str(os.path.abspath(os.path.dirname(__file__)))
SECRET_KEY = str(os.getenv("APP_SECRET_KEY"))
DEBUG = str(os.getenv("DEBUG"))
ALLOWED_EXTENSIONS = str(os.getenv("ALLOWED_EXTENSIONS"))
TESTING = os.getenv("TESTING", False)

# s3
AWS_ACCESS_KEY_ID = str(os.getenv("AWS_ACCESS_KEY_ID"))
AWS_SECRET_ACCESS_KEY = str(os.getenv("AWS_SECRET_ACCESS_KEY"))
S3_BUCKET = str(os.getenv("S3_BUCKET"))
S3_UPLOAD_DIRECTORY = str(os.getenv("S3_UPLOAD_DIRECTORY"))

Now i can have two different sets of results. It pulls from my Environment variables. One when my application is on my local computer and from Heroku config variables when in production. For example.

 DEBUG = str(os.getenv("DEBUG")) 

is "TRUE" on my local computer. But False on Heroku. In order to check your Heroku config run.

Heroku config

Also keep in mind that if you ever want to keep some files part of your project locally but not in heroku or on github you can use git ignore. Of course those files won't exist on your production application then.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon