この記事はGoogle Cloud Platform Advent Calendar 20203日目の記事です
AWSだとParameterStoreなどがあるがGCPだとなんなんだろうということで調べて使ってみた
Secret Manager
外部サービスのAPIキーやパスワードなどの秘匿情報を含むデータをGCP上で管理できるサービス
今回は実際にローカルの開発環境から使ってみる
データの登録
コマンドラインから登録する
$ echo 'hoge fuga' | gcloud secrets create my-secret --data-file=-
標準入力から入力する方法以外にもいろいろある
$ echo -n $TOGGL_API_TOKEN | gcloud secrets create 'toggl/token' --data-file=- ERROR: (gcloud.secrets.create) INVALID_ARGUMENT: Resource ID [toggl/token] is not in a valid format.
AWSのパラメータストアのノリで/
区切りがいけるかなと試してみたがだめだった
/
は使えない模様
$ echo -n $TOGGL_API_TOKEN | gcloud secrets create 'toggl-token' --data-file=- Created version [1] of the secret [toggl-token].
取得
$ gcloud secrets versions access latest --secret='my-secret' hoge fuga
更新
$ echo -n 'hoge fuga piyo' | gcloud secrets versions add my-secret --data-file=-
値が変わっていることが確認できる
$ gcloud secrets versions access latest --secret='my-secret' hoge fuga piyo
Rubyの実装で試してみる
CloudRunからキーを参照して使う予定だったのでいったんローカルでサーバを起動して動作させられるか試す
事前にサービスアカウントを作成してSecret Manager のシークレット アクセサー
のロールを追加しておく
- app.rb
require "google/cloud/secret_manager" require "sinatra" post "/" do client = Google::Cloud::SecretManager.secret_manager_service key = client.secret_version_path project: project_id, secret: 'my-secret', secret_version: 'latest' res = client.access_secret_version name: key p 'secret ======' p res.payload p res.payload.data end
- サーバの起動
$ ruby app.rb
- アクセス
$ curl http://127.0.0.1:8080
適当にアクセスしてログを見る
- ログ
"secret ======" <Google::Cloud::SecretManager::V1::SecretPayload: data: "hoge fuga piyo"> "hoge fuga piyo"
gcloud
コマンドでは意識しなかったがsecretが保存されているパスを指定する必要がある
サンプルでいうと
projects/#{project_id}/secrets/{secret_name}/versions/latest
project_id
が必要
GOOGLE_APPLICATION_CREDENTIALS
にサービスアカウントのキーを置いておけばそのあたりよしなにやってくれるのかと思っていたらそんなことはなく
PermissionDeniedで怒られた
2020-10-30 10:40:12 - Google::Cloud::PermissionDeniedError - 7:Secret Manager API has not been used in project 111111111111 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/secretmanager.googleapis.com/overview?project=111111111111 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.. debug_error_string:{"created":"@1604054412.050131516","description":"Error received from peer ipv4:172.217.27.74:443","file":"src/core/lib/surface/call.cc","file_line":1062,"grpc_message":"Secret Manager API has not been used in project 111111111111 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/secretmanager.googleapis.com/overview?project=111111111111 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.","grpc_status":7}: /usr/local/bundle/gems/google-cloud-secret_manager-v1-0.5.0/lib/google/cloud/secret_manager/v1/secret_manager_service/client.rb:826:in `rescue in access_secret_version' /usr/local/bundle/gems/google-cloud-secret_manager-v1-0.5.0/lib/google/cloud/secret_manager/v1/secret_manager_service/client.rb:792:in `access_secret_version' ./app.rb:21:in `block in <main>'
プロジェクトIDがないと別のプロジェクト的なものと解釈されてAPI有効にしろ!などと言われるっぽい(該当プロジェクトでは有効にしている)
ここで出てくるPROJECT_NUMBER的なもの(111111111111)はどのプロジェクトなのかは探せなかったので不明
結構詰まったが最終的にはGitHubでコード検索して実装方法を探して解決した
過去のバージョンの値を取得する
ここのバージョンを指定することで過去の値も取ることができる
- ログ
"projects/sampleproject-0000000/secrets/my-secret/versions/1" <Google::Cloud::SecretManager::V1::SecretPayload: data: "hoge fuga"> "hoge fuga"
あまり過去のバージョンのキーを指定するケースが思い浮かばないがそういうこともできる
おわり
簡単に使用できた
各種言語のクライアントライブラリもあるので導入は簡単にできそう
実際に使っていくと管理対象が増えてきたときにどうやって管理するのかが心配ではある
AWSのパラメータストアだと/
区切りでパスを指定できて特定のパスまでの情報を一括で取得できたりしてよくできているなと思った
一方GCPだとそうではなさそうなので命名規則でなんとかするくらいしか思い浮かばず
そもそも用途がーみたいな話もありそうだなと思いつつ、どのような運用が良いのか答えが出ていないので詳しい方にアドバイスとかもらえたら嬉しい