GoogleCloudのParameterManagerがlatest識別子に対応したので試してみる

GoogleCloudのParameterManagerがlatest識別子に対応したので試してみる

2026.06.02

はじめに

データアナリティクス事業本部のkobayashiです。

以前Google CloudのParameter Managerについて2本記事を書きました。

https://dev.classmethod.jp/articles/googlecloud-parametermanager/

https://dev.classmethod.jp/articles/googlecloud-secret-parametermanager/

これらの記事ではパラメータの取得時に必ずバージョンIDを明示的に指定する必要があり、最新のバージョンを取得したい場合でも developproduction のような具体的なバージョン名を指定するか、事前に最新のバージョンを取得する処理を挟む必要がありました。

2026年4月7日のアップデートでParameter Managerが latest 識別子 に対応し、バージョンIDを指定せずに最新のパラメータバージョンを取得できるようになりました。Secret Managerの versions/latest と同じ感覚で使えるようになっています。

https://docs.cloud.google.com/secret-manager/docs/release-notes

latest 識別子とは

Parameter Managerのバージョンを参照するパスの末尾、本来バージョンIDを指定する部分に latest を指定すると、そのパラメータの 最新のアクティブなバージョン が取得されます。

通常のバージョンを指定したパス:

projects/{プロジェクトID}/locations/global/parameters/{パラメータ名}/versions/{バージョンID}

latest を指定したパス:

projects/{プロジェクトID}/locations/global/parameters/{パラメータ名}/versions/latest

これまでは複数バージョン管理しているパラメータに対して「最新を取りたい」というだけの目的でバージョン一覧を取得してソートする、もしくは呼び出し側で常に最新のバージョン名を更新する、といった対応が必要でした。latest 識別子によりそうしたコードが不要になります。

事前準備

前回までと同様、JSON形式のパラメータを作成し複数のバージョンを登録した状態から始めます。

$ gcloud parametermanager parameters create param_store_test_json \
    --location=global --parameter-format=json

$ gcloud parametermanager parameters versions create v1 \
    --parameter=param_store_test_json --location=global \
    --payload-data='{"database":"myapp_test","username":"test_user_v1","host":"dev.example.com","port":5432}'

$ gcloud parametermanager parameters versions create v2 \
    --parameter=param_store_test_json --location=global \
    --payload-data='{"database":"myapp_test","username":"test_user_v2","host":"dev.example.com","port":5432}'

$ gcloud parametermanager parameters versions create v3 \
    --parameter=param_store_test_json --location=global \
    --payload-data='{"database":"myapp_test","username":"test_user_v3","host":"dev.example.com","port":5432}'

なお、前回までは gcloud beta parametermanager を使用していましたが、Parameter ManagerはGA済みのため beta は不要になっています。

gcloudコマンドで latest を使う

latest を指定してパラメータを取得してみます。

$ gcloud parametermanager parameters versions render latest \
    --parameter=param_store_test_json --location=global
parameterVersion: projects/{プロジェクトID}/locations/global/parameters/param_store_test_json/versions/v3
payload:
  data: eyJkYXRhYmFzZSI6Im15YXBwX3Rlc3QiLCJ1c2VybmFtZSI6InRlc3RfdXNlcl92MyIsImhvc3QiOiJkZXYuZXhhbXBsZS5jb20iLCJwb3J0Ijo1NDMyfQ==
renderedPayload: eyJkYXRhYmFzZSI6Im15YXBwX3Rlc3QiLCJ1c2VybmFtZSI6InRlc3RfdXNlcl92MyIsImhvc3QiOiJkZXYuZXhhbXBsZS5jb20iLCJwb3J0Ijo1NDMyfQ==

レスポンスの parameterVersion を確認すると、最後に作成した v3 のバージョンが返ってきていることがわかります。バージョンIDを意識せずに最新のものが取得できました。 renderedPayload__REF__ でSecret Managerを参照しているパラメータの場合に解決後の値が入るフィールドで、__REF__ を使っていない今回のケースでは payload.data と同じ値が返っています。

REST APIで latest を使う

REST APIでも同様に versions/latest をURLパスに指定するだけです。前回のスクリプトをベースに latest 識別子で取得する形に書き換えてみます。

get_param_latest.py
import requests
import google.auth
import google.auth.transport.requests

import base64
import json

# サービスアカウントの認証情報を取得
credentials, project = google.auth.default(
    scopes=["https://www.googleapis.com/auth/cloud-platform"]
)

auth_req = google.auth.transport.requests.Request()
credentials.refresh(auth_req)

headers = {
    "Authorization": f"Bearer {credentials.token}",
}

