あなたが知らないHeroku Private Spacesの機能

Happy Holiday :)
2016年のHeroku Advent CalendarはHerokuのPrincipal Solutions Architectの相澤がお届けします。

Herokuはサインアップするだけですぐに使えるWebアプリケーションのプラットフォームとして知られていますが、Herokuの真の価値は[Heroku Enterprise](https://www.heroku.com/enterprise)という企業向けのパッケージを使って初めて感じることができます。このエントリーではHeroku Enterpriseの目玉機能である[Heroku Private Spaces](https://www.heroku.com/private-spaces)について紹介していきます。

![psanime.png](https://qiita-image-store.s3.amazonaws.com/0/4267/675abb5d-e5e6-f23a-6a42-1d9464860002.png)

## 東京Regionの利用
PrivateSpacesの大きな特徴であり、日本のユーザーにとってインパクトが大きいのが、日本のデータセンターでHerokuを運用できるということでしょう。
詳しくは後述しますが、PrivateSpacesはユーザーごとに独立した実行環境を任意のデータセンターに展開します。２０１６年現在、選択可能なデータセンターは東京（日本）、フランクフルト（欧州、ドイツ）、オレゴン（米国西海岸）、バージニア（米国東海岸）の４つです。現在、シドニーについてもベータテストが行われているため、順調に行けば遠くない将来にシドニーのデータセンターも利用可能になる見込みです。

日本のユーザーがPrivateSpacesを利用する場合は、もちろん東京リージョンを選択することになるでしょう。


## Virtual Private Cloud - 独立したネットワーク

クレジットカード払いでHerokuをお使いの方については、Heroku上で運用しているアプリケーションは米国のバージニア州にあるデータセンターもしくはヨーロッパのデータセンターいずれかにその実行環境があります。これら２つのデータセンターに配備されているHerokuの実行環境は、PrivateSpacesと区別して「Commmon Runtime」と呼ばれています。もちろんEnterprise契約のユーザもCommon Runtimeを利用することはできます。Common Runtimeはマルチテナント型で運用されている「開かれたHeroku環境」です。世界中のHerokuユーザーが運用しているアプリケーションを論理的にはひとつの実行環境で運用しているため、良く言えばアクセシビリティが高く、言い換えるとネットワークレベルのアクセス制御をユーザごとに施すには本質的に向いていません。

一方、PrivateSpacesはユーザーごとに独立したネットワークセグメントを割当て、その内側にそのユーザー専用のHeroku実行環境を用意します。技術的には[Amazon Web Services](https://aws.amazon.com/)の提供する[Virtual Private Cloud(VPC)](https://aws.amazon.com/vpc/)を構築し、その内部にアプリの実行に必要なコンテナ管理基盤をオンデマンドで展開します。これによって、各々のPrivate Spacesには独立したネットワークアドレスを割当てることができます。また、PrivateSpacesの外側からのアクセスに対してはIPアドレスによる制約をかけることができます。

## Heroku Postgres Private Plan - 隔離されたデータベースの利用

Herokuで利用できるデータベースはサードパーティー提供のものも含めると数多くありますが、Heroku自身が運用しているクラウド型のデータベースサービスとして最もよく使われているのが[Heroku Postgres](https://devcenter.heroku.com/articles/heroku-postgresql)です。Common Runtimeで利用できるHeroku Postgresのインスタンスは、インターネットに公開されています。そのため、Heroku Postgresに対するアクセスは、データベースのホスト名、データベース名、ユーザ名、パスワードなどが正しければ、インターネット上のどこからでもアクセス可能です。もちろんデータベース名、ユーザ名、パスワードは第三者が容易に推測することはとても難しい文字列を採用していますが、アクセス（の試行）が可能である以上、悪意を持ってデータベースインスタンスに負荷をかける事自体は可能です。また、何らかの理由によりあるデータベースに対する正しい接続情報が漏洩した場合、悪意のある第三者にデータベースの内容を取得されてしまう恐れがあります。

一方、PrivateSpacesを利用した場合、データベースインスタンスそのものをPrivateSpacesの内部に配備することが可能になります。PrivateSpaces内部に配備されたデータベースインスタンスには、PrivateSpacesの外部から直接アクセスすることはできません。PrivateSpaces内部のデータベースにアクセスできるのは以下のいずれかの場合に限られます

1. 同一のPrivateSpaces内で稼働しているコンテナ（Dyno）からのアクセス
2. [Heroku Connect](https://www.heroku.com/connect)を経由したSalesforce組織からのアクセス
3. Heroku CLIで認証済みの`psql`コマンド（`heroku pg:psql`コマンドによるアクセス）

## Private Dyno - サーバー専有型コンテナ(Dyno)の利用

Common Runtimeではアプリ実行環境としてサーバー共有型コンテナかサーバー専有型コンテナのいずれかを選択することができます。サーバー共有型コンテナは軽量で、Heroku観点で見ると実行環境の集約密度を高めるという意味でプラットフォーム提供事業者としては有利です。しかしながら、ユーザー観点で見ると自分の実行環境が配備されているサーバーに他のユーザーの実行環境も相乗りしている状態になります。Herokuのコンテナ（Dyno）は、他のコンテナからの干渉をなるべく受けないように工夫はされていますが、実際のところ、同じサーバーで実行されているコンテナとサーバーの計算資源を共有しているため、全く干渉されないということはありません。Common Runtimeで他のユーザーからの干渉を全く受けない独立したサーバーを利用するためには、Performance Dynoという種類のコンテナを選択する必要があります。

一方、PrivateSpacesを利用した場合、PrivateSpaces内部で実行されるコンテナは全てサーバー専有型となります。

## Private Spaces Dyno DNS Registry - PrivateSpaces内の名前解決

Common Runtime上で実行しているアプリは、それぞれインターネットからのアクセスを受付けることができます。`Procfile`で `web`というタグが付けられたプロセスでアプリケーション・サーバーを起動すると、環境変数`$PORT`で指定されたポートをアプリケーション・サーバーがListenするようになります。`$PORT`で指定されるポートは、内部的にはHerokuのルーターがHerokuの実行環境上でどのポートにリクエストをディスパッチするポートの番号を表しています。そして外部からは80番または443番へのアクセスしか受付けません。すなわち、Heroku上で運用されているひとつのアプリはHTTP（またはTLS）によるリクエストを通じてのみプロセス間の通信を行うことになります。

この制約は最近流行の [Micro Services Architecture](http://www.martinfowler.com/articles/microservices.html) を構成しようとする場合に少し不便です。なぜならば、複数のアプリがREST APIを使って協調してひとつのサービスを構成する場合、アプリ間の連携は常にインターネットを経由してやり取りされることになるからです。もともと外部からの利用も想定して設計されたAPIはそれでも良いですが、例えば内部データをアプリに対して提供するための内部的なAPIはインターネットに公開する必要はありませんし、そうなってしまうのであれば外部/内部問わずあらゆるAPIに対するアクセス対して、正当なアクセス元であるかを確認するための認証/認可のプロセスを組み込まなければなりません。

PrivateSpacesでは、[Dyno DNS Registry](https://devcenter.heroku.com/articles/dyno-dns-registry)という内部DNSを利用することが可能です。Dyno DNS RegistryはPrivateSpaces内部のプロセス間でお互いの内部IPアドレスを交換する仕組みです。この機能を有効化すると、外部に公開しなくてよいプロセスについても任意のポート番号を指定してListenすることができます。もちろんポートをListenしているプロセスもHTTPサーバーである必要もありません。例えば[Gopher](https://tools.ietf.org/html/rfc1436)のようなプロトコルをListenするプロセスをコンテナ上で実行し、PrivateSpaces内の別のプロセスから7070番のポートに対してGopherリクエストを送信することもできるのです。

# Heroku Private Spacesを利用するには

Heroku Private Spacesを利用するには、セールスフォース・ドットコムの営業担当を通じて、Heroku Enterprise契約を締結する必要があります。Heroku Enterprise契約は個人では契約できないので利用したいという方は自社のエラい人に頑張って交渉してください :P

## OrganizationのダッシュボードからSpacesを選択する

めでたくHeroku Enterprise契約が締結されると、Heroku Organizationという機能が利用可能になります。Heroku Organizationは、Heroku Enterprise契約を締結した法人ひとつひとつに割当てられるHerokuの法人用実行環境です。開発者ユーザー視点では会社の資産として管理するアプリをグルーピングするフォルダだと考えてもらえばいいかもしれません。（Organization機能に関する詳細は[こちら](https://devcenter.heroku.com/categories/organization-accounts)）

Organizationが利用可能になると、HerokuのダッシュボードのPersonalAppsと書いてある部分をクリックすることで、Organizationの管理を行うことができるようになります。あらかじめ割当てられたOrganizationの名前を選択することで、Organizationの管理画面に移行します。Organizationの管理画面にはSpacesというタブがあるのでこれをクリックします。
![スクリーンショット 2016-12-26 13.22.09.png](https://qiita-image-store.s3.amazonaws.com/0/4267/a1dc8064-c26e-6ef2-ffc8-73ada2a7655b.png)

## 新しいSpaceを作成する

つぎに、作成するPrivate Spaceの名前と展開する地域を選択して「Create Private Space」をクリックします。

![qiita-space.png](https://qiita-image-store.s3.amazonaws.com/0/4267/62feccd4-272d-4812-1005-8d7382ba7e14.png)

PrivateSpaceの構築が始まります。画面に書いてあるように構築完了までは数分かかるので、キッチンに行ってコーヒーを淹れてきましょう。

![qiita-space2.png](https://qiita-image-store.s3.amazonaws.com/0/4267/2c399672-915e-1e39-e2e3-5823da6b4558.png)

PrivateSpacesの内部につくったアプリにはアプリのリストの右側にSpaceの名前が表示されます。

![qiita-space3.png](https://qiita-image-store.s3.amazonaws.com/0/4267/5e6d7ac8-c196-6ef4-d7ea-8f1e92322b7c.png)


これで心置きなくPrivateSpacesを利用できるようになりました！

Enjoy :)