シークレットを構成する

サービスで、API キー、パスワード、証明書などの機密情報を必要とする依存関係が必要になることがあります。Cloud Run の場合、このタイプの機密情報を Secret Manager で作成したシークレットに保存することをおすすめします。

コンテナでシークレットを使用するには、次の 2 つの方法があります。

  • 各シークレットをボリュームとしてマウントし、そのシークレットをファイルとしてコンテナで利用できるようにします。ボリュームを読み取ると常に Secret Manager からシークレット値が取得されます。これは、最新のバージョンで使用できます。この方法はシークレット ローテーションでも有効です。
  • 環境変数を使用してシークレットを渡します。環境変数はインスタンスの起動時に解決されるため、この方法を使用する場合は、最新ではなく、特定のバージョンにシークレットを固定することをおすすめします。

詳細については、Secret Manager のベスト プラクティスのドキュメントをご覧ください。

デプロイ時とランタイムにシークレットを確認する方法

サービスのデプロイ時に、環境変数として使用されるシークレットまたはボリュームとしてマウントされたシークレットがすべてチェックされ、コンテナの実行に使用されるサービス アカウントがそれらにアクセスできることを確認します。いずれかのチェックに失敗した場合、サービスのデプロイは失敗します。

ラインタイムにインスタンスが起動したときに、次の処理が実行されます。

  • シークレットが環境変数の場合、インスタンスの開始前にシークレットの値が取得されます。シークレットの取得に失敗した場合、インスタンスは開始しません。
  • シークレットがボリュームとしてマウントされている場合、インスタンスの起動時にチェックは行われません。ただし、ランタイムにシークレットにアクセスできない場合、マウントされたボリュームの読み取りに失敗します。

ボリュームの所有権は実行環境とデプロイタイプによって異なる

シークレット ボリュームをマウントする場合、ファイルとディレクトリを所有する ID は、ワークロードの実行環境や、デプロイメントが 1 つまたは複数のコンテナで構成されているかどうかによって異なります。

単一のコンテナをデプロイする第 1 世代の実行環境の場合、コンテナに使用されている ID がシークレット ボリュームを所有します。それ以外の場合はすべて、root がボリュームを所有します。以下が該当します。

  • 複数のコンテナをデプロイする第 1 世代の実行環境
  • 第 2 世代の環境

始める前に

  1. Enable the Secret Manager API.

    Enable the API

  2. 既存のシークレットを使用するか、シークレットの作成の説明に沿って Secret Manager でシークレットを作成します。

必要なロール

シークレットを構成するために必要な権限を取得するには、次の IAM ロールを付与するよう管理者に依頼してください。

Cloud Run がシークレットにアクセスできるようにするには、サービス ID に次のロールが必要です。

サービス ID プリンシパルを Secret Manager のシークレット アクセサー ロールに追加する方法については、シークレットへのアクセスを管理するをご覧ください。

Cloud Run に関連付けられている IAM ロールと権限のリストについては、Cloud Run IAM ロールCloud Run IAM 権限をご覧ください。Cloud Run サービスが Google Cloud APIs(Cloud クライアント ライブラリなど)と連携している場合は、サービス ID の構成ガイドをご覧ください。ロールの付与の詳細については、デプロイ権限アクセスの管理をご覧ください。

Cloud Run がシークレットにアクセスできるようにする

構成を変更すると、新しいリビジョンが作成されます。明示的に更新しない限り、以降のリビジョンでも、この構成が自動的に設定されます。

新しいサービスをデプロイするか、既存のサービスを更新してリビジョンをデプロイする際に、Google Cloud コンソール、Google Cloud CLI、または YAML ファイルを使用して、サービスでシークレットを利用できるようにします。目的のタブをクリックします。

