スポンサーリンク

Pythonの「設定値はどこに置くべきか?」実務で迷わない判断フロー(ENV/.env/TOML/Secretsまで)

仮想環境・インフラ構築
  1. はじめに
  2. 1. 論点整理:設定値を間違えると何が起きるのか
    1. ハードコードが招く3つの代表的なリスク
    2. 「Gitに残る」という取り返しのつかなさ
    3. 問題の本質は「設計ミス」ではなく「判断基準の欠如」
  3. 2. まずは分類から考える:設定値は3種類に分けられる
    1. ① アプリケーション設定
    2. ② 環境依存の設定
    3. ③ 機密情報(シークレット)
    4. 分類を間違えると、なぜ危険なのか
  4. 3. 設定ファイル形式の選定基準(INI / TOML / YAML / JSON)
    1. INI(configparser)
    2. TOML(tomllib / toml)
    3. YAML
    4. JSON
    5. 結局どれを選べばいい?
  5. 4. 実務で迷わない判断フロー【全体像】
    1. ステップ1:これはシークレットか?
    2. ステップ2:環境によって値は変わるか?
    3. ステップ3:アプリの挙動を決める設定か?
    4. 判断フローを一言でまとめると
  6. 5. 手順A:機密情報はどこに置くべきか(環境変数と .env)
    1. なぜコードや設定ファイルに書いてはいけないのか
    2. ローカル開発では .env を使う
    3. 本番環境では .env を置かない
    4. .env は「仮置き場」と考える
    5. セキュリティを“理解した上で”使うことが大切
  7. 6. 手順B:Pydantic Settingsで“設定ミスを起動時に殺す”
    1. なぜ「起動時に落ちる設計」が正解なのか
    2. Pydantic Settingsとは何か
    3. 設定クラスを定義するイメージ
    4. 「動いてから気づく」をなくす
    5. 設定オブジェクトは1回だけ生成する
  8. 7. 手順C:環境ごとに設定を切り替える設計(ファイル分離型)
    1. 基本方針:共通設定+差分上書き
    2. base に書くもの、書かないもの
    3. 環境別ファイルでは「違うところだけ」書く
    4. 環境の切り替えは環境変数で行う
    5. 規模が大きくなる前に整えておく
  9. 8. 推奨プロジェクト構成と設定ファイルの置き場所
    1. 結論:設定は src の外に置く
    2. おすすめのディレクトリ構成例
    3. pyproject.toml に書くもの・書かないもの
    4. 設定は「あとから動かしにくい」
  10. まとめ
    1. あわせて読みたい
    2. 参考文献
  11. よくある質問(Q&A)
    1. 関連投稿:

はじめに

Pythonで開発をしていると、必ず一度はぶつかるのが
「この設定値、どこに置くのが正解なんだろう?」という悩みです。

ログレベルやタイムアウトのような軽い設定から、データベース接続情報、APIキーといった機密情報まで、 すべてを同じ感覚で扱ってしまうと、あとから思わぬトラブルにつながります。

たとえば、

  • 本番環境なのに開発用の設定で動いてしまった
  • APIキーをうっかりGitにコミットしてしまった
  • 設定が散らばっていて、変更するたびにコードを探し回る

こうした問題の多くは、スキル不足というよりも
「判断の軸を持たないまま設定を書いていること」が原因です。

実務で大切なのは、
「これはコードに書くべきか?」「設定ファイルか?」「環境変数か?」
を、その場で迷わず決められること。

この記事では、Pythonプロジェクトにおける設定管理を 感覚ではなく、判断フローとして整理します。

アプリケーション設定・環境依存設定・シークレットの違いから、 .env、環境変数、TOML/YAML、Pydantic Settings、クラウドのSecrets管理まで、 現場でそのまま使える考え方を順番に解説していきます。

「今は小さなスクリプトだけど、いずれ本番運用も考えている」
「チーム開発で、設定まわりをきれいに整理したい」

そんな方が、あとから設計をやり直さなくて済むように。
一緒に“迷わない基準”を作っていきましょう 🙂




1. 論点整理:設定値を間違えると何が起きるのか

Pythonの設定管理で起きるトラブルは、
実は「難しい技術の話」ではありません

多くの場合、問題の正体はとてもシンプルで、
設定値の置き場所を深く考えないまま実装してしまうことにあります。

ハードコードが招く3つの代表的なリスク

