Cloud Foundry on IBM Cloud で Blue-Green Deployment を試してみよう

この投稿は [Using Blue-Green Deployment to Reduce Downtime and Risk](https://docs.cloudfoundry.org/devguide/deploy-apps/blue-green.html) を IBM Cloud 上で実際に体験するための、日本語の簡単な手順書です。

日本語ですと [Bluemixアプリ開発と管理#14 Blue-Greenデプロイを使用してダウンタイムとリスクを削減](https://qiita.com/MahoTakara/items/0e4445e04646b6fb5259) の投稿が読みやすく、全体を理解する際の参考になります。

# 今回実施する内容

Blue-Green Deployment は Cloud Foundry において、2つの運用環境をうまく組み合わせることで、サービスのダウンタイムやリスクを削減する手法です。既に公開している Web サービスなどを、ダウンタイムなしで新しいバージョンに置き換えることが可能です。

Cloud Foundry でサービスを提供する場合にはほぼ必須となる運用スキルだと思いますので、今回の手順書をもとに体験してみてください。

# IBM Cloud ID の取得

IBM Cloud ID をまだ取得していない方は、以下の3分間ビデオを参照してみてください。

* [IBM Cloud のライトアカウントを作成しよう](https://www.youtube.com/watch?v=Krn1jQ4iy_s&list=PLzpeuWUENMK28zoOXBcf4t8KLlIkteOmz&index=2&t=0s)

# IBM Cloud CLI の導入

IBM Cloud CLI が未導入の方は導入してください。

"ibm cloud cli standalone" などで検索し「スタンドアロン IBM Cloud CLI のインストール」ページを探し、自分の環境にあったインストーラーを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/8929eb8b-10e4-7cd0-783f-7bf120c04b7a.png)
ウチはWindows環境なので以下な感じ。[Next] と [Finish] クリックするだけで終了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/a9f7bdf5-1fcc-173b-672e-1a94accf2141.png)
インストールが完了したら、コマンドプロンプトを開いて(既に開いていたら開き直して)、`ibmcloud --version` を実行してCLIが利用可能なことを確認しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/94332259-e5e7-28a5-a9c6-e6a4d48d0f5c.png)

# IBM Cloud にログインする

以下のコマンドでIBM Cloud にログインします。

```
ibmcloud login
```

「Email」と「Password」は IBM Colud ID を取得したときに利用したものを入力してください。地域(リージョン)は Cloud Foundry を利用できるものを選択する必要がありますが、特に理由がなければ `5` の `us-south (Dallas)` を選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/886b1378-7bd1-6d95-afcd-9be38fd281e8.png)
引き続き、Cloud Foundry 利用のため 以下のコマンドを実行します。

```
ibmcloud target --cf
```

以下のように Cloud Foundary 関連の情報が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/a1d9fb97-8e0e-a346-a0b5-c45dfc20b9ce.png)

## 補足:地域(リージョン)について

IBM Cloud には地域(リージョン)の概念があって、`ibmcloud regions` コマンドで一覧を出力できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/8ecda9e4-98b9-4d22-95f0-88da7d6cfc35.png)
地域ごとに利用できるサービス内容が異なり、Cloud Fundry サービスを提供していない地域を選択したまま `ibmcloud target --cf` コマンドを実行するとエラーになります。

再ログインしても地域の選択が表示されない場合、地域の明確な指定には logon コマンドの -r オプションを使用します。例えば `ibmcloud login -r us-south` で再ログインすれば地域は us-south(Dallas) となり、Cloud Fundry サービスを利用できます。

# ブルー環境を構築する

まずは、最初の公開バージョンであるブルー環境を作成します。今回は PHP を用いた簡単な Web ページを用意してみます。

まずは blue というディレクトリ(フォルダ)を作成して、その中に移動します。以下は Windows での実行例。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/2a2e526f-97b6-7c89-9f35-0eb89b210929.png)
`index.php` というファイルを作成し、内容は以下のように基本的な PHP の記述にします。body タグの背景色を青色っぽくしてあります。

```php:index.php
<html>
 <head>
  <title>Blue Environment</title>
 </head>
 <body style="background-color:#aaf">
  <?php phpinfo(); ?>
 </body>
</html>
```

さて、準備ができましたので、IBM Cloud 上の Cloud Foundry 環境にアップロードして公開しましょう。以下のコマンドを実行します。

```
ibmcloud cf push blue -m 128M -n yamachan-demo-time
```

`cf push` コマンドで `blue` アプリを `yamachan-demo-time` というホスト名で公開しています。

【ヒント】-m 128M のオプションは実行時のメモリサイズの上限を指定するもので、必須ではありません