コンソール

  1. Google Cloud コンソールで、[Cloud Run] に移動します。

    Cloud Run に移動

  2. [コンテナをデプロイ] をクリックし、[サービス] を選択して、新しいサービスを構成します。最初のサービス設定ページに入力してから、[コンテナ、ボリューム、ネットワーキング、セキュリティ] をクリックしてサービス構成ページを開きます。

  3. 既存のサービスを構成する場合は、サービスをクリックし、[新しいリビジョンの編集とデプロイ] をクリックします。

  4. 手順に沿って、シークレットをボリュームとしてマウントするか、シークレットを環境変数として公開します。

    • シークレットをボリュームとしてマウントするには:

      1. [ボリューム] タブをクリックし、[ボリュームを追加] を選択します。
      2. [ボリュームのタイプ] リストから、[シークレット] を選択します。
      3. [ボリューム名] フィールドに名前を入力するか、デフォルト名を使用します。
      4. [シークレット] リストから、使用するシークレットを選択します。
      5. [パス 1] フィールドに、マウントするファイルの名前を入力します。
      6. [バージョン 1] リストで、参照するシークレットのバージョンを選択します。デフォルトでは最新バージョンが選択されます。必要に応じて特定のバージョンを選択できます。
      7. [完了] をクリックします。
      8. [コンテナ] タブに移動して、シークレットをコンテナにマウントします。
      9. [ボリュームのマウント] タブで、[ボリュームをマウント] をクリックします。
      10. [名前 1] リストからボリューム名を選択します。
      11. [マウントパス 1] フィールドに、このシークレットのマウントパスを入力します。これは、シークレットのすべてのバージョンが配置されるディレクトリです。
      12. [完了] をクリックします。
      13. [作成] または [デプロイ] をクリックします。
    • シークレットを環境変数として公開するには:

      1. [コンテナ] タブをクリックします。
      2. [変数とシークレット] タブで、[シークレットを参照] をクリックします。
      3. [名前 1] フィールドに、環境変数の名前を入力します。
      4. [シークレット] リストから、使用するシークレットを選択します。
      5. [バージョン 1] リストから、参照するシークレットのバージョンを選択します。
      6. [完了] をクリックします。
      7. [作成] または [デプロイ] をクリックします。

gcloud

サービスでシークレットを利用できるようにするには、次のいずれかのコマンドを入力します。

  • サービスをデプロイするときにシークレットをボリュームとしてマウントするには:

    gcloud run deploy SERVICE --image IMAGE_URL  \
    --update-secrets=PATH=SECRET_NAME:VERSION

    次のように置き換えます。

    • SERVICE: 実際のサービスの名前。
    • IMAGE_URL: コンテナ イメージへの参照(us-docker.pkg.dev/cloudrun/container/hello:latest など)。Artifact Registry を使用する場合は、リポジトリ REPO_NAME がすでに作成されている必要があります。URL の形式は LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG です。
    • PATH は、ボリュームのマウントパスとシークレットのファイル名で置き換えます。先頭にスラッシュを付ける必要があります(例: /etc/secrets/dbconfig/password)。ここで、/etc/secrets/dbconfig/ はボリュームのマウントパス、password はシークレットのファイル名です。
    • SECRET_NAME は、同じプロジェクト内のシークレット名に置き換えます(例: mysecret)。
    • VERSION は、シークレットのバージョンに置き換えます。最新バージョンには latest または数字(2 など)を使用します。
  • サービスをデプロイするときに、シークレットを環境変数として公開するには:

    gcloud run deploy SERVICE \
    --image IMAGE_URL \
    --update-secrets=ENV_VAR_NAME=SECRET_NAME:VERSION

    次のように置き換えます。

    • SERVICE: 実際のサービスの名前。
    • IMAGE_URL: コンテナ イメージへの参照(us-docker.pkg.dev/cloudrun/container/hello:latest など)。Artifact Registry を使用する場合は、リポジトリ REPO_NAME がすでに作成されている必要があります。URL の形式は LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG です。
    • ENV_VAR_NAME は、シークレットで使用する環境変数の名前に置き換えます。
    • SECRET_NAME は、同じプロジェクト内のシークレット名に置き換えます(例: mysecret)。
    • VERSION は、シークレットのバージョンに置き換えます。最新バージョンには latest または数字(2 など)を使用します。
  • 複数のシークレットを同時に更新できます。これを行うには、各シークレットの構成オプションをカンマで区切ります。次のコマンドは、ボリュームとしてマウントされたシークレットと、環境変数として公開された別のシークレットを更新します。

    既存のシークレットを更新するには、次のコマンドを入力します。

    gcloud run deploy SERVICE --image IMAGE_URL \
    --update-secrets=PATH=SECRET_NAME:VERSION,ENV_VAR_NAME=SECRET_NAME:VERSION
  • 既存のシークレットをクリアして、サービスで新しいシークレットを利用できるようにするには、--set-secrets フラグを使用します。

    gcloud run services update SERVICE \
    --set-secrets="ENV_VAR_NAME=SECRET_NAME:VERSION"