まず、設定値をコードに直接書く(ハードコードする)ことで、 次のようなリスクが生まれます。

  • 変更コストが一気に跳ね上がる
    値を変えるたびにコード修正・テスト・デプロイが必要になり、 「設定を変えただけなのに作業が重い」状態になります。
  • 本番事故につながりやすい
    開発用のURLやデバッグ設定のまま本番にデプロイしてしまう、 という事故は決して珍しくありません。
  • セキュリティ事故の温床になる
    APIキーやパスワードをコードに書いた結果、 Gitリポジトリ経由で外部に漏れるケースも多発しています。

「Gitに残る」という取り返しのつかなさ

特に怖いのが、機密情報をGitに含めてしまうケースです。

一度コミットされた情報は、たとえ後から削除しても 履歴として残り続けます。
「消したつもり」でも、実際には完全に消えていないことがほとんどです。

その結果、

  • APIキーの再発行
  • 外部サービスの一時停止
  • 被害範囲の調査

といった本来不要な作業に時間を取られることになります。

問題の本質は「設計ミス」ではなく「判断基準の欠如」

ここで大事なのは、
「それをやった人が悪い」という話ではない、という点です。

多くの現場では、
「どの設定を、どこに置くべきか」を体系的に学ぶ機会がない まま開発が進みます。

だからこそ、

・これはコードに書いていい?
・設定ファイルに逃がすべき?
・環境変数にするべき?

といった判断を、その場の雰囲気や過去の経験だけで決めてしまいがちです。

次の章では、この迷いを解消するために、
設定値を「3つの種類」に分類する考え方から整理していきます。




2. まずは分類から考える:設定値は3種類に分けられる

「この設定、どこに置くべき?」と迷ったとき、
いきなりファイル形式やライブラリを考え始めると、だいたい混乱します。

実務で一番大事なのは、置き場所を考える前に“性質”を見極めることです。

Pythonの設定値は、ほぼ例外なく次の3種類に分類できます。

① アプリケーション設定

アプリそのものの挙動を決める設定です。
環境が変わっても、基本的には同じ値を使います。

  • ログレベル(INFO / DEBUG など)
  • タイムアウト時間
  • 機能フラグ(有効 / 無効)

これらは「秘密ではない」かつ「環境差が小さい」ため、 設定ファイルで安全に管理できます。

② 環境依存の設定

開発・検証・本番といった環境によって値が変わる設定です。

  • データベースの接続先URL
  • 外部APIのエンドポイント
  • 実行モード(development / production)

これらはコードに書くと事故の元になります。
環境変数や、環境別に分けた設定ファイルで切り替えるのが基本です。

③ 機密情報(シークレット)

最も慎重に扱うべき設定が、シークレットです。

  • APIキー
  • パスワード
  • アクセストークン

これらは「漏れたら終わり」の情報なので、 コードや設定ファイルに直接書いてはいけません。

ローカル開発では .env
本番環境では Secrets Manager などの専用機構を使う、というのが王道です。

分類を間違えると、なぜ危険なのか

設定事故の多くは、 「③を①や②として扱ってしまった」ことが原因です。

たとえば、

  • APIキーを設定ファイルに書いてGit管理する
  • 本番DBのURLをコードに直書きする

これらは一見ラクですが、
後から必ず大きなコストとして返ってきます。

セキュリティ事故の多くは、 高度な攻撃ではなく「人間の判断ミス」から始まります。

その背景や仕組みをしっかり理解したい方には、 次のような書籍も参考になります。

つくりながら学ぶ! Pythonセキュリティプログラミング
APIキーや認証情報を「なぜそう扱うべきか」を、 実際に手を動かしながら理解できる一冊です。

Amazonでチェックする | ✅ 楽天でチェックする

次の章では、この分類を踏まえたうえで、
INI / TOML / YAML / JSON をどう使い分けるかを整理していきます。




3. 設定ファイル形式の選定基準(INI / TOML / YAML / JSON)

設定値を分類できたら、次に迷うのが
「どの形式の設定ファイルを使うべきか?」という点です。

ここで大切なのは、 「流行っているから」ではなく「用途に合っているか」で選ぶこと。

Pythonでよく使われる代表的な4つの形式を、
実務目線で整理していきます。

INI(configparser)

Python標準ライブラリだけで扱える、最もシンプルな形式です。

  • 構造が単純で学習コストが低い
  • 追加ライブラリが不要
  • 階層構造は表現しにくい

小規模ツールや一時的なスクリプトであれば、十分に実用的です。

