Heroku上で動く本番アプリをPrivateSpaceへ引っ越した際のあれこれ

先日、Herokuで本運用されているRailsアプリケーションを同じくHerokuのEnterprise版、PrivateSpaceへ移行するという経験をしました。
Heroku自体の普及度や知名度を考えると、Enterprise版やPrivateSpaceに関する情報・知見はまだまだ少ないように思えるので、似たような人の参考になればと思ってエントリを残しておきます。
ちなみに本エントリの内容はいずれも2019/1時点の情報になります。

PrivateSpaceとは

こちらにある通り、Heroku Enterprise版で使える機能の一種で、よりセキュアな専用ランタイムでアプリを稼働できるというものになります。
稼働リージョンとして東京が選択できるようになる他、Spaceという概念も加わり、接続元の管理等のネットワーク設定もこちらで行うことができます。
ちなみにエンタープライズ版は年間契約の請求書払いになっていて、利用期間も契約期間としてカッチリ決まっています。カード登録すればシームレスに利用開始できる普通のやつとはもはや別ゲー感ありますね。

tl;dr

- Enterprise版でもHerokuのイージーさは健在だった
- 躓いたポイントがいくつか
- 困った時のサポートチケット

お前誰よ?

Webエンジニアです。Linc'wellという医療系のスタートアップでRailsアプリケーションの開発を担当してます。
2018/10からのジョインですが、Herokuをproduction運用するサービスは今回触るのが初めてでした。つまりHeroku初心者と言って差し支えないやつです。

実際の移行について

1. チームの移行

まず断っておくと、Heroku Enterprise版はガチの法人契約になってます。
契約が締結されて無事利用が始まると、最初にEnterprise用のHeroku Teamが新たに発行され、その案内がメールで届きます。
このチームは従来のCommonRuntimeのチームとは異なるものなので、サービスで管理するアプリケーションを一元化するには、既存のアプリケーション群はすべて新しいチームへと所属を移し替える必要が出てくるのです。
(ただし移行自体はボタン一発でTransferできますのでご安心を)

ちなみに各appsのチーム移行は作業単体でみると上記のようなオンラインドキュメントがあるものの、Enterprise版への切り替えをはじめとした細かい情報が思いの外少なかった印象です。
開発環境から段階的に施行したり、事前にサポートチケットを発行して、稼働中のサービスに影響がないかを確かめながらの作業になりました。

実際のサポートとのやり取りでも「Enterpriseへチームが変わると支払方法も変わるので、有料Add-onでエラーが出るかも」と回答をもらったりもしたのですが、そんな情報は当然 undocumented なわけで、そういった裏側の設定等はサポートの方に協力してもらいつつで進めていきました。

すでに探り探り感が尋常じゃないのですが、大抵のことはオンラインドキュメントに記載があったりして、なんやかんやで無事にチームを移すことができました。

ちなみにEnterprise版のチームメニューがこちらです。
いくつか新項目が増えてはいますが、それ以外は基本的に従来と同様なので小慣れた操作ができそうです、まずはひと安心ですね。

2. 移行先となる新本番appの構築

さて、ここから本番appをPrivateSpaceへ移し替えようと思うのですが、そのためにはEnterprise版Teamで追加された「Spaces」のタブからスペースを作成し、そこへappを構築していきます。

基本的にDynoのTier等はShieldをはじめとしたPrivateSpaceに即したものに変わりはしますが、それ以外には特別なこともなく、普段通りに作業を進めていけると思います。

アプリを現行のものと同様に構築していき、PostgresやRedisをはじめとした必要なAdd-onをアタッチしていきます。
ちなみにこの時点での新本番appの状態ですが、まだ移行前ということでDBにはステージングのコピーをrestoreしていて、URLも `xxxx.herokuapp.com` というカスタムドメインなしの素の状態にしています。

3. 移行準備

この段階でPipelineのproduction上には現本番、そして移行先となる新本番の2つのappが並列に存在することになりました。
上図の通り、あとはDBとドメインを新本番へ切り替えれば移行作業はあらかた完了する感じになっているわけです。

3. 本番移行作業

その後オンラインドキュメントを調べつつではありましたが、必要な作業をまとめていった結果、実際の本番移行は以下の手順で行いました。

1. メンテナンスモードON
2. DBの切り替え (pg:backups:capture + pg:restore)
3. ドメインの切り替え
4. デリケートな環境変数の付け替え
5. メンテナンスモードOFF

上記の各ステップですが、それぞれコマンド化+チェックリスト化して事前にまとめておいたおかげで、想定通りかなりスムーズに作業できました。
というかEnterprise版であってもおなじみのコマンド群は変わらず使えるので、appへの操作自体に特別なことは少なく、従来通り行える感じでした。