実行時の様子は以下のような感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/ce2c274f-57ac-fd84-74b3-cd5f957e38b3.png)中略
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/a3033bdb-cfe2-f97b-ec5d-d5de4c903c6e.png)
そして Web ブラウザで [https://yamachan-demo-time.mybluemix.net/](https://yamachan-demo-time.mybluemix.net/) にアクセスすると、作成した PHP ページが公開されているのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/61f2e9a5-c4e3-6ccc-7489-2c15ed0aba77.png)
これでサイト運用は開始、ですね。

現時点では以下のように、blue として構築した実行環境が稼働しており、yamachan-demo-time.mybluemix.net というアドレスへのアクセスがここに誘導されている、という状況です。
![blue.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/ad3981af-41df-bfd8-a8e7-4cccd74fccd0.png)

## 補足:簡単なWebページ作成

今回、フォルダ内に簡単な内容のファイル1個を用意しただけで、なにやら複雑な Web ページが公開されて、ちょっと驚いた方も居るでしょうか？今回、この話題は本質ではありませんが、ここで簡単なネタバラシをしておきます。

今回、以下の2つを使って準備を簡単に、まあ正直に言えば手を抜いています。

### PHP に用意されている phpinfo() 関数

`phpinfo()` は、PHP の入門書を開くと、たいてい最初のほうで紹介されている有名な関数です。この関数はいま実行中の PHP 環境の様々な情報を、HTML のテーブル形式で出力してくれます。これ1行いれておくだけで、これから使う PHP の様々な情報が見られるわけで、非常に便利な関数です。

今回の blue サンプルは、この `phpinfo()` を表示するだけの簡単なサンプルを流用して、それに背景色を設定しただけ、のお手軽な Web ページなのです。

### Cloud Foundry 環境における自動パッケージ選択

Cloud Foundry も仮想サーバーを提供するサービスですから、YAMLファイル(manifest.yml)とか、JSONファイル(package.json)とか、何か設定ファイルを用意しなければいけない、と思いませんか？

むろん用意すればちゃんと対応してくれますが、Cloud Foundry にはもっとお手軽なモードがありまして、これら設定ファイルで指定されていない場合、実行環境を自動判別してくれるんですよ。

例えば index.html しかないフォルダを公開しようとした場合「あ、これは静的なWebサービスだな」と判断して [Staticfile Buildpack](https://docs.cloudfoundry.org/buildpacks/staticfile/index.html) を自動で選択してセットアップしてくれます。

そして今回、フォルダの中には index.php ファイルしか無い訳ですから「あ、これはPHPなWebサービスだな」と判断して PHP 用の Buildpack でセットアップしてくれました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/3c9d5243-605e-1dee-3529-9d85646ac47d.png)
このお手軽さ、私は個人的に大好きです。

# グリーン環境を構築する

さて、より新しい、次の公開バージョンであるグリーン環境を作成します。ブルー環境をコピーして、index.php の内容を修正します。Windows だと以下のような感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/a3152cb4-b99f-8b71-20a6-638b2930f312.png)
index.php の修正内容は2ヶ所、title タグの中身を Green Environment に書き直すことと、body タグの背景色を緑っぽい色に変更すること、です。

```php:index.php
<html>
 <head>
  <title>Green Environment</title>
 </head>
 <body style="background-color:#afa">
  <?php phpinfo(); ?>
 </body>
</html>
```

さて、準備ができましたので、IBM Cloud 上の Cloud Foundry 環境にアップロードして公開しましょう。green ディレクトリで、以下のコマンドを実行します。

```
ibmcloud cf push green -m 128M -n yamachan-demo-time-temp
```

そして Web ブラウザで [https://yamachan-demo-time-temp.mybluemix.net/](https://yamachan-demo-time-temp.mybluemix.net/) にアクセスすると、作成した PHP ページが公開されているのがわかります。タイトルと背景色が異なりますよね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/d41efd2e-1833-7edf-c786-e41814f28975.png)
これでグリーンもサイト運用を開始、ですね。

【ヒント】2つのURLの違いを見逃さないでください。今回のグリーン用のURLにはホスト名の最後に -temp が付与されていますよ

現時点では以下のように、blue として構築した実行環境が稼働しており、yamachan-demo-time.mybluemix.net というアドレスへのアクセスがここに誘導されている、また green として構築した環境も動作しており、yamachan-demo-time-temp.mybluemix.net というアドレスへのアクセスがここに誘導されている、状況です。
![blue_and_green.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/c75d372f-48c6-5fc1-6a2b-2cadf5bc2f36.png)

# グリーン環境へのルートを変更する

さて、ここが今回の山場です。まず、map-route コマンドのヘルプを見ておきましょう。アプリに URL ルートを追加してくれる、コマンドのようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/2eea7ba0-7faf-fcef-9625-9ef1e6929866.png)
以下のコマンドを実行します。`green` アプリに対し、`mybluemix.net` ドメインにおいて、`yamachan-demo-time` というホスト名を追加のルートとして指定しています。