# latest で最新のパラメータバージョンを取得
param_name = "param_store_test_json"
response = requests.get(
    f"https://parametermanager.googleapis.com/v1/projects/{project}/locations/global/parameters/{param_name}/versions/latest:render",
    headers=headers,
)
ret = response.json()
print(f"取得したバージョン: {ret['parameterVersion']}")

decoded_bytes = base64.b64decode(ret["payload"]["data"]).decode("utf-8")
config_dict = json.loads(decoded_bytes)
print("最新バージョンのパラメータ:")
print(config_dict)

実行してみます。

$ python get_param_latest.py
取得したバージョン: projects/{プロジェクトID}/locations/global/parameters/param_store_test_json/versions/v3
最新バージョンのパラメータ:
{'database': 'myapp_test', 'username': 'test_user_v3', 'host': 'dev.example.com', 'port': 5432}

呼び出し側のコードにバージョンIDを持たせる必要がなくなり、新しいバージョンを追加するだけでアプリケーション側は自動的に新しい値を使うようになります。

新しいバージョンを追加して再度実行してみます。

$ gcloud parametermanager parameters versions create v4 \
    --parameter=param_store_test_json --location=global \
    --payload-data='{"database":"myapp_test","username":"test_user_v4","host":"dev.example.com","port":5432}'

$ python get_param_latest.py
取得したバージョン: projects/{プロジェクトID}/locations/global/parameters/param_store_test_json/versions/v4
最新バージョンのパラメータ:
{'database': 'myapp_test', 'username': 'test_user_v4', 'host': 'dev.example.com', 'port': 5432}

スクリプトには一切手を加えていませんが、最新の v4 の値が返ってくるようになりました。

Secret Managerを参照するパラメータとの組み合わせ

前回の記事ではParameter ManagerからSecret Managerのシークレットを __REF__ で参照する構成を試しました。この構成と latest 識別子を組み合わせることで、シークレットのローテーションがより扱いやすくなります。

Secret Manager側もシークレットの参照に versions/latest が使用できるため、両方を latest にすることで「Parameter Managerに保存している設定情報も、Secret Managerに保存しているシークレットも、常に最新を取得する」構成が組めます。

まずSecret Managerのシークレットを作成し、latest で参照する形式のパラメータを登録します。

$ gcloud secrets create db_password --replication-policy="automatic"
$ printf "password_initial" | gcloud secrets versions add db_password --data-file=-

$ gcloud parametermanager parameters versions create v1 \
    --parameter=param_store_test_json --location=global \
    --payload-data='{"database":"myapp_prod","username":"prod_user","password":"__REF__(\"//secretmanager.googleapis.com/projects/{プロジェクトID}/secrets/db_password/versions/latest\")","host":"prod.example.com","port":5432}'

__REF__ のリソース名の末尾を /versions/latest にしている点がポイントです。これにより、Secret Managerにパスワードの新しいバージョンを追加するだけで、render で得られる renderedPayload のパスワードも自動的に切り替わります。

Pythonで取得してみます。

get_param_secret_latest.py
import requests
import google.auth
import google.auth.transport.requests

import base64
import json

credentials, project = google.auth.default(
    scopes=["https://www.googleapis.com/auth/cloud-platform"]
)

auth_req = google.auth.transport.requests.Request()
credentials.refresh(auth_req)

headers = {
    "Authorization": f"Bearer {credentials.token}",
}

param_name = "param_store_test_json"
response = requests.get(
    f"https://parametermanager.googleapis.com/v1/projects/{project}/locations/global/parameters/{param_name}/versions/latest:render",
    headers=headers,
)
ret = response.json()
print(f"取得したバージョン: {ret['parameterVersion']}")
print("renderedPayload:")
print(json.loads(base64.b64decode(ret["renderedPayload"]).decode("utf-8")))

実行結果は以下のようになります。

$ python get_param_secret_latest.py
取得したバージョン: projects/{プロジェクトID}/locations/global/parameters/param_store_test_json/versions/v1
renderedPayload:
{'database': 'myapp_prod', 'username': 'prod_user', 'password': 'password_initial', 'host': 'prod.example.com', 'port': 5432}

Secret Manager側でパスワードをローテーションしてみます。

$ printf "password_rotated" | gcloud secrets versions add db_password --data-file=-

$ python get_param_secret_latest.py
取得したバージョン: projects/{プロジェクトID}/locations/global/parameters/param_store_test_json/versions/v1
renderedPayload:
{'database': 'myapp_prod', 'username': 'prod_user', 'password': 'password_rotated', 'host': 'prod.example.com', 'port': 5432}

