コンテンツにスキップ

4. 設定

どのアプリケーションにも、データベースの認証情報、APIキー、フィーチャーフラグ、環境ごとに異なる値など、さまざまな設定が必要です。Build.ioは、こうした設定をコードから分離して管理します。そのため、同じコードベースをそのまま複数の環境へデプロイできます。

この章では、環境変数とアプリ設定による構成の管理方法と、シークレットを安全に扱うためのベストプラクティスを説明します。

アプリケーションに環境変数として渡される設定値を、Build.ioではConfig Varと呼びます。アプリケーションの設定は、主にこのConfig Varで行います。値は実行時に渡されるため、機密データをコードベースに含める必要がありません。設定を変更するだけであれば、再デプロイも必要ありません。

アプリケーションが起動すると、Build.ioはすべてのConfig Varを環境変数として環境に注入します。コード側では、他の環境変数と同じ方法で読み取れます。

Ruby:

database_url = ENV['DATABASE_URL']

Node.js:

const apiKey = process.env.API_KEY;

Python:

import os
stripe_key = os.environ.get('STRIPE_SECRET_KEY')

Config Varは、web、workerなどすべてのプロセスタイプから利用できます。デプロイや再起動を行っても、設定した値はそのまま保持されます。

ダッシュボードで設定する場合は、アプリのSettingsタブを開き、Config Varsセクションに移動します。Reveal Environmentをクリックすると既存の値が表示され、その画面で必要な追加や編集を行えます。

CLIから設定する場合は、config:setコマンドを使用します:

$ bld config:set STRIPE_KEY=sk_live_xxx123 -a my-app

複数の変数をまとめて設定することもできます:

$ bld config:set API_URL=https://api.example.com RETRY_COUNT=3 -a my-app

現在の設定を確認するには、次のコマンドを実行します:

$ bld config:list -a my-app

変数を削除するには、config:unsetコマンドを使用します:

$ bld config:unset OLD_API_KEY -a my-app

Config Varを更新すると、アプリのDynoが再起動します。新しい値は即時に反映されるため、再デプロイの必要はありません。ただし、関連する複数の変数を個別に更新すると、そのたびに再起動が発生します。1つのコマンドでまとめて設定すれば、再起動は1回で済みます。

Config Var以外にも、アプリのデプロイ方法や実行方法を制御する設定がいくつかあります。これらはダッシュボードのアプリのSettingsタブにまとめられています。

スタックは、アプリをどの方式でビルドするかを決める設定です。ほとんどのアプリでは、デフォルトのまま変更する必要はありません。デフォルトのスタックはCloud Native Buildpacksを使用し、最新のセキュリティパッチが適用された状態に保たれます。アプリにDockerfileが含まれており、そちらを使ってビルドしたい場合は、スタックにdockerfileを指定してください。

ビルドパックは、ソースコードを実行可能なアプリケーションに変換します。通常は、アプリケーションの技術スタックに合ったビルドパックを追加します。必要に応じて、複数のビルドパックを追加することもできます。たとえば、アセットのコンパイルにNode.jsも必要なRubyアプリケーションが該当します。ここで注意したいのが、追加する順序です。ビルドパックは追加した順に実行され、前のビルドパックが用意した実行ファイルは、後続のビルドパックから呼び出せます。

Dynoが動作する場所は、アプリのリージョンで決まります。パフォーマンスを重視する場合は、ユーザーやデータベースに近いリージョンを選択してください。リージョンは設定後にも変更できますが、変更にはさまざまな影響が伴います。最初の段階で最適なリージョンを選んでおくことを推奨します。

アプリの実行時の動作とセキュリティは、いくつかのポリシーで制御できます。これらのポリシーは、アプリのSettingsタブのPoliciesセクションにあります。

WebSocketの許可(Allow WebSockets) — アプリのWebSocket接続を有効または無効にします。