TOML(tomllib / toml)

Python 3.11 から標準ライブラリで読み込み可能になった、 現代的でバランスの取れた設定形式です。

  • 型が明示的で読みやすい
  • 人が編集しやすい
  • 中〜大規模プロジェクトでも破綻しにくい

長期運用を前提とするなら、
まずTOMLを検討するのが無難な選択です。

YAML

インデントによる階層表現ができ、
人間にとって非常に読みやすいのが特徴です。

  • 複雑な構造を自然に書ける
  • 非エンジニアも編集しやすい
  • パース時の安全設定に注意が必要

人が頻繁に触る設定では便利ですが、
安全なローダーを使うことが前提になります。

JSON

言語を問わず使える、最も汎用的な形式です。

  • 機械的なやり取りに強い
  • 仕様が単純で誤解が少ない
  • コメントが書けない

設定というよりは、
外部サービス連携やデータ交換向けと考えるとしっくりきます。

結局どれを選べばいい?

迷ったときは、次の基準で考えると判断しやすくなります。

  • 人が頻繁に編集する → TOML / YAML
  • 構造がシンプル → INI
  • 機械連携が中心 → JSON

そして何より大切なのは、
「設定ファイルにシークレットを書かない」ことです。

次の章では、ここまでの整理を踏まえて、
実務で使える判断フローの全体像をまとめていきます。




4. 実務で迷わない判断フロー【全体像】

ここまでで、
・設定値の分類(3種類)
・代表的な設定ファイル形式
を整理してきました。

ここからはいよいよ、
「この設定はどこに置くべきか?」を即決するための判断フロー をまとめます。

ポイントは、
上から順に質問していくだけというシンプルさです。

ステップ1:これはシークレットか?

まず最初に考えるべき質問は、これです。

「この値が漏れたら困るか?」

もし答えが YES なら、
その設定はシークレットです。

  • APIキー
  • パスワード
  • アクセストークン

これらはコードや設定ファイルには置かず、
環境変数 or Secrets管理サービスを使います。

ステップ2:環境によって値は変わるか?

シークレットでない場合、次に考えるのは環境差です。

「開発・検証・本番で値は変わるか?」

答えが YES なら、 それは環境依存の設定です。

  • DB接続先
  • 外部APIのURL
  • 実行モード

これらは、
環境変数や、環境別に分けた設定ファイルで管理します。

ステップ3:アプリの挙動を決める設定か?

上記のどちらにも当てはまらない場合、 多くはアプリケーション設定です。

  • ログレベル
  • タイムアウト
  • 機能フラグ

これらは設定ファイル(TOML / YAML / INI など)で管理して問題ありません。

判断フローを一言でまとめると

このフローは、次の3問に集約できます。

  1. 漏れたら困る? → シークレット
  2. 環境で変わる? → 環境依存設定
  3. それ以外 → アプリケーション設定

この順番を必ず守ることで、
「あとからやり直す設定管理」から解放されます。

次の章からは、この判断フローを使って、
具体的な実装手順に落とし込んでいきます。




5. 手順A:機密情報はどこに置くべきか(環境変数と .env)

判断フローで「シークレット」と判定された設定は、
扱い方を間違えると即事故につながる領域です。

ここでは、実務で最も安全かつ現実的な
環境変数と .env を使った管理方法を整理します。

なぜコードや設定ファイルに書いてはいけないのか

APIキーやパスワードをコードや設定ファイルに書くと、 次のような問題が起きます。

  • Git履歴に永続的に残る
  • フォーク・クローン時に無制限に複製される
  • 誰がどこで使っているか分からなくなる

一度漏れたシークレットは、
「なかったこと」にはできません

ローカル開発では .env を使う

開発環境では、利便性と安全性のバランスから .env ファイルを使うのが一般的です。

  1. .env にキーと値を書く
  2. .gitignore に必ず追加する
  3. 起動時に環境変数として読み込む

これにより、
「コードは同じ、設定だけが違う」 状態を安全に作れます。

本番環境では .env を置かない

ここは非常に重要なポイントです。

本番環境では、 .env ファイルを配置しません

代わりに、

  • AWS Secrets Manager
  • Azure Key Vault
  • Google Cloud Secret Manager
  • Kubernetes Secrets

などの専用のSecrets管理機構から、 環境変数として注入します。

.env は「仮置き場」と考える

.env は便利ですが、
永続的な保管場所ではありません。

