2012年11月5日追記
現在、heroku gemのAPIを用いてのHerokuへのアクセスはdeprecatedになり、替わりに、heroku-apiを用いるようになっている(herokuコマンド自体は引き続き利用出来る)。
Herokuのconfig varをローカル環境下のスクリプト内で取得するには(heroku-api版)を参照されたし。
- HerokuとGitHubの両方にプッシュする時の秘密にしたい値の扱い - アインシュタインの電話番号?
- HerokuでWebアプリ開発を始めるなら知っておきたいこと (5)環境変数ENV - アインシュタインの電話番号?
HerokuとGitHubの両方にプッシュできるようになったのはいいけど、例えばTwitterのOAuth認証用のトークンとか、何かのAPIを利用するためのAPIキーとか、あるいはもっと大事な何かのパスワードなど、秘密にしておきたい情報は、GitHubにプッシュしてしまうと全世界に公開されるので非常にマズい。
かといって書いておかないと、Herokuにプッシュしたときに情報が足らなくてアプリが正常に動かない。
どうするん?毎回消したり書いたりするの?
config varというのは、上記のようにHerokuとGitHubの両方にプッシュする時の秘密にしたい値の扱い - アインシュタインの電話番号?に記されているような要求をこなす時に使うheroku config:add
で追加する値の事ね。
ENVでアクセス出来るし、正体はただの環境変数だと思うが、heroku help config
にはconfig vars
と表記されてるのでそっちの表記を採用。
さて、このconfig vars、ruedapさんも言及してるように、Herokuの環境下でしか利用出来ない値で、ローカル環境での開発時にはENVに無い。彼も言っているような、ローカル環境かどうか判定して、同一内容をENVに突っ込むスクリプトをrequire
、そのファイルは間違ってHeroku側のリポジトリにcommitしないように.gitignoreに書いておく……というのがサッと思いつく対処法か。だが、値の追加/編集時に、heroku config
とそのスクリプト、両方を同一内容になるように保持するというのは流石にめんどくさい。
そんな馬鹿な。
おかしい。
あり得ない。
ぜんっぜんprogrammableじゃない。
そもそも、heroku
コマンドはgem
で導入する物だし、もしかしてライブラリとして利用する方法があるんじゃないの?
という訳で、herokuコマンドのソースを斜め読んでみると、次のようにしてRubyのスクリプトから取得出来る事が分かった。
#!/usr/bin/ruby
require 'rubygems'
require 'heroku'
require 'pp'
EMAIL = '(Herokuに登録した時に使ったメールアドレス)'
PASSWORD = '(Herokuのパスワード)'
APPLICATION = '(アプリケーション名)'
KEY = '(値を取得したいconfig varのKEY)'
heroku = Heroku::Client.new(EMAIL, PASSWORD)
# APPLICATIONの全config varを取得
vars = heroku.config_vars(APPLICATION)
pp vars # heroku.config_varsの戻り値はただのHash
# 特定のconfig varを取得
var = vars[KEY]
p val
……コード中にメールアドレスだのパスワードだの埋め込むのは美しくない。何の為にconfig vars使おうとしてるのやら。
もうちょっとherokuのコードを読み進めてみると、既にheroku login
しているならば、Heroku::Client.new
の替わりにHeroku::Auth::client
でも良さそう。
という事は、実際に使う時は次のような感じだろうか。
# 既にheroku loginしている事前提
require 'rubygems'
# ...snip...
if !ENV.key?('VAR1') # config varのどれか一つでも存在しない場合
require 'heroku'
config_vars = Heroku::Auth.client.config_vars(APPLICATION)
# PATHやLANGといったheroku config:addで登録した物以外も出てくるので、愚直に代入処理をしている
ENV['VAR1'] = config_vars['VAR1']
ENV['VAR2'] = config_vars['VAR2']
# ...以下全てのconfig varについて同様に
end
#...snip...
うーん、ローカルかリモート(Heroku上)かの判定をENV.key?
で行うのは何か変だな……もっとスマートな方法が在りそうな気がするが……