Edited at
HerokuDay 24

Herokuの環境変数をアプリから変更する

More than 3 years have passed since last update.

この記事は Heroku Advent Calendar 2015 の 24 日目の記事です。


事の始まり

少し前に、こんな疑問をTwitterで見つけまして。

(動いているアプリのスクリプトコードから変更出来るか、という意味も含めて解釈させていただきます)

ちょっと調べてみると、HerokuのAPI叩くと解決しそうでした。

https://devcenter.heroku.com/articles/platform-api-reference#config-vars

手元でcurlで叩いてみると環境編集の取得と作成(patchコマンドでも出来た)、編集が出来ました。

(削除に関しては不明)


Faradayを使う

Faraday使うと普通にアプリ上から変更できるんじゃないかと思ったので、ちょっと検証してみました。

rails new etmnk-config-test -d postgresql

で作って、適当に bundle exec rails g controller configvars で環境変数をなんやかんやするためのコントローラ作ります。

(中身は後で追加)

#表示用

def index
end

# 変更用
def put
end

こんな感じでとりあえず作っといて、config/route.rbには

  root to: 'configvars#index'

get '/configvars', to: 'configvars#index'
patch '/configvars/:key/:value', to: 'configvars#put'

を追加しときます。

'/'もしくは'/configvars'で環境変数の一覧を表示し'/configvars/:key/:value'をpatchで指定することで、環境変数:keyに:valueの値を設定して追加します。

Gemfileはこんな感じに追記します。

gem 'faraday'

group :production do
gem 'pg', '~> 0.15' # postgresは今回は別に使いません
gem 'rails_12factor'
end

処理的にはこんな感じにしときます。説明のためいろいろ雑になってますが。

app/controllers/configvars_controller.rb

class ConfigvarsController < ApplicationController

# 一覧表示用
def index
client = Faraday.new(:url => "https://api.heroku.com")
res = client.get do |req|
req.url '/apps/your-app/config-vars'
req.headers['Content-Type'] = 'application/json'
req.headers['Accept'] = "application/vnd.heroku+json; version=3"
# 認証が必要なのでherokuアカウント情報をここで設定
req.headers['Authorization'] = Base64.encode64('your-email' + ':' + 'your-pass')
end
@body = JSON.parse(res.body)
end

# 環境変数更新用(追加でも使う)
def put
# URLから設定情報を取る
# /configvars/:key/:value
# からkeyとvalueを取る
key = params[:key]
value = params[:value]
confvalue = {}
confvalue[key] = value
client = Faraday.new(:url => "https://api.heroku.com")
res = client.patch do |req|
req.url '/apps/your-app/config-vars'
req.headers['Content-Type'] = 'application/json'
req.headers['Accept'] = "application/vnd.heroku+json; version=3"
req.headers['Authorization'] = Base64.encode64('your-email' + ':' + 'your-pass')
req.body = confvalue.to_json
end

redirect_to configvars_path
end
end

画面側はこんな感じに。

app/views/configvars/index.html.erb

<% p @body%>

<%= link_to 'conf', 'configvars/hoge/huga', :method => :patch %>

注: 環境変数全部表示してしまうので、取り扱いには注意してください

今回いろいろ手抜きでURLに直接パラメータ突っ込んでます。リンクを叩くと環境変数hogeにhugaの値が設定されて追加されると思います。

明日は最終日です。 @ayuminさんお願いします。