あくまで、
ローカル開発用の仮置き場 と捉えるのが安全です。

「今は小規模だから…」と油断すると、
後から本番移行する際に一気に破綻します。

セキュリティを“理解した上で”使うことが大切

なぜここまで厳密に分ける必要があるのか。
それを理解せずにルールだけ守っても、 形骸化しがちです。

シークレット管理の背景や攻撃パターンを 体系的に知りたい場合は、 次のような書籍も参考になります。

実践力を身につける Pythonの教科書
環境変数や設定管理を含め、 実務で必要な「安全な書き方」を一通り押さえられる一冊です。

Amazonでチェックする | ✅ 楽天でチェックする

次の章では、 設定ミスを起動時に検知できる設計として、 Pydantic Settings を使った方法を解説します。




6. 手順B:Pydantic Settingsで“設定ミスを起動時に殺す”

ここまでで、
「シークレットは環境変数で管理する」
という安全な前提は整いました。

次に考えたいのが、設定ミスをどうやって早期に発見するかです。

実務で本当に怖いのは、
設定が間違っているのに、アプリが“なんとなく”動いてしまう 状態です。

なぜ「起動時に落ちる設計」が正解なのか

設定値のミスは、実行中に発覚すると被害が大きくなります。

  • 本番で一部の機能だけ壊れる
  • エラーログが出ず、原因特定に時間がかかる
  • データ不整合が静かに進行する

これを防ぐために重要なのが、
「起動時に設定をすべて検証する」という考え方です。

その役割を担うのが、 Pydantic Settingsです。

Pydantic Settingsとは何か

Pydantic Settings は、 設定値を型付きのクラスとして定義し、 起動時にまとめて検証できる仕組みです。

主なメリットは次の通りです。

  • 型が合わない設定は即エラーになる
  • 必須項目の欠落を起動時に検知できる
  • 環境変数・設定ファイルを一元的に扱える

設定クラスを定義するイメージ

実装イメージとしては、
「設定ファイルを書く感覚」でクラスを定義します。


from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    app_name: str
    debug: bool = False
    timeout: int = 30
  

この時点で、
・型が合わない
・値が存在しない
といった問題は起動時にエラーになります。

「動いてから気づく」をなくす

Pydantic Settings を使う最大の価値は、 失敗のタイミングを早められることです。

本番で気づくより、
起動直後に落ちたほうが、はるかに安全です。

これは「厳しすぎる設計」ではなく、
現場を守るための優しさだと思っています。

設定オブジェクトは1回だけ生成する

実務では、 設定クラスを何度も生成しないことも重要です。

一般的には、 lru_cache などを使って シングルトンとして扱います。

これにより、

  • 設定の読み直しによる不整合を防ぐ
  • アプリ全体で同じ設定を共有できる

次の章では、 環境ごとに設定を切り替える設計について、 ファイル分離型のパターンを解説します。




7. 手順C:環境ごとに設定を切り替える設計(ファイル分離型)

Pydantic Settings を使えば、 型安全に設定を管理できますが、
次に悩みやすいのが「環境差をどう表現するか」です。

小規模なうちは環境変数だけでも回りますが、
設定項目が増えてくると、可読性や管理性が一気に落ちてきます。

そこで有効なのが、
環境ごとに設定ファイルを分ける設計(ファイル分離型)です。

基本方針:共通設定+差分上書き

ファイル分離型の基本は、とてもシンプルです。

  • すべての環境で共通する設定をbaseにまとめる
  • 環境固有の値だけを差分として上書きする

たとえば、次のような構成になります。


config/
├─ base.py
├─ development.py
└─ production.py
  

base に書くもの、書かないもの

base には、 環境に依存しないデフォルト値だけを書きます。

  • ログレベルの初期値
  • タイムアウト
  • 機能フラグのデフォルト

逆に、次のものはbase に書きません

  • APIキー
  • DBの接続先
  • 本番専用のURL

環境別ファイルでは「違うところだけ」書く

development / production では、
base との差分だけを定義します。

これにより、

  • 設定の重複を防げる
  • 差分が一目で分かる
  • 変更時の影響範囲が小さい

環境の切り替えは環境変数で行う

どの設定ファイルを使うかは、
実行時の環境変数で切り替えます。

APP_ENV=development
APP_ENV=production

この値を見て、
読み込む設定を切り替える仕組みを作ります。

重要なのは、 コード自体は環境を意識しないことです。

