Webアプリ開発者におすゝめ IBM Cloudで始めるPaaS活用

この文書は [bmxug.tokyo これから始めるPaaS開発相談会](https://bmxug.connpass.com/event/91928/) で発表した資料になります。

# 自己紹介

* Hideaki Tokida (@tokida, FB://hideaki.tokida)
    * BMXUG Board Member (.tokyo, tsukiji)
    * IBM Champion for Cloud 2017-2018 
    * Cloud Evangelist / Nippon Information and Communication Corp.
        * Cloud Native Application の啓蒙 

> BMXUGではスタッフ募集中


# はじめに

## 今日話すこと
* PaaSが簡単にアプリを使えるようにできること
* そんなに特殊なことは必要ないこと

## 今日話さないこと
* Cloud FoundyとかIBM Cloudとかの全体像
* CF/IBMCloudの細かい動作
* ローカル開発の仕方 (Pivotal CFDevの活用）
* 企業ユースで抑えるべきPaaSの利点

# PaaSの動きを知ろう　(デモ)

デモのソースコードはすべてこちらに掲載してあります。
* https://github.com/bmxug/php_sample

## CI/CDを一発で解決する魔法のコマンド cf (bx) push    
* IBM Cloud のベースになっている Cloud Foundry ベースのPaaSでは、たった一つの `cf (bx)` コマンドを利用するだけで `Integration` と `Deploy` が一発で行えます。

```
bx login -u USERNAME  -c ACCOUNT_ID
bx target –cf
bx app push 
```
実行結果は以下のようになります

```
名前:                   bmxug_20180704
要求された状態:         started
インスタンス:           1/1
使用:                   128M x 1 instances
routes:                 bmxug20180704.mybluemix.net
最終アップロード日時:   Wed 04 Jul 13:47:32 JST 2018
スタック:               cflinuxfs2
ビルドパック:           php 4.3.39
start command:          $HOME/.bp/bin/start

     状態   開始日時               CPU    メモリー        ディスク       詳細
#0   実行   2018-07-04T04:48:19Z   0.6%   27.8M of 128M   171.6M of 1G
```

上記に記載されている bmxug20180704.mybluemix.net にブラウザからアクセスしてみましょう。

<img width="972" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/11540/eb0bc599-38e1-e0b8-bede-1bed86931cb1.png">


何が起こったのかを見てみます。

```
❯❯❯ ls -la
total 16
drwxr-xr-x  4 hideaki  staff  136  7  4 12:57 .
drwxr-xr-x  3 hideaki  staff  102  7  4 12:50 ..
-rw-r--r--  1 hideaki  staff   18  7  4 12:57 index.php
-rw-r--r--  1 hideaki  staff  150  7  4 12:51 manifest.yml
```
ローカルにはこのファイルしかありません。

```manifext.yml
applications:
  - path: .
    name: bmxug_20180704
    environment_json: {}
    memory: 128M
    instances: 1
    disk_quota: 1024M
    services: []
```

```index.php
<?php
	phpinfo();
?>
```
この `index.php` をもとに自動的に Integration/Deploy が行われて結果として先程のPHPINFOの画面が表示されました。

## しなかったことはなにか？

*  ソフトウェアに関する **全て** の作業（VM/OS/Webサーバの設定）
    *  VMの手配
    *  OSのセットアップ
    *  HTTPサーバとPHP動作環境の用意
    *  ソースコードからアプリケーションの自動デプロイの環境
*  ネットワークに関する作業（最初からHTTPSで使える）
    *  名前(domain)の登録
    *  HTTPS証明書の取得と設定

##  したことはなにか

* ソースコードを書く
* cf(bx) でpush 

これらの作業を人の手を介さずに利用できる！という点が素晴らしいです。

# もう少し具体的な動作

![image.png](https://qiita-image-store.s3.amazonaws.com/0/11540/6006576a-7dec-3d5b-e04d-562346b6aadb.png)

CFでは、Buildpackとう機能により様々な機能を自動化させています。この仕組みにより様々な開発言語を動かすことができ、また環境依存をなくす事が出来ます。
BuildPackは各言語毎に用意されておりIBM Cloudでも様々な BuildPackが利用できます。

```
❯❯❯ bx cf buildpacks
'cf buildpacks' を起動しています...

ビルドパックを取得しています...

buildpack                                位置   有効    ロック済み   ファイル名
liberty-for-java                         1      true    false        buildpack_liberty-for-java_v3.23-20180628-1052.zip
sdk-for-nodejs                           2      true    false        buildpack_sdk-for-nodejs_v3.20.2-20180524-2057.zip
dotnet-core                              3      true    false        buildpack_dotnet-core_v1.0.26-20170913-1346.zip
swift_buildpack                          4      true    false        buildpack_swift_v2.0.12-20180510-1828.zip
noop-buildpack                           5      true    false        noop-buildpack-20140311-1519.zip
java_buildpack                           6      true    false        java-buildpack-v3.19.zip
ruby_buildpack                           7      true    false        ruby-buildpack-v1.6.46.zip
nodejs_buildpack                         8      true    false        nodejs-buildpack-v1.6.4.zip
go_buildpack                             9      true    false        go-buildpack-v1.8.6.zip
python_buildpack                         10     true    false        python-buildpack-v1.5.22.zip
xpages_buildpack                         11     true    false        xpages_buildpack_v1.2.2-20170112-1328.zip
php_buildpack                            12     true    false        php-buildpack-v4.3.39.zip
staticfile_buildpack                     13     true    false        staticfile-buildpack-v1.4.12.zip
binary_buildpack                         14     true    false        binary-buildpack-v1.0.14.zip
dotnet-core_v1_0_22-20170724-0813        15     false   false        buildpack_dotnet-core_v1.0.22-20170724-0813.zip
liberty-for-java_v3_17_1-20180131-1532   16     true    false        buildpack_liberty-for-java_v3.17.1-20180131-1532.zip
liberty_v3_14-20171013-1023              17     true    false        buildpack_liberty_v3.14-20171013-1023.zip
swift_buildpack_v2_0_11-20180402-2018    18     true    false        buildpack_swift_v2.0.11-20180402-2018.zip
sdk-for-nodejs_v3_20_1-20180509-1706     19     true    false        buildpack_sdk-for-nodejs_v3.20.1-20180509-1706.zip
liberty-for-java_v3_22-20180601-1200     20     true    false        buildpack_liberty-for-java_v3.22-20180601-1200.zip
```

BuildPackには3つの機能があり、Detect(実行環境の検査), Compile(環境の構築) ,Release(リリース準備）を行います。 

* https://github.com/cloudfoundry/php-buildpack/tree/master/scripts
* Buildpackは、自身で作成することも可能です
* Buildpackの機能により、言語ごとに様々な機能を利用して実行することが出来ます。例えばPHPの場合には Composer の定義があれば自動的に実行することが可能です。


## Buildpackの明示的な指定

Buildpackを明示的に指定するとDeploy全体が多少早くなります。またそれ以外にも標準で用意されていない新しいバージョンのBuildpackを指定出来たりと便利です。以下は新しいPHPの7.2.7を利用するために新しいBuildpackを利用した例です

```manifest.yml
applications:
  - path: .
    buildpack: https://github.com/cloudfoundry/php-buildpack.git
    name: bmxug_20180704
    environment_json: {}
    memory: 128M
    instances: 1
    disk_quota: 1024M
    services: []
```

今回は別のレポジトリのbuildpackを指定ししてますが同じパスの場合には #1.1.1 のようにバージョンをつけると特定のバージョンが利用可能です。IBM Cloudの場合には2世代前までのバージョンが呼び出せるそうです。

```..bp-config/options.json
{
	"PHP_EXTENSIONS": [ "bz2", "zlib", "curl", "mcrypt", "mbstring", "mysql", "gd" ],
	"PHP_VERSION": "7.2.7"
}
```

実際に見てみると以下のようになっています。

<img width="999" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/11540/c25fed84-91d6-d1f1-3f2b-723c3b4c44a9.png">

> PHPのBuildpackでは、一つのBuildpackの中に複数のPHPバージョンが格納されています。PHPのバージョンの切り替えは options.json で切り替えることが出来ます（これは PHPのBuildpackの機能によるものです）。Manifestファイルで指定するバージョンは `BuildPack`のバージョンになりますので注意してください



## デプロイした環境の確認

* デプロイしたコンテナにsshでログインすることが出来ます。(cf ssh **appname** )
* IBM Clooudの場合には WebUIから利用することが可能です

<img width="1440" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/11540/148375df-8ac2-3df2-7ca8-e0e8b124dd79.png">

```
vcap@c08d311a-58c8-4b28-61f2-c5f1:~$ ls -la
total 40
drwx------ 7 vcap vcap 4096 Jul  4 05:32 .
drwxr-xr-x 4 root root 4096 Jul  4 05:32 ..
drwxr-xr-x 9 vcap root 4096 Jul  4 05:32 app
-rw-r--r-- 1 vcap vcap  220 Apr  9  2014 .bash_logout
-rw-r--r-- 1 vcap vcap 3637 Apr  9  2014 .bashrc
drwxr-xr-x 3 vcap vcap 4096 Jul  4 05:32 deps
drwxr-xr-x 2 vcap vcap 4096 Jul  4 05:32 logs
-rw-r--r-- 1 vcap vcap  675 Apr  9  2014 .profile
-rw-r--r-- 1 vcap vcap   74 Jul  4 05:32 staging_info.yml
drwxr-xr-x 2 vcap vcap 4096 Jul  4 05:32 tmp
```

上記の app 配下にデプロイしたコードが配備されます。例えば index.php は app/htdocs 以下にコピーされていることが確認できます。

## PHP Buildpackの機能によるカスタマイズ例

ここでは例としてPHPで利用する上での幾つかの設定を変更してみます。これはPaaSというよりもBuildpackで柔軟な作り方ができるという例となります。

### php.ini の変更

php.iniを更新するためには以下のファイルを作成します。この処理を行うとbuildpackないで用意されている初期のphp.iniが上書きされます。

```..bp-config/php/php.ini
short_open_tag = On
```

以下の様に index.phpでショートタグを利用する様に修正します

```index.php
<?
	phpinfo();
?>
```

### Extentionの追加

Extentionの場合には以下のファイルを追加することで初期に用意されます。

```..bp-config.json
{
        "PHP_EXTENSIONS": [ "bz2", "zlib", "curl", "mcrypt", "mbstring", "mysql", "gd" ]
}
```

# もっと活用 PaaSで提供される機能の紹介

IBM Cloudでは、PaaSを活用するために様々な機能が用意されています。大きく分けてその中でも代表的な機能について簡単に紹介していきます。

## コンソール

* CFからの拡張としてDashboardが付いてきます。
* とはいえDeployは `cf(bx)` コマンドであることには変わりません。コンソールではいろいろな機能にアクセスしたりUIで分かりやすく表示をしてくれています。

<img width="1440" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/11540/180aba60-8ab7-4ad4-d700-60f8d70a27d3.png">


## ログ

* ログは `bx logs` でも確認することが出来ますがWebUIを利用した場合にはすべてのログがElasticSearchに格納され kibanaで参照することが可能です。
* 単純な標準出力だけでなく、システム的なログも出力されます。
 * Cloud Foundry API (API)
 * Staging (STG)
 * Router (RTR)
 * Loggregator (LGR)
 * Application (APP)
 * Diego SSH (SSH)
 * Diego Cell (CELL)

<img width="1440" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/11540/0e983536-f78a-b201-116f-f3a2aed8232d.png">

* 普通にKibanaとして活用できますので過去のログなどを検索するのに便利です。またダッシュボードを活用することでアクセス数の推移などにも利用することが出来ます。

<img width="1440" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/11540/e54bb1d9-110e-3385-00a1-029a6e2d5e77.png">

## 監視

* 監視の機能はとても協力で便利です。特に **スクリプトベースの監視** を行うことができるため柔軟性のあるチェックが利用することが出来ます。
* 複数ロケーションから、任意の頻度での試験が実施可能
* HTTP/HTTPSのGETだけでなく、**RESTを利用した（PUT/POSTなど）** の関数の実行も可能

## API管理機能

* APIサーバを構築したい場合、従来であれば API Managementと呼ばれる製品を利用するなどがひつようでしたがこの機能を利用すると簡易的に同じことを利用することが出来ます。
* ケースとしては複数のアプリを連携して動かす際にAPIを提供する機能を用意することがあります。この場合にIBM Cloudの場合個別にFirewallやVPCなどの概念がないためすべてフラットに公開されていることになります。そこでこのAPIの機能を利用しセキュリティを向上させることが簡単にできることになります。
* APIを公開に必要となるTokenKeyの発行や、Swaggerベースの設定など結構充実しています。

| 例えば `/bookinfo` を公開したいと考えた場合、それ以外へのパスのアクセス制御であったり認証であったりといったぶぶんをアプリケーションないに実行することなく API Managementの機能で補うことが出来ます。

## ソース管理機能

* IBMCloudの利用者には無料で **Gitlab** のレポジトリが無制限で利用することが可能です（このgitlabのサーバはIBMが管理しており最新版でないのは残念ですがコストを気にせず利用できる点は素晴らしい）
* また同時にDevOps機能によりパイプラインを利用した自動テスト・自動ビルドなどにも活用することが出来ます。




# IBM Cloudを使う理由

* SaaSがたくさん用意されている！

PaaSの機能だけでアプリを作るのは大変です。例えばDatabaseをPaaSの機能だけで作ることは少し難しいです。しかしIBM Cloudにはおおよそ140種類のSaaSが用意されています。

<img width="1440" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/11540/35cc2514-6392-2dbd-ae54-0cac2ce6a870.png">

この機能はすべてコマンドから簡単にオーダーして利用することが可能なだけでなく **アプリからも簡単に利用する仕組み** が用意されています。 PaaS環境のようなアプリケーションでは、特にCI/CDを利用した自動化環境ととても相性が良いです。


アプリケーションからSaaSを利用する流れ

1. サービスのオーダー（サービスの選択・プランの選択）
2. オーダしたサービスはインスタンス化されます。そのサービスインスタンスをアプリケーションに `bind` します。
3. `bind`をするとアプリケーションから、サービスインスタンスへの接続情報が環境変数経由で読み出すことが可能になります。

<img width="1440" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/11540/851c000e-8079-6640-a07f-f5ab2143e54d.png">

先程のサンプルアプリケーションに `bind`すると環境変数に接続情報が含まれているのがわかります。これによりソースコードに対して **環境依存する接続情報のハードコーディングが不要** になります。

<img width="715" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/11540/35d7dc23-d531-07fb-0dc0-5cc2f4b93800.png">

SaaSへアクセスしたい場合にはPHPの場合には環境変数 `$VCAP_SERVICE` から接続情報を取得すれば良いことになります。これ以外にも環境依存する変数については `環境変数` に定義して利用するのが `流儀` です。( [12factorにおける設定の考え方](https://www.12factor.net/ja/config) )

# IBM Cloud の始め方
## IBM Cloudのアカウント

* IBM Cloudにログインするとアカウントを作成することが誰でも出来ます（クレジットカード不要、要メールアドレス）
* 初期は「ライトプラン」となっています。この状態でPaaSを一定量利用することが出来ます。また「ライトプラン」と併記されたサービスについても利用することが可能です。
    * [IBM Cloud (Watson API)を無期限で無料で利用できるライトアカウントの使い方](https://qiita.com/tokida/items/13408a1d4230608f182f)



###  半年間 $12000 分、利用可能なプロモーションサイト
* https://cognitiveclass.ai/ibm-cloud-promotion/
* これは「トライアルアカウント」という物が6ヶ月間利用できます。昔は「ライトプラン」ではなくて全サービスが利用可能な「トライアルアカウント」がありその機能が半年の期限で利用可能なようです。
* 一度トライアルになるとライトに戻せないので注意が必要です。

> 数や期限に限りがあるかもしれません。

# あとがき
* コード勉強したいけど動かす環境つくることで消耗したくないとか、そもそもパッと公開して反応みたいとかとても簡単にできます。
* そういったライトな利用以外にも最近ではCloud Foundryの採用事例も増えてきているようなので企業内の情報系基盤としても検討されると嬉しいです。([Cloud Foundryの企業採用が進む](https://jp.techcrunch.com/2017/06/19/20170618cloud-foundry-makes-its-mark-on-the-enterprise/) )
* PaaSは特に好きなインフラ技術なので是非コード開発者の方に利用してほしいと思っています。便利な機能が多いのですがまだまだ知られていないと思うのでこの文書がきっかけになれば幸いです。


# 参考文献
* [IBM Bluemixクラウド開発入門](https://www.amazon.co.jp/IBM-Bluemix%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80%E2%80%95%E2%80%95Web%E3%81%8B%E3%82%89%E6%8B%A1%E5%BC%B5%E7%9F%A5%E8%83%BDWatson%E3%81%BE%E3%81%A7%E5%AE%9F%E8%B7%B5%E8%A7%A3%E8%AA%AC-Software-Design-plus/dp/4774190845)
    * 自著ですが、少し前に書いたので一部の情報は古いです。今回の話＋アプリ開発の仕方について書いてあります。今回話していないアカウントの話なども含んでいます。


# 参考資料
* [Bluemix User Group](https://bmxug.connpass.com/) 公式ページ
* [PaaS勉強会](https://paas.connpass.com/) Deepな勉強会
* [Cloud Foundry Docs](https://docs.cloudfoundry.org/) 公式ドキュメント
* [IBM Code](https://developer.ibm.com/code/) 公式サンプル集（必見）
* [IBM Cloud Blog](https://www.ibm.com/blogs/bluemix/) 日々更新される情報はこちらの公式ブログをチェック
* [PCF Dev (Pivotal Cloud Foundry) をmacにインストールしてみたメモ](https://qiita.com/Esfahan/items/30fd720d37f645028c7d) PCFを利用すればローカル環境でもCFが利用できる！
* [Cloud Foundryで学ぶ、PaaSのしくみ講座](https://www.slideshare.net/jacopen/paas-for-beginners) Jacopen先生のお勉強資料とてもわかり易いので必見（この他のSlideshareの資料も必見）
* [PlanBのおすすめ](http://www.niandc.co.jp/sol/tech/list.php) NI+C社のテクニカルブログ,Bluemix関連
* [Cloud Foundry にアプリケーションを push する際の典型的な10のエラー](https://www.slideshare.net/nota-ja/cloud-foundry-push-10) 少し以前の記事ですが必読
* [Wordpress on Bluemix ハンズオン](https://www.niandc.co.jp/sol/tech/date20160619_549.php) 少し古いですがComposerやサービスを併用したアプリの例としてリンクしておきます