Parameter Managerのバージョンには変更を加えていませんが、Secret Managerの最新バージョンの値が renderedPayload 側に反映されています。設定情報とシークレットを別々に管理しつつ、双方のローテーションをアプリケーションコードからは透過的に扱えます。

取得したバージョンをログに残す

latest を使うと呼び出し側はバージョンIDを意識しなくて良くなりますが、その分「いつ・どのバージョンが返ってきたか」がアプリケーションログから消えてしまいます。障害調査や監査の際に困らないよう、render のレスポンスに含まれる parameterVersion を実際に取得したタイミングでログに出しておく形にしておくと安心です。

レスポンスの parameterVersion はフルリソース名で返るため、ログ用にバージョンID部分だけを抜き出すヘルパーをかませて出力します。

get_param_with_log.py
import base64
import json
import logging

import requests
import google.auth
import google.auth.transport.requests

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(name)s %(message)s",
)
logger = logging.getLogger("param_loader")

def render_parameter(project: str, parameter: str, version: str = "latest") -> dict:
    """Parameter Managerからパラメータをrenderしつつ、取得したバージョンをログに残す"""
    credentials, _ = google.auth.default(
        scopes=["https://www.googleapis.com/auth/cloud-platform"]
    )
    credentials.refresh(google.auth.transport.requests.Request())

    url = (
        "https://parametermanager.googleapis.com/v1"
        f"/projects/{project}/locations/global"
        f"/parameters/{parameter}/versions/{version}:render"
    )
    response = requests.get(url, headers={"Authorization": f"Bearer {credentials.token}"})
    response.raise_for_status()
    body = response.json()

    # フルリソース名 (.../versions/v4) からバージョンID部分のみ取り出す
    resolved_version = body["parameterVersion"].rsplit("/", 1)[-1]
    logger.info(
        "parameter rendered: requested=%s resolved=%s",
        version,
        resolved_version,
        extra={
            "parameter": parameter,
            "requested_version": version,
            "resolved_version": resolved_version,
            "resource_name": body["parameterVersion"],
        },
    )

    payload_b64 = body.get("renderedPayload") or body["payload"]["data"]
    return json.loads(base64.b64decode(payload_b64).decode("utf-8"))

if __name__ == "__main__":
    _, project = google.auth.default(
        scopes=["https://www.googleapis.com/auth/cloud-platform"]
    )
    config = render_parameter(project, "param_store_test_json", version="latest")
    logger.info("config loaded: %s", config)

実行すると latest を指定して呼び出した行と、実際に解決されたバージョンが同じログ行に紐付いた形で出力されます。

$ python get_param_with_log.py
2026-05-25 14:43:44,228 INFO param_loader parameter rendered: requested=latest resolved=v1
2026-05-25 14:43:44,230 INFO param_loader config loaded: {'database': 'myapp_prod', 'username': 'prod_user', 'password': 'password_rotated', 'host': 'prod.example.com', 'port': 5432}

ログ集約基盤に extra の構造化フィールドをそのまま渡すフォーマッタを組み合わせれば、Cloud Loggingなどから resolved_version でフィルタしてどのバージョンが本番に出ていたかを後追いできます。Secret Managerを __REF__ で参照している場合は、シークレット側のバージョンも同様に呼び出し直後にログに残しておくと、ローテーション起因の障害切り分けがしやすくなります。

使う上での注意点

latest 識別子は便利ですが、使用する上で注意したい点がいくつかあります。

注意点 内容
取得バージョンが変わる 新しいバージョンを追加した時点で、latest の参照先が即座に切り替わるため、本番環境では意図せず値が変わらないよう管理する
バージョンの無効化 latest は無効化されたバージョンも含めて常に「最新作成バージョン」を指す。最新バージョンを無効化(disabled=true)すると、latest:render は古い有効なバージョンへフォールバックせず FAILED_PRECONDITION(HTTP 400、The resource ... is currently disabled.)でエラーになる。無効化によって旧バージョンへ切り戻すことはできない点に注意する

特に1点目は重要で、これまでバージョンを明示指定していたコードを latest に切り替える際は、誤って本番用パラメータに別環境用の値を追加してしまわないようバージョン作成のフロー自体を見直しておくと安全です。

まとめ

Parameter Managerの latest 識別子を試してみました。gcloud parametermanager コマンドでもRESTでも versions/latest を指定するだけで最新のパラメータが取得でき、呼び出し側からバージョンID管理のコードを取り除けます。Secret Managerを __REF__ で参照しているパラメータと組み合わせると、設定情報とシークレットの両方を一切のコード変更なしにローテーションできる構成が組めるので、シークレットローテーションを伴うワークロードでは有用な使い方になると思います。

最後まで読んで頂いてありがとうございました。

この記事をシェアする

関連記事