---
title: Cloud FoundryのSMB BrokerでAzure Filesを使う
tags: ["Cloud Foundry", "PAS", "Pivotal Cloud Foundry", "Azure", "Azure Files"]
categories: ["Dev", "PaaS", "CloudFoundry", "PCF"]
date: 2020-03-21T15:37:19Z
updated: 2020-03-22T12:59:51Z
---

Cloud Foundry / Pivotal Application Services(PAS)ではコンテナに永続ディスクをアタッチする用途でSMBとNFSのService Brokerが用意されています。

> Pivotal Application Servicesは最近リブランドされ、[VMware Tanzu Application Service (TAS)](https://tanzu.vmware.com/jp/application-service)にリネームされました。

ただし、SMBやNFSのprovisioningはサポートされておらず既存のサーバーをマウントするのみです。
別途、SMBサーバーを用意したくないので、AzureのManaged Serviceである[Azure Files](https://docs.microsoft.com/azure/storage/files/)を使って試してみます。
Azure FilesはSMB 3.0に対応しています。

SMB Brokerについては次のドキュメントを参照してください。
* https://docs.pivotal.io/platform/application-service/2-8/devguide/services/using-vol-services.html
* https://docs.google.com/presentation/d/1_5px0UB0k7USS71xVnn6XgU1eArZ__Ee_eYmxkj-XcE/edit#slide=id.g5ba1df2c92_0_10

また、PASでSMB Brokerを有効にする方法は[こちら](https://docs.pivotal.io/platform/application-service/2-8/operating/enable-vol-services.html#smb-enable)を参照してください。

<!-- toc -->

### Azure FilesのProvisioning

`az`コマンドでAzure Filesリソースを作成します。

```
export TENANT_ID=....
export CLIENT_ID=....
export CLIENT_SECRET=....
export LOCATION="Japan East"
export RESOURCE_GROUP=azure-files-demo
export STORAGE_ACCOUNT_NAME=makiazurefilesdemo
export SHARE_NAME=demoshare

az login --username ${CLIENT_ID} \
         --password ${CLIENT_SECRET} \
         --service-principal \
         --tenant ${TENANT_ID} 

az group create --name ${RESOURCE_GROUP} \
  --location "${LOCATION}"

az storage account create --name ${STORAGE_ACCOUNT_NAME} \
  --resource-group ${RESOURCE_GROUP} \
  --location "${LOCATION}" \
  --kind StorageV2 \
  --sku Standard_ZRS \
  --enable-large-file-share \
  --output none

# OR
# 
# az storage account create --name ${STORAGE_ACCOUNT_NAME} \
#   --resource-group ${RESOURCE_GROUP} \
#   --location "${LOCATION}" \
#   --kind FileStorage \
#   --sku Premium_LRS \
#   --output none

STORAGE_ACCOUNT_KEY=$(az storage account keys list \
    --resource-group ${RESOURCE_GROUP} \
    --account-name ${STORAGE_ACCOUNT_NAME} \
    --query "[0].value" | tr -d '"')

az storage share create \
    --account-name ${STORAGE_ACCOUNT_NAME} \
    --account-key ${STORAGE_ACCOUNT_KEY} \
    --name ${SHARE_NAME} \
    --quota 1024 \
    --output none
```

Azure PortalでStorage Account:`makiazurefilesdemo`の`demoshare`というFile Shareができていることを確認できます。

![image](https://user-images.githubusercontent.com/106908/77229792-2cac9200-6bd3-11ea-9602-02bc7553dcc2.png)



### Demoアプリのデプロイ

Demoアプリとして https://github.com/making/demo-uploader を使います。Spring Bootで実装されたシンプルなFile Uploaderです。

#### Marketplaceの確認

`cf marketplace`で`smb`サービスが利用できることを確認してください。

```
$ cf marketplace
Getting services from marketplace in org demo / space demo as makingx@gmail.com...
OK

service          plans      description                                                                    broker
app-autoscaler   standard   Scales bound applications in response to load                                  app-autoscaler
smb              Existing   Existing SMB shares (see: https://code.cloudfoundry.org/smb-volume-release/)   smbbroker

TIP: Use 'cf marketplace -s SERVICE' to view descriptions of individual plans of a given service.
```

#### アプリケーションのビルド

```
git clone https://github.com/making/demo-uploader
cd demo-uploader
./mvnw clean package -DskipTests=true
```

#### アプリケーションのデプロイ

```
cf push demo-uploader -p target/demo-uploader-0.0.1-SNAPSHOT.jar --no-start
cf create-service smb Existing demo-smb -c "{\"share\": \"//${STORAGE_ACCOUNT_NAME}.file.core.windows.net/${SHARE_NAME}\", \"version\": \"3.0\"}"
cf bind-service demo-uploader demo-smb -c "{\"username\": \"${STORAGE_ACCOUNT_NAME}\", \"password\": \"${STORAGE_ACCOUNT_KEY}\"}"
cf start demo-uploader
```

`cf env demo-uploader`の結果は次のようになります。

![image](https://user-images.githubusercontent.com/106908/77229897-cd9b4d00-6bd3-11ea-9b57-27fcc7d2f1a3.png)

環境変数`VCAP_SERVICES`の中の`smb`内に次の要素が含まれています。

```
    "volume_mounts": [
     {
      "container_dir": "/var/vcap/data/b96daab0-24ab-4912-8736-3fabdb82a9c6",
      "device_type": "shared",
      "mode": "rw"
     }
    ]
```

`container_dir`がコンテナ内にマウントされたSMBのディレクトリです。

アプリケーションがこのディレクトリにファイルを書き込めば、コンテナが再起動してもファイルは失われません。

この値は、
* Spring Boot 2.2以上では`${vcap.services.<SERVICE_INSTANCE_NAME>[volume_mounts][0][container_dir]}`で
* Spring Boot 2.1以下では`${vcap.services.<SERVICE_INSTANCE_NAME>.volume_mounts[0].container_dir}`で

参照できます。

> Spring Boot以外の場合は、[`.profile`](https://docs.cloudfoundry.org/devguide/deploy-apps/deploy-app.html#profile)内で`jq`コマンドを使ったり、`echo $VCAP_SERVICES | awk "match(\$0, /\/var\/vcap\/data\/([0-9a-z\-]+)/){print substr(\$0, RSTART,RLENGTH)}"`で取得した値を環境変数で設定することになります。

`demo-uploader`では次のように使用しています。 <br>
https://github.com/making/demo-uploader/blob/master/src/main/resources/application.properties#L1

`demo-uploader`からファイルをアップロードします。

![image](https://user-images.githubusercontent.com/106908/77230065-fb34c600-6bd4-11ea-9991-e4544184b6d9.png)

`demoshare` File Shareにファイルが出来ていることが確認できます。

![image](https://user-images.githubusercontent.com/106908/77230056-e821f600-6bd4-11ea-9163-08a6d2cbb9e1.png)

```
cf restart demo-uploader
```
してもこのファイルは消えません。
