Heroku Private Spaceでは、AWSのVirtual Private Cloudとピアリング接続をして、相互に内部的に接続し安全な通信を行うことができます。この機能をPrivate Space Peeringと言います。
Private Space Peeringしてみよう
そんなPrivate Space Peeringの設定方法についてまとめたものです。リンク先に事細かに手順は書いてありますが
- 英語キツイ
- Herokuしか使ってないからawsコマンド入れてなかった
- awsコマンドでどうしてもうまくいかない
のような人たちに向けて、日本語のaws consoleでの設定手順をまとめました。
前提条件
- heroku enterprise契約で、Private Spaceを購入していること
- AWSアカウントがあること
- heroku CLIが利用できること
- Heroku側でSPACEがすでに作成されていること
- AWS側でVPCがすでに作成されていること
1つ目の前提条件のハードルが一般的な利用では難しいのですが、それさえクリアしておけばカンタンに構成できます。
設定手順
次の4つの手順で設定します。
- Heroku側でVPCの構成を確認する
- AWS側でピアリングする
- Heroku側で受け入れる
- AWS側でルーティングテーブルを作成する
1. Heroku側でVPCの構成を確認する
まず、AWS側からピアリング設定を行うために、Heroku側の設定を確認します。GUIでもCUIでもカンタンです。
GUIのダッシュボードから確認する場合は、作成されているPrivate SpaceのNetwork
タブを見るだけです。

CUIの場合は、heroku spaces:peering:info <スペース名>
を実行するだけです。次のような結果が帰ってきます。
AWS Account ID:
AWS Region: ap-northeast-1
AWS VPC ID: vpc-b39527d4
AWS VPC CIDR: 10.0.0.0/16
Space CIDRs: 10.0.144.0/20, 10.0.128.0/20, 10.0.0.0/20, 10.0.16.0/20
Unavailable CIDRs: 10.1.0.0/16
※ ここでもAWS Account ID
を消してます
注意事項
ここで、AWS VPC CIDR
とUnavailable CIDRs
のいずれかと、接続するAWS VPCのCIDRがかぶっていないことを確認しておきます。Private SpaceもVPCも作成後にCIDRの変更はできませんので、いずれも作成時にIPアドレスレンジがバッティングしないように構成しましょう。
なお、Heroku Private SpaceのCIDRを変更する際はChoosing Private Network CIDR Rangeをごらんくださいませ
2. AWS側でピアリングする
awsマネージメントコンソールを開いて、おもむろにVPCの項目へ移動しましょう。ここでは何も考えずに「ピアリング接続」を選択し、「ピア接続の作成」ボタンをクリックします。まちがえて「ぴあ」って変換されるとアレですね。

ピア接続の作成
画面では、次のように設定します。

-
ピア接続ネームタグ
どうぞ好きにしてください -
ピア接続するローカルVPCを選択
今回接続したいAWS側のVPCを選択します。プルダウンで出てくるはずです。 -
ピア接続するもう一つのVPCを選択
-
アカウント
まずまちがいなく別のアカウントになりますから、「別のアカウント」を選択します。アカウントID
が手入力できますので、先程確認をしたAWS Account ID
をここに入れます。 -
リージョン
Heroku Private Spaceのリージョンを選択します。先程確認した中のAWS Region
にも記載があります。リージョンが異なる場合は別のリージョン
にして、リージョンを選択します -
VPC(アクセプタ)*
先程書くにしたAWS VPC ID
をここに入れます。
-
すべてを入れたら「ピア接続の作成」ボタンをクリックしましょう。設定上ミスがなければ、次の「成功」画面が出てくるでしょう。「OK」しといてください。

3. Heroku側で受け入れる
設定がうまく行っていれば、awsマネジメントコンソール上では、次のように「承認の保留中」となっているでしょう。Heroku側のacceptance
を待っている状況です。