YAML

  1. 新しいサービスを作成する場合は、この手順をスキップします。既存のサービスを更新する場合は、その YAML 構成をダウンロードします。

    gcloud run services describe SERVICE --format export > service.yaml
  2. 環境変数として公開されたシークレットの場合、env で、必要に応じて ENV_VARVERSIONSECRET_NAME を更新します。複数のシークレットを環境変数としてマウントすると、属性はその倍数になります。

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: SERVICE
    spec:
      template:
        metadata:
          name: REVISION
        spec:
          containers:
          - image: IMAGE_URL
            env:
            - name: ENV_VAR
              valueFrom:
                secretKeyRef:
                  key: VERSION
                  name: SECRET_NAME
  3. ファイルパスとしてマウントされたシークレットの場合は、必要に応じて MOUNT_PATHVOLUME_NAMEVERSIONFILENAMESECRET_NAME を更新します。ファイルパスとして複数のシークレットをマウントすると、属性はその倍数になります。

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: SERVICE
    spec:
      template:
        metadata:
          name: REVISION
        spec:
          containers:
          - image: IMAGE_URL
            volumeMounts:
            - mountPath: MOUNT_PATH
              name: VOLUME_NAME
          volumes:
          - name: VOLUME_NAME
            secret:
              items:
              - key: VERSION
                path: FILENAME
              secretName: SECRET_NAME

    VOLUME_NAME は任意の名前に設定できます。

    次のように置き換えます。

    • SERVICE は、Cloud Run サービスの名前に置き換えます。
    • IMAGE_URL は、コンテナ イメージへの参照(us-docker.pkg.dev/cloudrun/container/hello:latest など)に置き換えます。Artifact Registry を使用する場合は、リポジトリ REPO_NAME がすでに作成されている必要があります。URL の形式は LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG です。
    • REVISION を新しいリビジョン名に置き換えるか、削除(存在する場合)します。新しいリビジョン名を指定する場合は、次の条件を満たす必要があります
      • SERVICE- で始まる
      • 小文字、数字、- のみが使用されている
      • 末尾が - ではない
      • 63 文字以内である
  4. 次のコマンドを使用して、サービスを新しい構成に置き換えます。

    gcloud run services replace service.yaml

