Cloud Foundry の User-Provided Service (UPS) を cf コマンドで操作する

## User-Provided Service (UPS) とは

環境変数にセットするようなクレデンシャル情報を設定することができる仕組み。

1つの User-Provided Service インスタンスを複数のアプリに関連付けることによって、同じクレデンシャル情報を複数のアプリから使用することができる。

アプリ側は VCAP_SERVICES という環境変数から情報を取得する。

[User\-Provided Service Instances \| Cloud Foundry Docs](https://docs.cloudfoundry.org/devguide/services/user-provided.html)

> User-provided service instances enable developers to configure their apps with these using the familiar App Binding operation and the same app runtime environment variable used by Cloud Foundry to automatically deliver credentials for marketplace services (VCAP_SERVICES).

## User-Provided Service を操作するコマンド

### User-Provided Service インスタンスの作成・更新・削除

[create\-user\-provided\-service \- Cloud Foundry CLI Reference Guide](http://cli.cloudfoundry.org/ja-JP/cf/create-user-provided-service.html)

> 名前
> create-user-provided-service - ユーザー提供のサービス・インスタンスを CF アプリが使用できるようにします

> 使用法
> cf create-user-provided-service SERVICE_INSTANCE [-p CREDENTIALS] [-l SYSLOG_DRAIN_URL] [-r ROUTE_SERVICE_URL] [-t TAGS]

> 別名
> cups

[update\-user\-provided\-service \- Cloud Foundry CLI Reference Guide](http://cli.cloudfoundry.org/ja-JP/cf/update-user-provided-service.html)

> 名前
> update-user-provided-service - ユーザー提供サービス・インスタンスを更新します

> 使用法
> cf update-user-provided-service SERVICE_INSTANCE [-p CREDENTIALS] [-l SYSLOG_DRAIN_URL] [-r ROUTE_SERVICE_URL] [-t TAGS]

> 別名
> uups

[delete\-service \- Cloud Foundry CLI Reference Guide](http://cli.cloudfoundry.org/ja-JP/cf/delete-service.html)

> 名前
> delete-service - サービス・インスタンスを削除します

> 使用法
> cf delete-service SERVICE_INSTANCE [-f]

> 別名
> ds

### アプリと User-Provided Service インスタンスの関連付け

[bind\-service \- Cloud Foundry CLI Reference Guide](http://cli.cloudfoundry.org/ja-JP/cf/bind-service.html)

> 名前
> bind-service - サービス・インスタンスをアプリにバインドします

> 使用法
> cf bind-service APP_NAME SERVICE_INSTANCE [-c PARAMETERS_AS_JSON] [--binding-name BINDING_NAME]

> 別名
> bs

[unbind\-service \- Cloud Foundry CLI Reference Guide](http://cli.cloudfoundry.org/ja-JP/cf/unbind-service.html)

> 名前
> unbind-service - アプリからサービス・インスタンスをアンバインドします

> 使用法
> cf unbind-service APP_NAME SERVICE_INSTANCE

> 別名
> us

## User-Provided Service の操作例

User-Provided Service インスタンスの作成・更新・削除や、アプリとのバインドなどの操作を一通り実施する。
設定する情報は JSON フォーマットを使用する。

### 今回の環境

```
$ cf --version
cf バージョン 6.47.2+d526c2cb3.2019-11-05
```

### User-Provided Service インスタンスを作成する

```
$ cf create-user-provided-service my-ups -p '{"key1":"value1","key2":"value2"}'
my-account@example.com としてユーザー提供サービス my-ups を組織 my-org / スペース development 内に作成しています...
OK
```

### アプリに User-Provided Service インスタンスを関連付ける

```
$ cf bind-service my-app my-ups
my-account@example.com としてサービス my-ups を組織 my-org / スペース development 内のアプリ my-app にバインドしています...
OK

ヒント: 確実に環境変数の変更が有効になるようにするには、'cf restage my-app' を使用します
```

### アプリに User-Provided Service インスタンスがバインドされているか確認する

```
$ cf services
my-account@example.com として組織 my-org / スペース development 内のサービスを取得しています...

名前     サービス        プラン   バインド済みアプリ   最後の操作   ブローカー   upgrade available
my-ups   user-provided            my-app    
```

### アプリの環境変数を確認する

バインドすることによって User-Provided Service インスタンスの情報をアプリの環境変数として取得できるようになる。

```
$ cf env my-app
my-account@example.com として組織 my-org / スペース development 内のアプリ my-app の環境変数を取得しています...
OK

システム提供:
{
 "VCAP_SERVICES": {
  "user-provided": [
   {
    "binding_name": null,
    "credentials": {
     "key1": "value1",
     "key2": "value2"
    },
    "instance_name": "my-ups",
    "label": "user-provided",
    "name": "my-ups",
    "syslog_drain_url": "",
    "tags": [],
    "volume_mounts": []
   }
  ]
 }
}
(以下略)
```

### アプリに User-Provided Service インスタンスの情報を反映させる

```
$ cf restage my-app
このアクションを実行すると、アプリのダウン時間が発生します。

my-account@example.com として組織 my-org / スペース development 内のアプリ my-app を再ステージングしています...
```

### Node.js による VCAP_SERVICES 取得

以下のコードをデプロイすることによって、

```javascript
const http = require('http')
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'})
  res.end(process.env.VCAP_SERVICES)
}).listen(8080)
```

以下のような JSON 文字列を出力することができる。

```json
{"user-provided":[{
  "label": "user-provided",
  "name": "my-ups",
  "tags": [

  ],
  "instance_name": "my-ups",
  "binding_name": null,
  "credentials": {
    "key1": "value1",
    "key2": "value2"
  },
  "syslog_drain_url": "",
  "volume_mounts": [

  ]
}]}
```

### User-Provided Service インスタンスを更新する

```
$ cf update-user-provided-service my-ups -p '{"key3":"value3","key4":"value4"}'
Updating user provided service my-ups in org my-org / space development as my-account@example.com...
OK

TIP: Use 'cf restage' for any bound apps to ensure your env variable changes take effect
```

バインド済みのアプリの環境変数を確認すると、先に設定した値が消えて、新しい値に更新されている。

```
$ cf env my-app
my-account@example.com として組織 my-org / スペース development 内のアプリ my-app の環境変数を取得しています...
OK

システム提供:
{
 "VCAP_SERVICES": {
  "user-provided": [
   {
    "binding_name": null,
    "credentials": {
     "key3": "value3",
     "key4": "value4"
    },
(以下略)
```

### アプリと User-Provided Service インスタンスの関連付けを解除する

```
$ cf unbind-service my-app my-ups
my-account@example.com として組織 my-org / スペース development 内のサービス my-ups からアプリ my-app をアンバインドしています...
OK
```

### User-Provided Service インスタンスを削除する

```
$ cf delete-service my-ups

サービス my-ups を削除しますか?> y
my-account@example.com として組織 my-org / スペース development 内のサービス my-ups を削除しています...
OK
```

## 参考資料
- [User\-Provided Service Instances \| Cloud Foundry Docs](https://docs.cloudfoundry.org/devguide/services/user-provided.html)
- [Cloud Foundry CLI Reference Guide](http://cli.cloudfoundry.org/ja-JP/cf/)
- [CFAR Environment Variables \| Cloud Foundry Docs](https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html)
- [Tips for Node\.js Applications \| Cloud Foundry Docs](https://docs.cloudfoundry.org/buildpacks/node/node-tips.html#start)