💡

【Google Cloud】Secret Managerの1シークレットに複数の環境変数を登録する

に公開

はじめに

※ 本記事の内容は2025年9月2日時点でのものです。

Google CloudのSecret Managerを使うと、
アプリケーション内で使用する環境変数を安全に管理できます。

しかしながら、一般的な使い方では「1シークレット = 1環境変数」として登録するため、
環境変数が増えると管理が煩雑になりがちです。

そこで今回は、複数の環境変数をSecret Managerの1シークレットにまとめて登録し、
Django(Pythonフレームワーク)で作ったアプリに対して
Cloud Run経由で読み込ませるところまでを対応したので、その手順をまとめました。

※※※
他言語フレームワーク(PHP Laravel等)でも実現は可能ですが、
ソースコードへの実装手順がやや異なる場合があります。
※※※


どんな場面で使えるか

  • 個人開発・小〜中規模のアプリ

  • プロトタイピングやPoC

  • 既存の.env運用をそのままGCPに移行したい場合

※※※
大規模プロジェクトやセキュリティ要件が厳しい環境では、
後述のように「1環境変数=1シークレット」の方式を選んだ方が安心です。
※※※


メリットとデメリット

メリット

  • 管理がシンプル
    複数の環境変数を1ファイル(1シークレット)としてSecret Managerにまとめられる。

  • 既存のツールがそのまま使える
    Pythonならpython-dotenvなどのライブラリでそのまま読み込める。

  • Cloud Runと相性が良い
    シークレットをファイルとしてマウントできるので.env形式との相性がいい。

デメリット

  • ローテーション単位が大きい
    1つの変数だけを差し替えたい場合でも、ファイル全体を更新する必要がある。

  • 差分管理がしにくい
    Gitのように「どの変数が変わったか」を追いづらい。

  • プロジェクト規模によっては不向き
    大規模システムやセキュリティポリシーが厳格な環境では「1変数=1シークレット」の方が推奨されるケースも多い。


前提条件(筆者の環境)

この記事の内容は以下の環境を前提としています。

  • インフラ: Google Cloud
  • 実行環境: Cloud Run
  • ソースコード管理: Docker イメージをビルドしてCloud Runにデプロイ済み
  • アプリケーションフレームワーク: Django (Python)

すでにCloud Runでアプリが動いていて、
「環境変数の管理をSecret Managerで改善したい」という状況を想定しています。


実装手順

1. Secret Managerに.envファイルを登録する

GCPコンソールから 「シークレットを作成」 をクリック。

任意のシークレット名を入力し、
シークレットの値に.envファイルの中身(複数の環境変数の値)をそのまま入力する。

作成ボタンをクリックし、登録が完了となります。

2. Cloud Runサービスにシークレットをマウントする

Cloud Runの対象サービスに入る

「新しいリビジョンの編集とデプロイ」をクリックする

「コンテナ」タブ →「変数とシークレット」タブ →「シークレットを参照」ボタンをクリックし、
先ほど登録したシークレットをプルダウンから指定する。

(名前は任意のものでOKです)

「ボリューム」タブ →「ボリュームを追加」から「新しいボリューム」を作成し、
ファイルのパスを追加します。

完了ボタンをクリックするとこうなります。

まだマウントはされていない状態なので、「コンテナ」タブ →「ボリュームのマウント」から
「ボリュームをマウント」をクリックし、入力欄にマウントパスを設定します。

「/<マウントパス>/<前述のファイルパス>」となります。
(例:/secrets/.env.test)

ここまで設定出来たらデプロイを実行しましょう。
これでCloud Runのコンテナ内に.envファイルが配置されます。

3. アプリケーション側(Django)で.envファイルを読み込む

# settings.py
import os
from dotenv import load_dotenv

if os.path.exists("/secrets/.env.test"):
    load_dotenv("/secrets/.env.test")

DATABASES = {
    "default": {
        "NAME": os.getenv("TEST_DB"),
        "USER": os.getenv("TEST_USER"),
        "PASSWORD": os.getenv("TEST_PASSWORD"),
        "HOST": os.getenv("TEST_HOST"),
        "PORT": os.getenv("TEST_PORT"),
    }
}

これで通常の.envファイルと同様に環境変数が読み込めます。
Djangoでは python-dotenvload_dotenv("/secrets/.env.test") を呼ぶだけでOKです。

Djangoは標準で.envを読む仕組みを持たないので、
上記のように自分で読み込むスタイルとなります。

これが例えばPHPフレームワークのLaravelだと、
標準で.env読み込みがあるため、どの.envを読ませるかを制御する必要があります。
Docker entrypointでコピーをするか、アプリブート時にパスを指定するのが定番かと思います。


まとめ

  • 管理がシンプルになる一方で、ローテーションや差分更新には弱い。

  • 小規模・短期開発や既存.env移行にはおすすめ、大規模・厳格環境では従来の「1シークレット=1環境変数」方式を。

  • 用途に応じて今回の「1シークレット=複数の環境変数」と従来方式を使い分けるのがベストかと思いました。

Discussion