Terraform

  1. シークレットを作成し、シークレット バージョンにアクセスします。

    resource "google_secret_manager_secret" "default" {
      secret_id = "my-secret"
      replication {
        auto {}
      }
    }
    
    resource "google_secret_manager_secret_version" "default" {
      secret      = google_secret_manager_secret.default.name
      secret_data = "this is secret data"
    }
  2. サービス アカウントを作成して、シークレットへのアクセス権を付与します。

    resource "google_service_account" "default" {
      account_id   = "cloud-run-service-account"
      display_name = "Service account for Cloud Run"
    }
    
    resource "google_secret_manager_secret_iam_member" "default" {
      secret_id = google_secret_manager_secret.default.id
      role      = "roles/secretmanager.secretAccessor"
      # Grant the new deployed service account access to this secret.
      member     = "serviceAccount:${google_service_account.default.email}"
      depends_on = [google_secret_manager_secret.default]
    }
  3. Cloud Run から Secret Manager のシークレットにアクセスするには、マウントされたファイルパスとしてアクセスするか、環境変数としてアクセスします。

    1. ファイルパスとしてマウントされたシークレットの場合は、volumes パラメータで Secret Manager リソースを参照します。namevolume_mounts パラメータのエントリに対応しています。

      resource "google_cloud_run_v2_service" "mounted_secret" {
        name     = "service-with-mounted-secret"
        location = "us-central1"
        ingress  = "INGRESS_TRAFFIC_ALL"
      
        deletion_protection = false # set to "true" in production
      
        template {
          volumes {
            name = "my-service-volume"
            secret {
              secret = google_secret_manager_secret.default.secret_id
              items {
                version = "latest"
                path    = "my-secret"
                mode    = 0 # use default 0444
              }
            }
          }
          containers {
            image = "us-docker.pkg.dev/cloudrun/container/hello"
            volume_mounts {
              name       = "my-service-volume"
              mount_path = "/secrets"
            }
          }
          service_account = google_service_account.default.email
        }
        depends_on = [google_secret_manager_secret_version.default]
      }
    2. 環境変数として公開されたシークレットの場合は、env パラメータで Secret Manager リソースを参照します。

      resource "google_cloud_run_v2_service" "env_variable_secret" {
        name     = "service-with-env-var-secret"
        location = "us-central1"
        ingress  = "INGRESS_TRAFFIC_ALL"
      
        deletion_protection = false # set to "true" in production
      
        template {
          containers {
            image = "us-docker.pkg.dev/cloudrun/container/hello"
            env {
              name = "MY_SECRET"
              value_source {
                secret_key_ref {
                  secret  = google_secret_manager_secret.default.secret_id
                  version = "latest"
                }
              }
            }
          }
          service_account = google_service_account.default.email
        }
        depends_on = [google_secret_manager_secret_version.default]
      }

他のプロジェクトのシークレットを参照する

別のプロジェクトのシークレットを参照するには、プロジェクトのサービス アカウントにシークレットへのアクセス権があることを確認します。

コンソール

  1. Google Cloud コンソールで、[Cloud Run] に移動します。

    Cloud Run に移動

  2. [コンテナをデプロイ] をクリックし、[サービス] を選択して、新しいサービスを構成します。最初のサービス設定ページに入力してから、[コンテナ、ボリューム、ネットワーキング、セキュリティ] をクリックしてサービス構成ページを開きます。

  3. 既存のサービスを構成する場合は、サービスをクリックし、[新しいリビジョンの編集とデプロイ] をクリックします。

  4. 手順に沿って、シークレットをボリュームとしてマウントするか、シークレットを環境変数として公開します。

    • シークレットをボリュームとしてマウントするには:

      1. [ボリューム] タブをクリックし、[ボリュームを追加] を選択します。
      2. [ボリュームのタイプ] リストから、[シークレット] を選択します。
      3. [ボリューム名] フィールドに名前を入力するか、デフォルト名を使用します。
      4. [シークレット] リストで、[シークレットを手動で入力] をクリックします。
      5. シークレットのリソース ID を次の形式で入力します。

        projects/PROJECT_NUMBER/secrets/SECRET_NAME
        

        次のように置き換えます。

        • PROJECT_NUMBER は、Google Cloud プロジェクト番号に置き換えます。プロジェクト番号を確認する方法の詳細については、プロジェクトの作成と管理をご覧ください。

        • SECRET_NAME: Secret Manager でのシークレットの名前。

      6. [パス 1] フィールドに、マウントするファイルの名前を入力します。

      7. [バージョン 1] リストで、参照するシークレットのバージョンを選択します。デフォルトでは最新バージョンが選択されます。必要に応じて特定のバージョンを選択できます。

      8. [完了] をクリックします。

      9. [コンテナ] タブに移動して、シークレットをコンテナにマウントします。

      10. [ボリュームのマウント] タブで、[ボリュームをマウント] をクリックします。

      11. [名前 1] リストからボリューム名を選択します。

      12. [マウントパス 1] フィールドに、このシークレットのマウントパスを入力します。これは、シークレットのすべてのバージョンが配置されるディレクトリです。

      13. [完了] をクリックします。

      14. [作成] または [デプロイ] をクリックします。

    • シークレットを環境変数として公開するには:

      1. [コンテナ] タブをクリックします。
      2. [変数とシークレット] タブで、[シークレットを参照] をクリックします。
      3. [名前 1] フィールドに、環境変数の名前を入力します。
      4. [シークレット] リストで、[シークレットを手動で入力] をクリックします。
      5. シークレットのリソース ID を次の形式で入力します。

        projects/PROJECT_NUMBER/secrets/SECRET_NAME
        

        次のように置き換えます。

        • PROJECT_NUMBER は、Google Cloud プロジェクト番号に置き換えます。プロジェクト番号を確認する方法の詳細については、プロジェクトの作成と管理をご覧ください。

        • SECRET_NAME: Secret Manager でのシークレットの名前。

      6. [バージョン 1] リストから、参照するシークレットのバージョンを選択します。

      7. [完了] をクリックします。

      8. [作成] または [デプロイ] をクリックします。

