シークレットを構成する

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

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

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

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

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

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

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

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

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

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

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

  • 複数のコンテナをデプロイする第 1 世代の実行環境
  • 第 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. [完了] をクリックします。
      • シークレットを環境変数として公開する場合:
        1. 変数の名前を指定し、シークレット バージョンを選択します。常に現在のシークレット バージョンを使用する場合は、latest に設定します。
        2. [完了] をクリックします。
  5. [作成] または [デプロイ] をクリックします。

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. シークレットを作成し、シークレット バージョンにアクセスします。

    
    terraform {
      required_providers {
        google = {
          source  = "hashicorp/google"
          version = "~> 5.13.0"
        }
      }
    }
    
    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     = "cloudrun-srv-mounted-secret"
        location = "us-central1"
        ingress  = "INGRESS_TRAFFIC_ALL"
      
        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     = "cloudrun-srv-env-var-secret"
        location = "us-central1"
        ingress  = "INGRESS_TRAFFIC_ALL"
      
        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. [コンテナ] タブをクリックします。

    画像

    • [シークレット] で、次の操作を行います。
      • [シークレットの参照] をクリックします。
      • [Secret が表示されない場合は、Secret のリソース ID を入力してください] を [シークレット] プルダウン リストから選択し、次のフォームを表示します。

        プロジェクト間のシークレット

      • [リソース ID による Secret の追加] フォームに、他のプロジェクトのシークレットを projects/PROJECT_NUMBER/secrets/SECRET_NAME の形式で入力します。他のプロジェクトのリソース ID が利用可能な場合は、それをコピーして貼り付けることができます。その場合、シークレットを選択してから、シークレットの右側にある [アクション] をクリックし、プルダウン メニューから [リソース ID をコピー] を選択します。
      • [シークレットを追加] をクリックします。
      • [参照の方法] プルダウン メニューで、シークレットの使用方法を選択します(ボリュームとしてマウントするか、環境変数として公開します)。
      • シークレットをボリュームとしてマウントする場合:
        1. [マウントパス] で、シークレットに使用するマウントパスを指定します。
        2. デフォルトでは最新バージョンが選択されます。必要に応じて特定のバージョンを選択できます。[シークレット バージョンに指定されているパス] で、バージョンへのパスとバージョン番号を指定します。
        3. [完了] をクリックします。
      • シークレットを環境変数として公開する場合:
        1. 変数の名前を指定し、シークレット バージョンを選択します。常に現在のシークレット バージョンを使用する場合は、latest に設定します。
        2. [完了] をクリックします。
  5. [作成] または [デプロイ] をクリックします。

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 にします。