CredHub Service BrokerでCloud Foundry上のアプリケーションへセキュアに環境変数を設定
PCF 2.2でGAになったCredHub Service Brokerについて。(関連記事)
User Provided Serviceの場合
CredHub Service Brokerは一言で言うとセキュアなUser Provided Serviceです。
違いを説明するためにまずはUser Provided Serviceを使ってみます。
fooディレクトリを作成して、
mdkir foo
cd foo
phpinfo()を表示するだけのPHPアプリケーションを作成します。
cat <<EOF > index.php
<?php
phpinfo();
EOF
cf pushでデプロイします。
cf push hello-php -b php_buildpack -m 32m
このアプリケーションに何らかのAPIキーを渡すために、User Provided Serviceを使ってみます。
cf create-user-provided-service (またはcf cups)で次のようにサービスインスタンスを作成します。
cf create-user-provided-service demo-ups -p '{"api-key":"THIS_IS_A_SECRET_KEY"}'
これをcf bind-serviceでアプリケーションにバインドして、リスタートすると、
cf bind-service hello-php demo-ups
cf restart hello-php
環境変数VCAP_SERVICESのJSON文字列の中に{"api-key":"THIS_IS_A_SECRET_KEY"}が含まれます。

例えばPHPでは次のようにAPIキーにアクセスできます。
$vcap_services = json_decode(getenv('VCAP_SERVICES'));
$credentials = $vcap_services->{'user-provided'}[0]->credentials;
$api_key = $credentials->{'api-key'};
Spring Bootの場合はapplication.propertiesに次のように設定すれば良いです。
api-key=${vcap.services.demo-ups.credentials.api-key}
アプリケーションに環境変数を設定する方法としてUser Provided Serviceは便利なのですが、一つ課題があり、
cf envで環境変数を確認する際に次のように設定内容がターミナル上で表示されてしまいます。
cf env hello-php

これを嫌がる方は多いです。cf set-envで環境変数を設定する場合も同じです。
CredHub Service Brokerの場合
CredHub Service Brokerは設定したCredentialsをCredHubに保存します。CredHubに保存されるデータは暗号化されますし、HSM(Hardware Security Module)と連携することもできます。
CredHub Service Brokerが有効になっていればcf marketplaceから確認できます。

まずは先ほど作成したdemo-upsサービスインスタンスをアンバインドして削除します。
cf unbind-service hello-php demo-ups
cf delete-service demo-ups
次のCredHub Service Brokerのサービスインスタンスを作成します。作成方法は次の通りで、User Provided Serviceと似ています。
cf create-service credhub default demo-credhub -c '{"api-key":"THIS_IS_A_SECRET_KEY"}'
これをcf bind-serviceでアプリケーションにバインドして、リスタートすると、
cf bind-service hello-php demo-credhub
cf restart hello-php
cf envで環境変数を確認する際はCredentialsが直接表示される代わりに、次のようにCredHubへの参照キーのみが表示されます。
cf env hello-php

ではアプリケーションからわざわざCredHubにアクセスしにいけないかというとそうではなく、アプリケーションからはUser Provided Serviceと同じようにVCAP_SERVICES内にCredentialsが見えます。

アプリケーションは環境変数を見れば良いだけです。 PHPの場合は次のようにアクセスできます。
cat <<'EOF' > apikey.php
<?php
$vcap_services = json_decode(getenv('VCAP_SERVICES'));
$credentials = $vcap_services->credhub[0]->credentials;
echo "API_KEY = " . $credentials->{'api-key'};
EOF

Spring Bootの場合はapplication.propertiesに次のように設定すれば良いです。
api-key=${vcap.services.demo-credhub.credentials.api-key}
環境変数VCAP_SERVICESからCredentialsにアクセスできる点はUser Provided Serviceと同じですが、
cf envでCredentialsが表示されない- Credentialsの保存場所がCredHub
という点でよりセキュアです。
内部の仕組みについてはこちらの記事を参照してください。