Upgrade to Pro — share decks privately, control downloads, hide ads and more …

アプリケーションコンフィグの設定パターン 銀座Rails #27

Masato Mori
November 27, 2020

アプリケーションコンフィグの設定パターン 銀座Rails #27

2020/11/27に銀座Rails#27で発表したスライドです。
https://ginza-rails.connpass.com/event/193008/

Masato Mori

November 27, 2020
Tweet

More Decks by Masato Mori

Other Decks in Programming

Transcript

  1. About Me
 • 森 雅智: @morimorihoge
 • BPS株式会社でRailsの受託開発チームをやってたり、週1大学非常勤で Web開発を教えてたりします
 •

    Ruby/Rails歴は11年くらい。Web開発は17年くらい
 • 銀座Ralis #10でActiveRecordでVIEWを使おうという話をしました
 • 最近の銀座Railsでは出張Railsウォッチという枠を頂いて発表しています
 About BPS & TechRacho
 • Web受託開発や電子書籍製品開発をやっている会社です
 • TechRachoという自社技術Blogを運営しています
 ◦ 3年半ほど前から平日毎日更新してます
 ◦ https://techracho.bpsinc.jp/ • お仕事相談、転職相談、TechRachoへのご意見など気軽にどうぞ
 ◦ https://www.bpsinc.jp/ 2

  2. 12-Factor Appにおける「設定」の定義
 • アプリケーションの 設定 は、デプロイ(ステージング、本番、開発環境など)の間で 異なり得る唯一のものである
 • 認証情報を漏洩させることなく、コードベースを今すぐにでもオープンソースにする ことができるなら、アプリケーションの設定が正しく外部に分離できている


    12-Factor Appでは設定を環境変数に格納することを勧めている(利点は後述)
 一方で、アプリケーション内部の設定については12-Factor Appは定義の対象外として いる
 -> 今回の発表ではこちらも対象としていく
 6

  3. 色々な設定注入方法一覧
 9
 • ソースコード内定数
 • コマンドライン実行時引数
 • 環境変数
 • 定数型設定ファイル(YAML、JSONなど)


    • ソースコード形式設定ファイル(config/initializersなど)
 • DBやKVSの設定情報用テーブル
 • その他の方式

  4. ざっくり整理してみる
 18
 読み込みタイミング 設定値の編集方法 再読込方法 リクエスト処理時 オーバーヘッド ソース内定数 プロセス起動時 ソース修正

    プロセス再起動 低 コマンドライン引数 プロセス起動時 実行コマンド変更 プロセス再起動 低 環境変数 プロセス起動時 環境設定更新 プロセス再起動 低 YAML/JSON プロセス起動時 ファイル修正 プロセス再起動 低 ソースコード設定ファ イル プロセス起動時 ソース修正 プロセス再起動 低 DB/KVSテーブル 値参照時 DB値更新 DB値参照 小 次ページから切り口ごとに見ていきます 

  5. 読み込みタイミングによる違い
 多くの手法はプロセス実行時読み込みとなるが、それはすなわち設定値の変更に deployが必要になるということ(まさに12-Factor Appの「設定」の定義)
 19
 読み込みタイミング 設定値の編集方法 再読込方法 リクエスト処理時オー バーヘッド

    ソース内定数 プロセス起動時 ソース修正 プロセス再起動 低 コマンドライン引数 プロセス起動時 実行コマンド変更 プロセス再起動 低 環境変数 プロセス起動時 環境設定更新 プロセス再起動 低 YAML/JSON プロセス起動時 ファイル修正 プロセス再起動 低 ソースコード設定ファイ ル プロセス起動時 ソース修正 プロセス再起動 低 DB/KVSテーブル 値参照時 DB値更新 DB値参照 小 多くの手法はプロセス実行時読み込みとなるが、それはすなわち設定値の変更に deployが必要になるということ(まさに12-Factor Appの「設定」の定義)
 -> deployせずに設定変更したければ、DB/KVSを使うのが良さそう 

  6. 設定変更方法による違い
 設定変更にソース修正が必要な方法を使う場合、運用上のニーズである設定変更が機 能開発のソース変更と混じる
 -> branchのmerge運用がカオスになりやすい要因の一つ
 20
 読み込みタイミング 設定値の編集方法 再読込方法 リクエスト処理時オー

    バーヘッド ソース内定数 プロセス起動時 ソース修正 プロセス再起動 低 コマンドライン引数 プロセス起動時 実行コマンド変更 プロセス再起動 低 環境変数 プロセス起動時 環境設定更新 プロセス再起動 低 YAML/JSON プロセス起動時 ファイル修正 プロセス再起動 低 ソースコード設定ファイ ル プロセス起動時 ソース修正 プロセス再起動 低 DB/KVSテーブル 値参照時 DB値更新 DB値参照 小 ※YAML/JSON方式は当該configをcommitするかにも依る
 -> deployせずに設定変更したければ、DB/KVSを使うのが良さそう 

  7. API KEYなどの秘密情報管理の観点
 21
 参照・更新権限 ソース内定数 リポジトリへのアクセス権限次第 コマンドライン引数 設定されている場所や実行方法によるが、 リポジトリのCI設定ファイルなどに書かれている場合はそのファイルの書き方依存となる ※Secure

    Variable的な機能があればよりセキュアに設定できる 環境変数 設定されている場所や実行方法によるが、 リポジトリのCI設定ファイルなどに書かれている場合はそのファイルの書き方依存となる ※Secure Variable的な機能があればよりセキュアに設定できる YAML/JSON リポジトリに置く場合はcredentials機能などを使わないととても危険 リポジトリ管理外に置くのであれば、当該設定ファイルのアクセス権限依存 ※AWS S3などであればpolicy設定などで細かく設定できる ソースコード設定ファイル 基本的にここに生で書くことはなさそう? もしやる場合はYAML/JSONの場合と同様 DB/KVSテーブル DB/KVSへのアクセス権限次第 どのケースでも、shellが取れてrails consoleが使えると見られない情報はないので、踏み台サー バーなどでshell環境を用意する場合は権限に要注意

  8. configからconfigを作るという選択肢
 ファイル形式の設定しか受け入れてくれないが、設定を環境変数で渡したいというケー ス(DockerでApacheやMySQLのコンテナを使おうとするとありがち)
 Dockerだとentrypoint.shの中でenvsubst(gettextパッケージ内)などのテンプレートエン ジンを使ってテンプレート化されたconfigに環境変数を実行時展開して読み込ませるとい う手が使える
 # buildに含めるのでも良いが、その場合設定変更時に毎回buildが必要
 -> 参考:

    envsubstを使ってDockerで設定ファイルに環境変数を埋め込めこむ汎用的な パターン
  https://qiita.com/minamijoyo/items/63ae57b99d4a4c5d7987
 23
 # entrypoint.sh . /container.env EXTRACT_VARS=’$VAR_A $VAR_B...’ envsubst “$EXTRACT_VARS” < httpd.conf.tpl > /etc/apache2/conf/httpd.conf apache2-foreground やや冗長だが、こういうやり方もあるということで・・・