heroku 中級編 - 1分で実現するCI/CDをHeroku Pipelinesで 

Heroku Advent Calendar 2018 9日目。1年ぶりにTOEICを受験してきました。TOEICの所為にして、投稿が地味にちょっと遅れたことをなかったコトにしようとする、悪い大人の見本、しょっさんです。未だに、Google IMEが「しょっさん」を覚えてくれず「ショッさん」って変換するの、ほんとに憎いです。そろそろ覚えてください。

# 「できる」ということ

長いこと「エンジニア」人生を送ってくると、いろんなエンジニアがいます。技術力の高すぎる風光明媚なエンジニアや、志だけが高いだけのエンジニアの中に、お客様の要求に対して技術で猛攻撃する傾向のある人を見かけて、悲しい思いをすることがあります。技術は人や世界を助けることは多いのですが、技術だけで全ては片が付かないことや、どんなに論理が優れていても受け入れがたい倫理や感情論はどうしても存在します。そういったものも考慮できることが、優れたエンジニアリングスキルを持っている人と信じています。

さて、そんな中、ずっと昔からどうしても受け入れられない言葉があります。エンジニアの発する「できる」という言葉。01志向の中にあって、Yes/Noの答えを求められたときに、判断基準としてわかりやすいあの「できる」です。`RFP`(Request for Proposal)や仕様書などで定義される、要求機能・非機能に対して答える「できる」というあれです。この「できる」について、みなさまどのようにお考えでしょうか。わたしは、この「できる」という言葉を信用しないことにしています。崇高なエンジニアの場合は、「できます」と答えたあと「しかしながら（　＾ω＾）・・・」という自分に不利益な制約について正しく述べるか、質問をすれば正しく回答します。できる理由とできること(範囲)、実際には実現できないことや実現の困難さを正しく述べられることは、一流のエンジニアに重要な「説明責任(Accountability)」です。

なぜ、こんな話をするのかと言うと「できる/できない」は実は「Yes/No」という二軸ではなく、その間には広く深い闇が広がっている所為です。この広く深い闇をなかったコトにして「できる」というエンジニアの、いかに多いことか。自分も昔はそうであったこともありますが、お客様の要求する「できる」とひじょーーーーーーーーーーーーーに乖離した「できる」が世の中には多く存在します。わたしは、この期待値を遥かに下回った「できる」がひじょーーーーーーーーーーーーーーーーーーーに嫌いです。

少し深淵を探ってみましょう。「できる」はある程度、次の段階で示せます。

1. すでに実装済み・実現されている技術であり、今すぐ使えるという意味の「できる」
2. 標準で実装されているが、最初から使えるものでないが、ボタン一つで設定をオンにしたり、設定項目を１つ２つ設定すれば使えるという意味の「できる」
3. オプション機能、またはある機能を使えるようにした上、ある程度の設定をすれば使えるという意味の「できる」
4. 複数の機能や、複数のコンポーネント・オプション・仕組みを組み合わせることで使うことのできるという意味での「できる」
5. 全く別の想定していなかったコンポーネント(ソフトウェアやハードウェアなど)を追加すると、実現可能性があるという意味での「できる」
6. 開発すれば何でも「できる」

お客様の聞いてくる「できる」の期待値はだいたい１か２です。IT経験の長いお客様でも３までで、４からは「できる」の意味合いが別のことと期待しています。４からは「〜をすればできる(△)」という領域です。エンジニアの中では６まで含んで「できる」と答えるエンジニアがいるので、困ったものなのです。

これ、仕事ではなくとも、素人さんに「・・・・できる？」と云う期待値が１か２での質問に対して、４か５の状態のことを「できる」と返すエンジニアが散見されます。「できる」とはそういうことじゃないんです。「容易に実現することができる」かどうかなんです。素人は所詮素人さんなんです。「メール送りたければ`sendmail.cf`書けばいいじゃん」って素人はもとより、最近のエンジニアに伝えても、それは「できない」なんです。今どき`sendmail`かよというツッコミを求めてるのではなく、これが一番伝わりやすそうな年齢層に向けて書いてるというだけです。

# だからどうした。