「どの環境で動いているか」は設定側が責任を持ち、
アプリケーションは常に同じコードで動く。

この分離ができていると、 デプロイや環境追加が驚くほど楽になります。

規模が大きくなる前に整えておく

環境分離は、
プロジェクトが大きくなってから直すのが一番つらい部分です。

早い段階でこの形を意識しておくと、
将来の自分やチームを確実に助けてくれます。

次の章では、 設定ファイルをどこに置くべきかという、 もう一段実務寄りの話に進みます。




8. 推奨プロジェクト構成と設定ファイルの置き場所

設定の分類・判断フロー・実装手順を押さえても、
最後に必ず迷うのが「設定ファイルをどこに置くか」です。

ここでは、実務でトラブルになりにくい
定番かつ安全なプロジェクト構成を紹介します。

結論:設定は src の外に置く

まず結論から言うと、
設定ファイルは src/ の中に置かないのが基本です。

なぜなら、src/ 配下は 「配布・実行されるコード」として扱われる領域だからです。

ここに環境依存の設定や運用設定を混ぜると、

  • パッケージ化時に不要な設定が含まれる
  • テストと本番の境界が曖昧になる
  • 設定変更がコード変更に見えてしまう

といった問題が起きやすくなります。

おすすめのディレクトリ構成例

実務でよく使われる構成は、次のような形です。


project/
├─ src/
│  └─ myapp/
│     ├─ __init__.py
│     └─ main.py
├─ config/
│  ├─ base.toml
│  ├─ development.toml
│  └─ production.toml
├─ .env
├─ pyproject.toml
└─ README.md
  

この構成なら、

  • コードと設定の責務が明確に分かれる
  • 環境ごとの差分が一目で分かる
  • 本番用設定を安全に扱える

pyproject.toml に書くもの・書かないもの

最近のPythonプロジェクトでは、 pyproject.toml が中心的な存在になります。

ただし、ここに何でも書いていいわけではありません

書いてよいもの

  • ビルド設定
  • ツール設定(pytest / ruff / mypy など)
  • 開発者全員で共通なルール

書いてはいけないもの

  • 環境ごとに変わる設定
  • 本番専用の値
  • APIキーやパスワード

pyproject.toml「開発ルールの置き場」と考えると、 判断を誤りにくくなります。

設定は「あとから動かしにくい」

設定ファイルの置き場所は、
後から変えるコストが非常に高い部分です。

だからこそ、
プロジェクト初期の段階で 「安全側」に寄せた構成を選ぶことが大切です。




まとめ

Pythonの設定管理で一番大切なのは、
「正しいツールを選ぶこと」ではありません

本当に重要なのは、
設定値を見た瞬間に「どう扱うべきか」を判断できる基準を持つことです。

この記事では、その基準として 判断フローを紹介してきました。

  1. 漏れたら困るか? → シークレット
  2. 環境で変わるか? → 環境依存の設定
  3. それ以外 → アプリケーション設定

この順番さえ守れば、
設定ファイルの形式やライブラリ選定で 迷うことはほとんどなくなります。

私自身、設定管理を軽く見ていた頃は、
「動いているからOK」と先送りにして、 後から何倍ものコストを払ってきました。

逆に、 最初に少しだけ丁寧に考えたプロジェクトは、 規模が大きくなっても驚くほど壊れません。

設定管理は地味ですが、
プロジェクトの寿命を大きく左右する土台です。

ぜひ、次に設定値を書くときは、
「これはどの分類だろう?」と 一呼吸おいてから判断してみてください 🙂

あわせて読みたい


参考文献


よくある質問(Q&A)

Q
小規模なスクリプトでも設定管理は必要ですか?
A

必須ではありませんが、
「後で大きくなる可能性があるなら、最初から分けておく」 のがおすすめです。

特に APIキー や URL が出てきた時点で、 判断フローを使う価値があります。

Q
.env を本番環境で使っても問題ありませんか?
A

基本的にはおすすめしません。
本番では Secrets Manager などから 直接環境変数として注入する方が安全です。

.env はあくまで ローカル開発用の仮置き場と考えましょう。

Q
設定ファイルと環境変数、どちらを優先すべきですか?
A

優先順位は次の通りです。

  1. シークレット → 環境変数
  2. 環境差 → 環境変数 or 環境別設定ファイル
  3. アプリ設定 → 設定ファイル

迷ったら、 「漏れたら困るか?」 を最初に考えるのがコツです。

※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。

※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。

スポンサーリンク