私の場合はHerokuのナレッジが少なかったのでドキュメントと格闘した部分もありましたが、操作に慣れてしまえばイージーに移行できてしまうのではないでしょうか。PaaS様々ですね。
こうなるともう --app の指定さえ間違えなければ失敗することはないんじゃないかと思います(笑) 楽チン楽チン。

つまづいたポイントについて

ただしそんな中でも躓いた or 難儀したポイントというのはやはりあって、ここではそれらを紹介していきたいと思います。
中にはEnterprise版がどうこうというよりも、私自身がHerokuにそこまで慣れてなかったことで躓いたものもありますがそこはご容赦ください(汗

DNS Targetの値が付け替えで再生成された

まずはドメインの移行に関して。

これは普通のHeroku apps同様にカスタムドメインの付け替えで完結する話なのですが、Herokuの場合は `DNS Target` というホストの向き先へ設定しているだけという認識だったため、元々Heroku appについているカスタムドメインを別のHeroku appへ付け替えるということで下記のような作業だけを想定していました。

$ heroku domains:remove [PRODUCTION_FQDN] --app [OLD_PRODUCTION_APP_NAME]
$ heroku domains:add [PRODUCTION_FQDN] --app [NEW_PRODUCTION_APP_NAME]

しかし実際にはaddする際、旧本番とは全く異なるDNS Targetの値が再生成されて別のものに変わったことで、レジスタラ側のCNAMEでターゲット変更が必要になりました。

後から気づいたことですが、上記の通りHerokuカスタムドメインの仕様が途中で変わったため、値がリセットされたようです。去年の10/15以前にドメイン設定された方は移行の際にご注意を。
ステージング上でのリハーサルで発覚したこととはいえ、オンラインドキュメント上を流し読みだけでは拾いきれなかった事象だったため記しておきます。

FQDNのtrailing dotに関する挙動

こちらは細かい話題になりますが、移行後に発覚した問題としてFQDNの末尾にドットが付加されたURLだと移行後にはエラーになる、という事態に遭遇しました。

この現象、例えばユーザーさんが `https://www.mydomain.com./`  といったドット付きのURLでブックマークしていた場合、エラーになって見れなくなってしまうので原因を調査することになりました。

ただこれに関しては自力ではどうにもならなかったためサポートに問い合わせたところ、末尾に付くドットの扱いについては以下のような違いがある、という回答が得られました。

何が問題だったかというと、下記の通りAWS Route53で設定されたCNAMEの場合はtrailing dotが任意の扱いだったのですが、それがHeroku上ではCommonRuntimeとPrivateSpaceとで扱いに差異が存在していたわけです。

こんな具合にCommonRuntimeとPrivateSpaceでは微妙に仕様が異なり、かつすべてがdocumentedではなさそうなので、迷ったら積極的にサポートチケットを発行した方がよさそうですね。思わぬ回答が得られるかもしれません。

55秒未満のH28エラー

ActionCableのクライアント側からのリクエストで、移行後に `H28 Client Connection Idle` がけっこうな頻度で発生するようになりました。

The client did not send a full request and was terminated due to 55 seconds of inactivity. For example, the client indicated a Content-Length of 50 bytes which were not sent in time.

ドキュメントにはこのように書かれていますが、上記に該当しないケースで発生したため、こちらもサポートへ問い合わせました。

すると「Private SpacesのHerokuルータではクライアント側からネットワーク接続が切断された場合にもH28を発生させている」という回答が得られ、こちらもドキュメントに記載のない挙動になっていることがわかりました。

サービスの運用上はそれほど問題にはならかったものの、こちらも聞いといてよかった事案となりました。

外部からスペース内のDBに接続できない

これは当然ではあるのですが、PrivateSpaceのDBインスタンスはセキュアな環境で稼働するため、外部からカジュアルに接続することはできません。公式でも謳われている通りですね。

私たちのケースで言うと、元々BIツールとしてmetabaseを別appで立てていたのですが、移行後はCommonRuntime -> PrivateSpaceの接続になるため、それがそっくり使えなくなりました。
不用意に穴を開けるわけにもいかないので、なにかしら対策が必要が部分になります。
(ちなみにこれは現在進行形のissueになってます汗)

まとめ

なにかと便利なHerokuですが、そのイージーさはEnterprise版でも健在で、特にややこしい部分もなく移行ができたという印象です。
法人契約だろうがCUI / GUI問わずいつもの雰囲気でアプリを構築していけるのはありがたかったです。CommonRuntimeのHerokuに慣れた人であれば、ほぼ手間をかけずにEnterpriseも使いこなせるでしょう。

もしHerokuで運用するサービスに相応のセキュリティレベルが要求されるようになった場合、Enterprise版への移行というのは有力な選択肢のひとつになるんではないかなと思います。

We are hiring! 的な

Linc'wellでは医療分野で技術力を活かしたいエンジニアを絶賛募集してます!業界をテクノロジーで変えていきたいという方、お待ちしてます!


この記事が気に入ったらサポートをしてみませんか?