世の中「カンタンにできます」ということを訴えているサービスはとてもたくさんあります。そして、本当にそれらが容易に実現される世の中にもなってきました。私としては、ITはそのように多くのものを容易に実現するための、良いパートナーであるべきであると心から願っています。「こうすればできる」と甘んじてその先に進まないのではなく、「よりカンタンに」「シンプルに」実現できること、そしてそれを実装していくことがエンジニアとして重要なことだと考えています。

複雑なことを組み合わせて実現できることは崇高で風光明媚なことですが、それを簡単に利用させることのできるようになることが、本来のエンジニアリングではないでしょうか。

余計な手間を使わずに、本当に必要なことに時間をかける。今後、日本は労働人口減少に従ってエンジニアの数も減少していきます。エンジニアこそ、より時間をかけずに、新しい使いやすいサービス実現のために時間を使うべきなのです。

だから、`Heroku` なんです(ようやくここまできた)

# 1分で実現するCI/CD環境

## 時間の重要性

前置きが多いと思われたかもしれませんが、残された人生も少ない私にとって「時間」はとても大切です。一番上の娘も成人し、そろそろ孫がという世代に近づいてきたということは、死期もそれだけ迫っているということです。というか、もういつ死んでもおかしくない年齢です。健康にいくら気を使っても、どうにもならないことが多く、どんなに鍛えても風邪をひくし、かんたんに重症化します。夜は早く寝たいし、少ない労働力で、多くの金銭を手にしたいわけです。まだまだ娘たちには金と手間がかかります。ホントお金をもっとください。

閑話休題。

さて、開発者にとって重要なコアコンピタンスはなんでしょうか。そです。開発することです。すぐれたソフトウェアを開発することです。そのソフトウェアを動かす環境については、微塵も時間を使いたくないはずです。本来は。`aPaaS`(Application Platform as a Services)や`PaaS`はそれらを改善してくれましたが、まだまだでした。ソフトウェアの動く環境はこれらが提供してくれましたが、開発していくための環境はまだまだこれからという部分があります。

## カンタンに設定して使えるCI/CD

世が`DevOps`だ`NoOps`だと騒ぐより以前から、開発者のために素晴らしいプラットフォームを提供しようとがんばってきたのが`Heroku`プラットフォームです。元はと言えば`Ruby on Rails`のための`PaaS`でしたが、現在では８言語に対応したプラットフォームを提供しています。しかもそれのみならず、標準的な機能として`CI/CD`(Continuous Integration/Continuous Deployment)をサポートするツールも提供していることが`Heroku`の特徴です。

`DevOps`は文化・組織論をベースにしたプロセス進化論ですが、その中においてソフトウェアの開発を自動化し、生産性を向上させるCI/CDといった考え方も開発されました。背景にアジャイルの開発などもあったでしょう。迅速な開発を行うための様々な苦労から生み出されてきたことでしょう。`CI`は開発プロセスを自動化します。コードがコミットされれば、その時点でのソフトウェアをインテグレーション・ビルドし、テストまで行います。ソフトウェアが正しい状態で稼働することをいかにして保つかを根本理念として持っています。`CD`は、その状態を可視化します。実際に開発・テスト用の一時的な環境で、それらが動いていることを視認して確認することができます。

これら`CI/CD`は、インフラがクラウド化され、IT基盤が容易に廃棄して、新しい環境を作ることができるようになり、実現できるようになりました。様々なツールを組み合わせて実現できるようになりましたが、それでも複数のコンポーネントやサービスを組み合わせて実現せねばできないものでした。それは、コードバージョニングを司るツールと開発・テストを行う環境とそれらを管理するツール、実際に稼働するプラットフォームなどが分離していたことから、それらを組み合わせることが必要不可欠でした。

`Heroku`は、コードバージョニングこそ`GitHub`にまかせていますが、それ以外のすべてを`Heroku`プロットフォームですべて実現することで、`CI/CD`を実装できる環境を「カンタンに」実現できることに成功しました

開発者の方々へ`Heroku`を進める理由の大半が「カンタンに」多くのことを実現できるからです。覚えることが少なければ、トレーニングの時間も少なく、すぐにプロジェクトを立ち上げられます。実際の作業時間が少なければ、それだけプロジェクトの期間を削減できます。ソフトウェアの開発に多くの時間を割くことができます。

