よかろうもん!

アプリからインフラまで幅広くこなすいまどきのクラウドエンジニアが記す技術ブログ

OpsWorksで機能追加された環境変数を試してみて気づいた注意すべきこと

2014年8月のアップデートでOpsWorksのApps層の設定項目に環境変数が追加されました。

ということで、新しい環境を整備する際にこの機能を試してみたところ、想定と異なる動きをしていたので、その挙動についてかんたんに解説しようと思います。

HerokuなどのPaaSでは環境変数をセットすると、cron実行時などでも環境変数を参照できます。しかし、OpsWorksのApplication Layerの環境変数機能では、2014年10月時点ではそれができません。
というのも、WebServerに環境変数がセットされ、それがアプリケーションに伝わる仕組みだからです。

WebサーバとしてApache+Passengerを利用している場合は、Apacheの設定ファイルにSetEnvが追記されそちらがアプリケーションに伝わります。
Nginx+Unicornの場合も同じで、下記のようにUnicornの設定ファイルに追記され、そちらRailsアプリケーションに渡されます。
https://github.com/aws/opsworks-cookbooks/blob/release-chef-11.10/unicorn/recipes/rails.rb#L49

この仕組みでもアプリケーションが稼働し始めた際には問題なく動きますが、Deploy Hookなどで環境変数を参照したいときやCron実行時に環境変数を参照したいときなどに参照できないという不都合が生じます。
Herokuに慣れていると、セットした環境変数rails consoleやrake実行時にもセットされるためそれが当たり前だ思ってしまいますが、OpsWorksの現仕様ではそうなっていないので注意が必要です。
OpsWorksのインスタンスにログインしてdeployユーザに昇格してみてexportコマンドを実行するとわかりますが、OpsWorks側でセットした環境変数を参照することはできません。
※Herokuの場合はheroku run bashで接続してexportを実行するとユーザ環境変数にセットさていることがわかります。

よくよくリリースノート(AWS OpsWorks Supports Application Environment Variables)を読み返してみると、確かにApplication Environment Variablesをサポートしたと書いてあるので、Application層=Webサーバの環境変数を利用した仕組み、と読み取れはしますね・・・。
ただ、Apps層でdeployイベント発動時にセットされるRAILS_ENVについては、deploy hook実行時にも参照できるようになっていたので、その点が誤解を招いた結果になってしまったんですね。。。

今回、私が本機能を利用しようとした本当の目的としては、githubなどのソースコード管理システムに渡したくない情報、すなわちIAMのクレデンシャルの情報(AWS Access KeyやAWS Secret Key)をOpsWorksの世界に閉じ込めたいというところでしたので、いまいち利用シーンがフィットしないということになってしまいました。
AWSのセキュアな情報を同じServicerの機能(OpsWorks)に閉じ込めることは、セキュリティ的に見ても価値があると思いますので、ぜひこの点は改善してもらえたらと思います。

もっというと、Configureイベント発動時にdeplyユーザの環境変数にまでセットしてもらえると大変助かります。cron実行時にも参照できますし。ただ、セキュリティとの兼ね合いも検討しないといけないというのはわかりますが。。

ということで、みなさんもOpsWorksの新機能である環境変数を試される場合は、この点を考慮しておくとスムーズに検証できるかと思います。
そして、これからのOpsWorksの発展にも期待していますので、AWSのエンジニアの方々、よろしくお願いします。