heroku CLIで受け入れを行う前に、正しくHeroku側に承認要求が来ているかどうかを調べます。heroku spaces:peerings <スペース名>
を実行しましょう。
=== enablement-jp Peerings
PCX ID Type CIDR Blocks Status VPC ID AWS Region AWS Account ID Expires
───────────────────── ────────────── ───────────── ────────────────── ───────────────────── ────────── ────────────── ────────────────────
pcx-01f31cfb89521de9c unknown 172.16.0.0/16 pending-acceptance vpc-0cb1a66017eed9372 us-east-1 2019-02-11T05:46:14Z
****** heroku-managed 10.1.0.0/16 active ****** ****** ******
このように、「Status」がpending-acceptance
となっているものがあれば、正しく承認要求が来ています。ここでの「PCX ID」を元に受け入れを行います。heroku spaces:peerings:accept pcx-01f31cfb89521de9c --space <スペース名>
を実行します。スペース名
の前に--space
が必要なことに気をつけましょう。
うまく行けば次の結果が帰ってきます。
Accepting and configuring peering connection pcx-01f31cfb89521de9c
設定されたかどうか、もう一度heroku spaces:peerings <スペース名>
を実行して確認してみましょう。
=== enablement-jp Peerings
PCX ID Type CIDR Blocks Status VPC ID AWS Region AWS Account ID Expires
───────────────────── ──────────────── ───────────── ─────── ───────────────────── ────────── ────────────── ───────
pcx-01f31cfb89521de9c customer-managed 172.16.0.0/16 active vpc-0cb1a66017eed9372 us-east-1 435886841536
****** heroku-managed 10.1.0.0/16 active ****** ****** ******
設定されてそうですね。これは、GUIのダッシュボーでも確認できます、先程設定を確認したダッシュボードをリロードしてみましょう。

ね。
4. AWS側でルーティングテーブルを作成する
heroku側では受け入れたVPCのCIDRにあわせて静的経路が作成されますが、AWS側では準備しておいて上げる必要があります。

VPCダッシュボードの「ルートテーブル」をクリックして、対象となるAWS VPCのルートテーブルを選択します。したらば、下の方にある「Routes」タブをクリックします。

「Edit routes」ボタンがありますから、それをクリックして静的経路を使いしましょう。
新たに経路を追加しますので、「Add route」で新しく行を追加します。

新しい行で、次の2つを設定しましょう。
-
Destination
最初に内容を確認したAWS VPC CIDR
を設定します。 -
Target
「Peering Connection」を指定すると、対象のIDのものが出てきますから、それを指定します。
あとは「Save routes」ボタンをクリックするだけです。
設定完了
Heroku→AWS VPCへ接続する場合には、Security Groupの「Inbound Rules」にソースIPアドレスレンジとターゲットへのポート番号を開けて上げる必要があります。
AWS VPC→Herokuへは、Internal Routing設定されたWeb Dynoへしかアクセスができません。くわしくはheroku 上級編 - Private Space でできること -にも記述していますので、こちらもご参考になさってください。
試しに、VPC内のEC2からInternal RoutingされたHeroku Web Dynoへアクセスしてみると、こんな感じで疎通できていることが確認できます。
[ec2-user@ip-172-16-0-8 ~]$ hostname
ip-172-16-0-8.ec2.internal
[ec2-user@ip-172-16-0-8 ~]$ curl -s -D - -o /dev/null test-vpn-compute.herokuapp.com
HTTP/1.1 200 OK
Cache-Control: no-cache, private
Content-Type: text/html; charset=UTF-8
Date: Mon, 04 Feb 2019 06:25:31 GMT
Server: Apache
Via: 1.1 spaces-router (3e6fc26c45df)
Transfer-Encoding: chunked
[ec2-user@ip-172-16-0-8 ~]$ dig test-vpn-compute.herokuapp.com
; <<>> DiG 9.9.4-RedHat-9.9.4-61.amzn2.1.1 <<>> test-vpn-compute.herokuapp.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14933
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;test-vpn-compute.herokuapp.com. IN A
;; ANSWER SECTION:
test-vpn-compute.herokuapp.com. 60 IN A 10.0.25.212
test-vpn-compute.herokuapp.com. 60 IN A 10.0.15.133
;; Query time: 30 msec
;; SERVER: 172.16.0.2#53(172.16.0.2)
;; WHEN: Mon Feb 04 06:27:25 UTC 2019
;; MSG SIZE rcvd: 91