Google Cloud Platform(GAE, GCE): Secret variables(環境変数)の設定方法


背景

主にGAE(Ruby, Flexible Environment)を用いてPaaSを構築していたところ、githubなどにコミットしたくないsecret variables(ここでは環境変数。データベースのパスワードやsecret tokenなど)の設定方法で小一時間ほどハマったのでメモ。

なぜハマったか

Herokuで同様にPaaSを構築した際には、環境変数はGUIもしくはコマンドラインツールから簡単に設定できていた。
Herokuの場合:

# 環境変数一覧
$ heroku config

# 環境変数名を指定して参照
$ heroku config:get ENV_VAR_NAME

# 追加 (一応addも使えます)
$ heroku config:set ENV_VAR_NAME="value"

# 削除 (一応removeも使えます)
$ heroku config:unset ENV_VAR_NAME

GAEも最近流行ってきているので、コマンドラインツールから設定できると勝手に思い込んでいたが、GAEにはHerokuのような環境変数に対するサポートがなかった(そりゃそうだ)。

GAEでの一般的な環境変数設定方法と問題点

公式ドキュメントによると、Rubyではプロジェクトのルートディレクトリにapp.yamlを置き、このyamlファイル内で定義する。

You can define environment variables in app.yaml to make them available to the app:

env_variables:
  MY_VAR: 'my value'

ただしapp.yamlは一般に、複数人開発を行い、かつ誰でもdeployをできる場合、.gitignoreに含むファイルでもない。
仮にリードエンジニアのみがローカルからdeployする場合でも、app.yamlファイルのバックアップ問題や、ローカルコンピュータに秘密値を持つことの危険性などが存在する

どのように解決するか

Project metadataを利用する

公式ドキュメントはこちら
GAE, GCEでは、メタデータをメタデータサーバーに格納している。このメタデータサーバーに対してクエリを投げ、インスタンスに関する情報(インスタンスのホスト名、インスタンス ID、起動スクリプトとシャットダウン スクリプト、カスタム メタデータ、サービス アカウントの情報など)を取得する。

一般には起動スクリプトやシャットダウンスクリプトと組み合わせて利用するが、メタデータはkey:valueで格納されるため、secret variablesもメタデータサーバに格納できる。

Googleによると、Compute Engine, Container Engine, Managed VMsにはmagic URLがあり 、http://metadata.google.internal/computeMetadata/v1にCURLするとメタデータにアクセスできる。ここでのManaged VMsとは現在のGAE Flexible Environmentであり、Rubyを使用する限りはFlexile Environmentを使用しているので、metadataへのアクセスは保証されている。

メタデータサーバーへのリクエストや、メタデータのレスポンスがインスタンスの外に出ることはなく、ホストに送信されるメタデータ情報は暗号化されるため、メタデータ情報のセキュリティが確保されている。

app.yamlをEncryptする

GPGを用いてapp.yamlを暗号化することで、安全にapp.yamlを管理する。
具体的には、たとえばRuby gemのdotgpgを利用する。
ただし、app.yamlファイルには環境変数以外の情報も含まれている。
また、Deploy時にdecryptする必要があるが、GAEへのdeploy時にそのようなことができるかは不明。

感じたこと

GAE/Goの事例は多くみるが、GAE/Ruby(Ruby on Rails)の本番環境での事例をあまり見かけないのは、このような面倒なトラップが隠れているからかな?と思った。
他にも方法があればコメントお願いします。