## 1分で実現するCI/CD

では実際に1分で環境を準備しましょう。慣れてないと、もう少し時間がかかるかもしれませんが、5分も必要としないでしょう。

### 前提条件

1. Herokuアカウントを持っている
2. GitHubアカウントを持っている
3. GitHub上に`CI/CD`するためのソースコードツリーがある・またはこれから準備する

また、無料アカウントやクレジットカードで登録されているユーザの場合、`Heroku CI`(自動テスト)を利用すると月に$10かかります。Heroku Enterprise契約されているユーザの場合は、`Heroku CI`は追加の課金なくご利用いただけます。

### 設定する前に

有償だと幅が広がりますが、無料でも十分、それらの機能の恩恵を受けられます。作業内容は次の３つです。

1. Heroku Pipelines を作成する
2. 必要な環境を割り当てる
3. 各機能を`オン`にする

今回設定する`CI/CD`シナリオは、次のとおりです。

1. `GitHub`上で`PR`(Pull Request)されたら、そのPR環境をデプロイして利用可能にする
2. `GitHub`上のソースコードが変更されたら自動的にテストを行う
3. `GitHub`上の`master`ブランチにソースコードがマージされたら、ステージング環境へ自動的にデプロイする

### 1. Heroku Pipelines を作成する

Heroku/GitHubにはすでにログインしている状態からスタートします。

まずは、Herokuパイプラインを作成しましょう。

Herokuダッシュボードのアプリケーション一覧の画面からはじめます。右上の`New`ボタンをクリックして、プルダウンメニューから`Create new pipeine`をクリックします。

<img width="258" alt="Screen Shot 2018-12-09 at 16.52.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/37263/a1e0ddc5-3a0d-ddf5-85e1-c785da3c35c6.png">

「Create New Pipeline」では、(1)パイプラインの名前を入れる (2)GitHubリポジトリと連携する、の２つの作業が必要です。パイプラインの名前は、自分の管理するパイプラインの中に同じ名前がなければ、好きな名前を割り当てられます。好きな名前を入れましょう。次に`Connect to GitHub`ボタンをクリックします。