```
ibmcloud cf map-route green mybluemix.net -n yamachan-demo-time
```

特にエラーもなく実行できたようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/25b0f93c-e969-84be-d086-6ec4f55ef75a.png)
これで、green には blue と同じホスト名がルートとして追加されたので、図としては以下のような状況になっているはずです。
![blue_and_green2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/444ea377-d875-eee9-5f63-074f38a3c758.png)
この図の意味するところは

1. yamachan-demo-time-temp.mybluemix.net へのアクセスは green にのみ誘導される
2. yamachan-demo-time.mybluemix.net へのアクセスは blue もしくは green に誘導される

だと思われます。実際に試してみますと、1. は確かに Green Environment のページを表示します。そして 2.は、以下のように、Blue Environment のページと、Green Environment のページが、リロードのたびにランダムに表示されるように見えます。
![qiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/2a746772-edf0-1a4f-09ce-070adfd2b537.gif)
見ていて面白いですね。現在のバージョンであるブルーと、新しく作成したグリーンが同じ URL 上で同時に稼働しているわけです。

# ブルー環境をルートから外す

さて、このままいつまでもブルーとグリーンの環境を同居させるわけにもいきません。今回の目的はブルー環境をスムーズにグリーン環境に移行することですから、グリーン環境の準備ができた今、ブルー環境を外していきましょう。

さきほどの map-route に似たコマンドで unmap-route というコマンドがあり、これを用いてblue を yamachan-demo-time ホストから外し(アンマップし)ます。

```
ibmcloud cf unmap-route blue mybluemix.net -n yamachan-demo-time
```

問題無く実行できたようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/eb641597-59a6-bd93-6c11-2583c0ec70d5.png)
これでルートは以下の図のようになり、ブルー環境を表示する方法がなくなります。
![green_only.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/29fa40c4-5a83-224a-0889-716dbb70e83a.png)

# グリーン環境へのテンポラリのルートを外す

さて現時点では、以下の 2つの URL で Green Environment ページにアクセスできます。

1. https://yamachan-demo-time.mybluemix.net/
2. https://yamachan-demo-time-temp.mybluemix.net/

ここで 2. の URL を無効にすれば、green 環境が完全に blue 環境を置き換えた状態になるでしょう。コマンドは以下になります。

```
ibmcloud cf unmap-route green mybluemix.net -n yamachan-demo-time-temp
```

問題無く実行できたようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/78e5634e-c075-8b7c-f0ab-80a72965b7bc.png)
これでルートは以下の図のようになり、ブルー環境がグリーン環境に完全に置き換わりました。
![green_only2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/fa48345f-2066-e8e7-60f1-f33d1abbd0b9.png)

# 後片付け

今回のアプリは利用メモリ量も少なく、放置しておいても課金されることは無いとおもいます。が、今後いろいろ試していくために、削除方法も手順に含めておきます。

[cloud.ibm.com](https://cloud.ibm.com/) から IBM Cloud にログインし、左上の [IBM Cloud] をクリックしてダッシュボードに移動して、[リソースの表示]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/7e851004-155d-d0b4-db6b-d057a8fde792.png)
Cloud Foundary アプリの下に blue, green のアプリが表示されているはずなので、右にあるメニューから、それぞれ [削除] を実行してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/ee4e1164-a508-564a-b856-a1803d98e7a3.png)
削除の際に「経路」があればそれもチェックした後、[削除]ボタンで削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/0fd31a32-1c00-48c2-dfa5-998c01e34273.png)
リソース・リストの項目が全て (0) になれば、後片付けは終了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/eec9980d-352b-4d5e-5e94-e55f5f971c98.png)

# 何が嬉しかったの？

以上の操作で、最初はブルー環境が公開されていたサイトを、より新しいグリーン環境に置き換えることができました。

もし最初にブルー環境が公開されている時に、更新しようとしてブルー環境を push した場合、push が終わるまでの間の数分間、Web ページへのアクセスがエラーになってしまいます。またもしその新しいバージョンに本番環境における問題があった場合、元のバージョンに戻すのにまだ時間がかかってしまいます。

新しいバージョン(グリーン環境)をまずテスト用のURLで公開し、動作を確認した後に本番URLにマップする。そしてそれも問題なければ、元のブルー環境を外す。今回の Blue-Green Deployment のやり方は、Web ページがエラーになりません、つまりダウンタイムが発生しませんし、安全で問題の少ない更新のやり方であると思います。

次のバージョンを公開する際は、今度は blue を新しい公開環境とし、ブルーとグリーンを入れ替えて今回の操作をすればokです。

# というわけで

以前から気になっていた Cloud Foundry の Blue-Green Deployment を最新の環境で試し、かつ日本語で手順をまとめてみました。

皆さまにもこの方法を体験していただき、アプリケーション開発の際に役立てていただけたら嬉しいです。

それではまた！