一時証明書のプロビジョニング(Provision Temporary Certificates) — ACM(自動証明書管理)による証明書が発行されるまでの間、自己署名証明書を生成します。アプリを新しく立ち上げるときに役立つ設定です。ドメインのDNSが解決し、正式な証明書がプロビジョニングされるまでの間も、アプリはHTTPSエンドポイントを利用できます。

レスポンスタイムアウト(Response Timeout) — 1つのリクエストの処理にかけられる時間の上限です。この時間を超えると、Build.ioがリクエストを終了します。処理に時間のかかるリクエストを扱うアプリでは、この値を大きくしてください。ただし、タイムアウトを長くすると、その間はDynoのリソースが占有され続けます。

Webアプリケーションファイアウォール(WAF) — 受信トラフィックのすべてを透過的にプロキシする、組み込みのファイアウォールを有効にします。プロキシを経由しても、スループットはほとんど低下しません。WAFはOWASP Core Rule Setに基づいて、SQLインジェクションやクロスサイトスクリプティングなど、代表的なWeb攻撃を遮断します。なお、TLSパススルーが有効な場合、WAFはトラフィックを検査できません。

TLSパススルー(TLS Passthrough) — SSL/TLSの終端を、ルーティング層のBuild.ioではなくアプリ自身で処理できるようにします。カスタム証明書の検証が必要な場合や、TLS終端を独自に行うサービスを動作させる場合に使用してください。ただし、これを有効にするとルーティング層がトラフィックを読み取れなくなるため、WAFやその他のHTTPレベルの検査は機能しなくなります。

プロセスネームスペースの共有(Share Process Namespace) — 同じDyno上のコンテナ間でプロセスネームスペースを共有します。これにより、親プロセスが残した孤立プロセスを、Build.ioの組み込みプロセスマネージャーが積極的にクリーンアップできるようになります。

Erosion Resistance — プロセスの稼働時間に上限を設け、その時間が経過したプロセスを、エラーの有無にかかわらず自動で再起動します。メモリリークのように、時間の経過とともにプロセスが応答不能になっていく問題に対するセーフガードです。

ビルドキャッシュ(Build Cache) — 以前のビルド結果をキャッシュし、次回以降のビルドを高速化します。依存ツリーが大きいプロジェクトや、コンパイルに時間のかかるプロジェクトでは特に効果があります。古いキャッシュが原因でビルドに問題が生じた場合は、一時的に無効にしてクリーンビルドを実行できます。

APIキー、データベースのパスワード、暗号化キーといったシークレットの保存先には、Config Varが適しています。Build.ioはConfig Varを保存時と転送時の両方で暗号化します。また、ビルドログやアプリのソースコードにシークレットが出力されることはありません。

コードからシークレットを排除する

Section titled “コードからシークレットを排除する”

シークレットをリポジトリにコミットしないでください。プライベートリポジトリであっても同様です。シークレットはConfig Varで管理します。誤ってコミットしてしまった場合は、ただちにローテーションしてください。Gitの履歴は永久に残るため、一度コミットしたシークレットは漏洩したものとして扱う必要があります。

ローカル開発では、.envファイルを使用し、このファイルを.gitignoreに追加しておきます。dotenv(多くの言語で利用できます)のようなツールを使うと、開発中もこれらの値が環境変数として読み込まれ、本番環境でのConfig Varと同じように動作します。

シークレットのローテーション

Section titled “シークレットのローテーション”

シークレットを定期的にローテーションしておけば、万一漏洩した場合でも被害を最小限に抑えられます。自身が管理している認証情報(自社で発行したAPIキーなど)であれば、Config Varを新しい値に更新するだけで完了します:

$ bld config:set API_KEY=new_key_value -a my-app

アプリは新しい値で再起動します。外部サービスの認証情報の場合は、複数のキーを同時に有効にできるかどうかを確認してください。対応している場合は、新しいキーを追加してデプロイし、動作を確認したうえで古いキーを失効させられます。この手順であれば、ダウンタイムは発生しません。