IBM BluemixはCloudFoundryをベースとしたPaaSです。
CloudFoundryでのアプリケーション開発は、ruby、javascript (node.js)、javaなどの言語を使って、APIを通じてPaaSが提供してくれる個々のサービスを利用します。このようなAPIを利用する際に資格情報(接続先URL、ポート、ユーザID、パスワードなど)が必要となりますが、これらの情報はすべてプラットフォームからアプリケーションにVCAP_SERVICES
という環境変数で与えられます。(参考: CloudFoundry Documentation: Binding Credentials.)
#VCAP_SERVICESとは
Bluemixの場合にも、サービスを利用する場合にはこのVCAP_SERVICESを使った資格情報を使う必要があります。
たとえば、Bluemix上でredisを使う場合を考えましょう。
Bluemixでredisサービスを作成すると、ダッシュボードにアイコンが現れます。
このアイコンの左下にある「資格情報の表示」をクリックすると、VCAP_SERVICESに埋め込まれる資格情報(json形式)が表示されます。
{
"redis-2.6": [
{
"name": "my-redis",
"label": "redis-2.6",
"plan": "100",
"credentials": {
"hostname": "xx.xx.xx.xx",
"host": "xx.xx.xx.xx",
"port": xxxx,
"password": "xxxx-xxxx-xxxx-xxxx-xxxx",
"name": "xxxx-xxxx-xxxx-xxxx-xxxx"
}
}
]
}
この情報を使用して、たとえばredisにデータを格納する場合は、以下のようなコードを書くことになります。なお、ここでは、VCAP_SERVICESがないということはローカルでのデバッグ実行を意味しており、その場合はローカルに立てたredisを使うようにしています。
require 'redis'
redis_service_label = 'redis-2.6'
if process.env.VCAP_SERVICES?
services = JSON.parse process.env.VCAP_SERVICES
redis_creds = services?[redis_service_label]?[0]?.credentials
redis_host = redis_creds?.host ? 'localhost'
redis_port = redis_creds?.port ? '6379'
redis_pass = redis_creds?.password ? null
client = redis.createClient redis_port, redis_host
if redis_pass?
client.auth redis_pass
client.set key, val
'redis-2.6'はBluemix上で選択したサービスの種類ですので、同じサービスを複数使用した場合などは、配列の中から適当なものを見つけなければならないなど、jsonの構造を理解したうえで記述する必要があり、結構面倒です。
#cfenvの導入
もう少し手軽にVCAP_SERVICESを使えるようにしたnpmモジュールがcfenvです。
Bluemixでcfenvを利用するには、package.jsonのdependenciesにモジュール名"cfenv"
を追加します。
{
...
"dependencies": {
"cfenv": "*",
...
}
...
}
#cfenvの使い方
それでは、上記の例をcfenvで書き換えてみます。
require 'redis'
require 'cfenv'
redis_creds = cfenv.getAppEnv().getServiceCreds 'my-redis'
redis_host = redis_creds?.host ? 'localhost'
redis_port = redis_creds?.port ? '6379'
redis_pass = redis_creds?.password ? null
# 以下は同じ
client = redis.createClient redis_port, redis_host
if redis_pass?
client.auth redis_pass
client.set key, val
getServiceCreds
では、サービス名を使えます。サービスの種類は全般的に長く、また命名方法に一貫性が無いため、サービス名を使うことができると見通しが良くなります。同じ種類のサービスを複数利用するときなど、jsonの構造にそって要素を列挙する必要がなくサービス名で簡単にアクセスできることは非常に重要です。また、全般的にjsonの構造を比較的意識する必要がありません。
#まとめ
- BluemixはCloudFoundryですので、サービスの資格情報は
VCAP_SERVICES
環境変数に格納されています。 - 資格情報はjsonですので自力で解析することもできますが、cfenvモジュールを使えば、構造を意識する必要がなく、コードがシンプルになります。