![Screen Shot 2018-12-09 at 16.55.26.png](https://qiita-image-store.s3.amazonaws.com/0/37263/5ef3bcf3-108a-cd4d-dfe5-40981e12f10e.png)

`GitHub`の認可画面が出てきますので、すでにログインしていれば次の画面になります。未ログインの場合はログイン画面になるでしょうから、ログインします。対象のユーザのみならず、他の`Organization`も利用する場合は、それらも「Grant」します。そして、対象のユーザ/組織への認可で問題がなければ「Authorize heroku」　ボタンをクリックしましょう。

![Screen Shot 2018-12-09 at 16.58.10.png](https://qiita-image-store.s3.amazonaws.com/0/37263/77cfc732-77c4-cc13-0c3b-9e91f7e2df77.png)

正常に認可されると、次のように`Connect to Github`欄に「search box」が出てきます。左側がユーザ/組織を選択する部分で、そこを指名したあと、今回、連動したいGitHubリポジトリの名前を入れて「Search」ボタンを押します。

![Screen Shot 2018-12-09 at 17.03.19.png](https://qiita-image-store.s3.amazonaws.com/0/37263/c0d521a6-65e1-a207-8a63-701b7e691e8a.png)

対象のリポジトリの「Connect」をクリックして、問題がなければ「Create pipeline」をクリックします。これで、`Heroku Pipeline`の作成は完了です。

### 2. 必要な環境を割り当てる

正常に作成されると、`Heroku Pipeline`のダッシュボードになります。まだ`Heroku App`が、`STAGING`と`PRODUCTION`に割り当てていません。次にそれらの`Heroku App`を作成します。

![Screen Shot 2018-12-09 at 17.06.52.png](https://qiita-image-store.s3.amazonaws.com/0/37263/ccfc21ab-b427-2cd7-1cc4-730024fac3ee.png)

おもむろに該当環境の「Add app...」ボタンをクリックします。既存の`Heroku app`も指定する場合には、`Search for existing app...`へ文字を入れて該当のアプリケーションを指定して選択して割り当てます。今回は新規に作成しますので、「Create new app...」を押します。

<img width="406" alt="Screen Shot 2018-12-09 at 17.08.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/37263/853413c3-463d-510c-bcb1-625e5365f904.png">

画面右側に、`Heroku app`を新しく作成できる画面がにゅっと現れます。`App name`に好きな名前を入れて作成することもできますが、全世界で唯一の名前になる必要がありますので、根気よく緑色になるまで入力してください。「めんどくさい」と思われたら、空欄のママでも自動的にHeroku側が割り当ててくれますので、そちらもご利用ください。ここでは「Create app」ボタンをクリックすれば、すぐに`Heroku app`が作成されます。

![Screen Shot 2018-12-09 at 17.11.33.png](https://qiita-image-store.s3.amazonaws.com/0/37263/c32511ee-df01-f91c-6b63-9db946f64743.png)

問題なく作成されたでしょうか？

うまくいきましたら、同じ要領で、もう一つの環境にも`Heroku app`を割り当ててください。わたしの方ではこの様になりました。慣れてくれば、ここまでで30秒とかからないはずです。

![Screen Shot 2018-12-09 at 17.16.26.png](https://qiita-image-store.s3.amazonaws.com/0/37263/8a7cd11d-a0cc-4518-934f-7533bbccd620.png)

ここまでで、テスト環境と本番環境を割り当てるところまでが終了です。あとは、自動的なテストとデプロイの設定です。

### 3. 各機能を`オン`にする

次の３つの機能をオンにします。それだけです。

1. Heroku CI - 自動テスト (有償です orz)
2. Review App - PR環境の自動生成
3. Auto Deploy - ブランチと連動して自動的にアプリをリリース


#### 1. Heroku CI - 自動テスト

`Heroku Pipeline`ダッシュボードの上の方に、次のよな帯が出ていればしめたものです。「Enable CI」ボタンをクリックすれば完了です。

<img width="1210" alt="Screen Shot 2018-12-09 at 17.18.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/37263/ec6fc2b4-64fe-d5c7-0294-7a49f51ea276.png">

正式な設定方法は、`Heroku Pipeline`ダッシュボードの`Settings`タブ内にある`Heroku CI`欄で「Enable Heroku CI」ボタンをクリックすればよいです。

![Screen Shot 2018-12-09 at 17.18.30.png](https://qiita-image-store.s3.amazonaws.com/0/37263/a28252f9-4a10-1cf4-1c58-c694ab8306ca.png)

この`Heroku CI`ですが、無償アカウントでは利用できません。ごめんなさい。試しにやってみると、こんな赤いポップアップが出ます。ツラい。

<img width="389" alt="Screen Shot 2018-12-09 at 17.24.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/37263/8d7ee3fb-eef9-b0f4-e937-0576e0afbdb9.png">

`Heroku CI`を利用するには、クレジットカードを登録したユーザアカウントか、Heroku Enterprise 組織内のユーザアカウントを利用する必要があります。また、クレジットカードユーザの場合は月に$10/月かかります。よーく見ると書いてありますよね。

`Each pipeline with Heroku CI enabled is charged $10/month. Charges for dyno and add-on usage from test runs are prorated to the second. All charges are billed to the selected pipeline owner.`

また、テスト用に起動するCI環境のDynoやAdd-onも秒単位で課金の対象となりますとあります。好き放題に使うには Heroku Enterprise契約にしましょう。営業紹介するので、いつでもお声がけください。

`Heroku CI`を使えるようにすると、`GitHub`リポジトリ内のソースコードが変更されるたびに、`Heroku CI`が実行され、そのテスト記録が全て残されます。ダッシュボード内の「Tests」タブ内がこんな画面で埋め尽くされます。テストに失敗すると、赤い文字になりますよ。

<img width="1506" alt="Screen Shot 2018-12-09 at 17.30.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/37263/bd501746-b8dd-39b5-2127-00943e3e54f3.png">

#### 2. Review App - PR環境の自動生成

PR環境を作成しましょう。これをHerokuでは`Review App`と呼んでいます。GitHubでプルリクエストを上げると、そのプルリクエストソースコードツリーを拾って、一時的にレビュー専用の環境として作成します。作り方もカンタンですし、無償アカウントでも利用いただけます。まずは「REVIEW APPS」の「Enable Review Apps...」ボタンをクリックします。

<img width="399" alt="Screen Shot 2018-12-09 at 17.32.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/37263/84ced1ae-559a-c3f8-33d7-faebe322fb13.png">

「Enable Review Apps」では３つ、選択するものがあります。

1. `Inherit config vars from an app in this pipeline` - 環境変数を、どの`Heroku App`ベースとするかを指定します。どの環境を引き継ぐか、ということですね。
2. `Create new review apps for new pull requests automatically` - `GitHub` で `Pull Request` があがったら、自動的に`Review App`を作成します。チェックしておきましょう。
3. `Destroy stale review apps` - 作成してから経過した時間で自動的に勝手に削除します。１、２、５、30日から選択できます。なお、`Pull Request`されたソースコードが、別のブランチにマージされると、自動的に`Review App`も削除されます。
 
<img width="620" alt="Screen Shot 2018-12-09 at 17.33.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/37263/0d105d8c-817a-f66d-0fea-5b23c07d2b75.png">

※ これらのうち、2. 3. は後でいつでもカンタンに変更可能です。1.は変更できないので、一度`Disable`してからの再作成となります。

#### 3. Auto Deploy - ブランチと連動して自動的にアプリをリリース

最後の設定ですね。ここまででだいたい45秒です。

本番の環境へもできますが、いきなり本番ってのはきついので、`master`ブランチと連動して、ステージングの環境へリリースされるように設定します。`STAGING`に設定されている `Heroku app`内の上下矢印になっているボタンをクックします。次のプルダウンメニューが出てきますから「Configure automatic deploys...」をクリックしましょう。

<img width="404" alt="Screen Shot 2018-12-09 at 17.43.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/37263/f8ca1d2d-1923-27b7-213e-ce589890ad96.png">

ここでの設定は２つだけです。

1. `Choose a branch to deploy` - どのブランチにマージ(コミット)されたら、自動的にこの環境へデプロイするか、という指定です。今回は`master`としておきましょう。
2. `Wait for CI to pass before deploy` - デプロイ前に、`Heroku CI`が成功していることを条件とする。`Heroku CI`が失敗したときはデプロイしないようにできるわけです。無償アカウントの場合もチェック入れられますが、`Heroku CI`は実行されないので、とくに関係なく自動的にデプロイされるようです。

<img width="620" alt="Screen Shot 2018-12-09 at 17.44.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/37263/60cae1e7-1812-7b12-3d6b-3d06b11b9675.png">

これらの設定が終わったら「Enable Automatic Deploys」ボタンをクリックします。次の画面が出てくれば成功でしょう。なぜか、この画面が出て止まりますので、問題なければ右上の「☓」を押しときます。

<img width="616" alt="Screen Shot 2018-12-09 at 17.44.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/37263/4b0e3d6a-eaf7-0325-e9db-d5f597208a2b.png">


# 設定を終えて

ここまでで55秒程度で実演可能です。ほんのこれだけで、`CI/CD`を実現するに十分な環境を準備することができます。必要最低限な少ない設定しかありませんが、これ以上に細かく何かを設定する必要がある場合には、そのようなサービスを利用・連携する必要があります。しかし、そこまで必要なことがどれだけあるのか、そこまでする必要性はどこまであるのか。本当に必要なことを、必要なだけ、シンプルにアイディアを高めて実践していきましょう。

今回は設定しかご紹介していませんが、実際にどのようにフローを回したら良いのか、実際にフローを回すとどの様になるのかについては、以前に「[Herokuとチーム開発のおいしいレシピ～HerokuとGitHubを連携してCI/CDを実現する](https://codezine.jp/article/detail/10233)」を書いておりますので、こちらを参考にしていただけると幸いです。

中級編はここまでです。次回の上級編でお会いしましょう。