CloudBuildでSecret Managerの機密データを取得して変数として使用する
先日GCPのCloudBuild + KMSで機密ファイルを暗号化して管理するという記事を書きました。
今回はKMSの代わりにSecret Manager(シークレット・マネージャー)というGCPサービスで機密データを管理し、Google CloudBuildの中でデータを使用する方法をまとめておきます。
KMSとSecret Managerの使い分け(個人的意見)
トークンやパスワードなどの単純な文字列の管理であれば、KMSよりもSecret Managerを使った方が暗号化の手間がなく、バージョン管理もできて安全かつ楽だと思います。
一方で何らかの機密データを含むファイルをローカルで暗号化したうえで、CloudBuildの中で復元したいような場合にはKMSを使うと良いと思います。
Secret ManagerのAPIを有効にする
プロジェクトではじめてSecret Managerを使う場合にはGCPコンソールからAPIを有効化しておく必要があります。
シークレットを作成する
同じくSecret Managerからシークレットを作成します。
以下のようにCloudBuildの中で使いたいシークレットの名前と値を入力します。
CloudBuildからシークレットにアクセスできるようにIAM設定をしておく
CloudBuildの中でこのシークレットの値を取得できるようにするためには、CloudBuildのサービスアカウントに対してIAMポリシーを付与する必要があります。
CloudBuildのサービスアカウント名を控えておく
GCPコンソールのIAMを開くと、メンバーの一覧に~~○○@cloudbuild.gserviceaccount.com
というサービスアカウントが見つかります~~[1]。この文字列をコピーしておきます。
Secret ManagerでCloudBuildから取得したいシークレットに権限を付与
再びSecret Managerを開きます。操作を行う前に[情報パネルを表示]しておきます。
使いたいシークレットを選択し、情報パネルの[メンバー追加]ボタンを押して、○○@cloudbuild.gserviceaccount.com
に対して、Secret Managerのシークレットアクセサーというロールを付与します。
これで、さきほど作成したシークレットにCloudBuildからアクセスできるようになります。これで準備は完了です。
CloudBuildのステップの中で値を使用する
cloudbuild.yaml
などのCloudBuild構成ファイルの中で、Secret Managerのシークレットを使用するには以下のような書き方をします。
steps:
- name: gcr.io/cloud-builders/docker
entrypoint: 'bash'
args: ['-c', 'docker run --env example=$$FOO_BAR']
secretEnv: ['FOO_BAR']
availableSecrets:
secretManager:
- versionName: projects/example/secrets/FOO_BAR/versions/1
env: FOO_BAR
簡単に解説をしておきます。
availableSecrets
で使用したいシークレットを宣言しておく
availableSecrets:
secretManager:
- versionName: projects/example/secrets/FOO_BAR/versions/1
env: FOO_BAR
-
availableSecrets
の下にsecretManager
というフィールドを用意し、その下に使用したいシークレットの情報を並べます。 -
versionName
はprojects/GCPプロジェクト名/secrets/シークレット名/versions/バージョン番号
という形式で指定します。シークレットを更新した場合にはバージョンが2
、3
…となっていくイメージですね。
stepの中で変数を使用する
steps:
- name: gcr.io/cloud-builders/docker
entrypoint: 'bash'
args: ['-c', 'docker run --env example=$$FOO_BAR']
secretEnv: ['FOO_BAR']
-
ドキュメント(2021/02/23時点)によると、シークレットを参照するためには
entrypoint
としてbash
を指定する必要があります。 -
args
は-c
から始めるようにします。-c
の後に続く文字列が実行コマンドとなります。 - シークレット名には
$$
というプレフィックスをつけるようにします。
これでコマンド実行時にシークレットが埋め込まれるようになります。
より詳細な手順はドキュメントのConfiguring builds to access the secret from Secret Managerを読むのが良いと思います。
-
見つからない場合はCloudBuildのAPIを有効にする必要があります。GCPコンソールの検索ウィンドウから「CloudBuild」と検索すれば「CloudBuild API」というものがヒットするのでそちらから有効にしてください。 ↩︎
Discussion
記事ありがとうございます!
上記の引用部分で少し詰まったのでメモ残します🙏
2024年4月29日以降にCloudBuild APIを有効にしたプロジェクトでは、ビルド時に使われるサービスアカウントが以下のように変更されたので"○○-compute@developer.gserviceaccount.com"に対して権限を付与していく必要がありそうでした!(もしくはbuild用のサービスアカウントを別途作成)
before: CloudBuildサービスアカウント(○○@cloudbuild.gserviceaccount.com)
after: ComputeEngineサービスアカウント(○○-compute@developer.gserviceaccount.com)
参考: https://blog.g-gen.co.jp/entry/cloud-build-service-account-changes
詳しくありがとうございます!追記しておきます!