gcloud

  • サービスをデプロイするときにシークレットをボリュームとしてマウントするには:

    gcloud run deploy SERVICE --image IMAGE_URL  \
    --update-secrets=PATH=projects/PROJECT_NUMBER/secrets/SECRET_NAME:VERSION

    次のように置き換えます。

    • SERVICE: 実際のサービスの名前。
    • IMAGE_URL: コンテナ イメージへの参照(us-docker.pkg.dev/cloudrun/container/hello:latest など)。Artifact Registry を使用する場合は、リポジトリ REPO_NAME がすでに作成されている必要があります。URL の形式は LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG です。
    • PATH は、ボリュームのマウントパスとシークレットのファイル名で置き換えます。先頭にスラッシュを付ける必要があります(例: /etc/secrets/dbconfig/password)。ここで、/etc/secrets/dbconfig/ はボリュームのマウントパス、password はシークレットのファイル名です。
    • PROJECT_NUMBER は、シークレットが作成されたプロジェクトのプロジェクト番号に置き換えます。
    • SECRET_NAME は、mysecret などのシークレット名に置き換えます。
    • VERSION は、シークレットのバージョンに置き換えます。最新バージョンには latest または数字(2 など)を使用します。

YAML

  1. 新しいサービスを作成する場合は、この手順をスキップします。既存のサービスを更新する場合は、その YAML 構成をダウンロードします。

    gcloud run services describe SERVICE --format export > service.yaml

API の互換性には制約があるため、シークレットの場所はアノテーションに保存する必要があります。

  1. 環境変数として公開されたシークレットの場合:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: SERVICE
    spec:
      template:
        metadata:
          annotations:
            run.googleapis.com/secrets: SECRET_LOOKUP_NAME:projects/PROJECT_NUMBER/secrets/SECRET_NAME
        spec:
          containers:
          - image: IMAGE_URL
            env:
            - name: ENV_VAR
              valueFrom:
                secretKeyRef:
                  key: VERSION
                  name: SECRET_LOOKUP_NAME

    次のように置き換えます。

    • SERVICE: 実際のサービスの名前。
    • IMAGE_URL: コンテナ イメージへの参照(us-docker.pkg.dev/cloudrun/container/hello:latest など)。Artifact Registry を使用する場合は、リポジトリ REPO_NAME がすでに作成されている必要があります。URL の形式は LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG です。
    • ENV_VAR
    • PROJECT_NUMBER は、シークレットが作成されたプロジェクトのプロジェクト番号に置き換えます。
    • SECRET_NAME は、mysecret などのシークレット名に置き換えます。
    • VERSION は、シークレットのバージョンに置き換えます。最新バージョンには latest または数字(2 など)を使用します。
    • SECRET_LOOKUP_NAME は、有効なシークレット名の構文を持つ任意の名前(my-secret など)で置き換えます。SECRET_NAME と同じ値にすることもできます。
  2. シークレットをファイルパスとしてマウントする場合:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: SERVICE
    spec:
      template:
        metadata:
          annotations:
            run.googleapis.com/secrets: SECRET_LOOKUP_NAME:projects/PROJECT_NUMBER/secrets/SECRET_NAME
        spec:
          containers:
          - image: IMAGE_URL
            volumeMounts:
            - mountPath: MOUNT_PATH
              name: VOLUME_NAME
          volumes:
          - name: VOLUME_NAME
            secret:
              items:
              - key: VERSION
                path: FILENAME
              secretName: SECRET_LOOKUP_NAME

    次のように置き換えます。

    • SERVICE: 実際のサービスの名前。
    • IMAGE_URL: コンテナ イメージへの参照(us-docker.pkg.dev/cloudrun/container/hello:latest など)。Artifact Registry を使用する場合は、リポジトリ REPO_NAME がすでに作成されている必要があります。URL の形式は LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG です。
    • PATH は、ボリュームのマウントパスとシークレットのファイル名で置き換えます。先頭にスラッシュを付ける必要があります(例: /etc/secrets/dbconfig/password)。ここで、/etc/secrets/dbconfig/ はボリュームのマウントパス、password はシークレットのファイル名です。
    • PROJECT_NUMBER は、シークレットが作成されたプロジェクトのプロジェクト番号に置き換えます。
    • SECRET_NAME は、mysecret などのシークレット名に置き換えます。
    • VERSION は、シークレットのバージョンに置き換えます。最新バージョンには latest または数字(2 など)を使用します。
    • SECRET_LOOKUP_NAME は、有効なシークレット名の構文を持つ任意の名前(my-secret など)で置き換えます。SECRET_NAME と同じ値にすることもできます。
    • VOLUME_NAME は任意の名前(my-volume など)で置き換えます。SECRET_NAME と同じ値にすることもできます。

シークレットの設定を表示する

Cloud Run サービスの現在のシークレットの設定を表示するには:

コンソール

  1. Google Cloud コンソールで、[Cloud Run] に移動します。

    Cloud Run に移動

  2. 目的のサービスをクリックして、[サービスの詳細] ページを開きます。

  3. [リビジョン] タブをクリックします。

  4. 右側の詳細パネルの [コンテナ] タブに、シークレットの設定が表示されます。

gcloud

  1. 次のコマンドを使用します。

    gcloud run services describe SERVICE
  2. 返された構成で、シークレットの設定を見つけます。

コードでシークレットを使用する

コード内でシークレットを環境変数としてアクセスする例については、エンドユーザー認証に関するチュートリアル、特に Secret Manager で機密性の高い構成を処理するのセクションをご覧ください。

許可されていないパスと制限

Cloud Run では、/dev/proc/sys、またはそのサブディレクトリにシークレットをマウントすることはできません。

/tmp にシークレットをマウントし、第 1 世代の実行環境を使用している場合は、/tmp へのシークレットのマウントに関する既知の問題をご覧ください。

Cloud Run では、複数のボリューム マウントを同じ場所にマウントできないため、複数のシークレットを同じパスにマウントすることはできません。

ディレクトリのオーバーライド

Cloud Run でシークレットがボリュームとしてマウントされ、ボリューム マウント パスの最後のディレクトリがすでに存在する場合、既存のディレクトリ内のファイルまたはフォルダにアクセスできなくなります。

たとえば、my-secret という名前のシークレットがパス /etc/app_data にマウントされている場合、app_data ディレクトリ内のすべてのコンテンツが上書きされ、表示されるファイルは /etc/app_data/my-secret のみになります。

既存のディレクトリ内のファイルを上書きしないようにするには、シークレットをマウントするディレクトリ(/etc/app_data/secrets など)を新たに作成し、シークレットのマウントパスを /etc/app_data/secrets/my-secret にします。