概要
Cloud Buildで
- ステップ内でDockerを使い
- DockerからApplication Default Credentialも使いたい
なら --network=cloudbuild
を渡そうという話です。
前提
例にはberglas利用します。
berglasは環境変数に特定フォーマットで秘密情報への参照を入れておくと、その値をとってきてくれます。
例えば FOO=sm://$PROJECT_ID/$SECRET_NAME berglas exec -- bar
を実行すると、Secret Managerから取ってきた値が環境変数 FOO
に入って bar
が実行されます。
準備
まずSecret Managerで TEST
というシークレットに値を入れておきます。
$ echo -n "supersecret" | gcloud beta secrets create TEST --replication-policy automatic --data-file=-
またCloud Buildの実行サービスアカウントに、Secret Accesorロールをつけておきます。
$ gcloud projects add-iam-policy-binding $PROJECT_ID \
--member "serviceAccount:$(gcloud projects describe $PROJECT_ID --format 'value(projectNumber)')@cloudbuild.gserviceaccount.com" \
--role roles/secretmanager.secretAccessor
実験
実験を単純にする為に env
で環境変数を出力していますが、ログに残るので本当に秘密の情報を扱うならそのまま使わないように気をつけてください。
ステップ内部でDockerを使わないのでうまくいく例
まずberglasのイメージを直接使ってみます。
steps:
- name: 'asia-docker.pkg.dev/berglas/berglas/berglas:latest'
args:
- 'exec'
- '--'
- 'env'
env:
- 'TEST=sm://$PROJECT_ID/TEST'
これで実行してみます。
$ gcloud builds submit --config cloudbuild.yaml --no-source
...
TEST=supersecret
...
復元されたTESTをみることができました。
ダメな例
次にビルドステップ内でdocker run
経由でberglasを使ってみます。
steps:
- name: 'gcr.io/cloud-builders/docker'
args:
- 'run'
- '-e'
- 'TEST=sm://$PROJECT_ID/TEST'
- 'asia-docker.pkg.dev/berglas/berglas/berglas:latest'
- 'exec'
- '--'
- 'env'
すると…
$ gcloud builds submit --config cloudbuild.yaml --no-source
...
failed to access secret sm://$PROJECT_ID/TEST: failed to access secret: rpc error: code = Unauthenticated desc = transport: Get "http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token?scopes=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform": dial tcp 169.254.169.254:80: i/o timeout
...
エラーが起きてしまいます。DockerコンテナからApplication Default Credential取得リクエストができないようですね。
どんなネットワークがあるのか試しに見てみます。
steps:
- name: 'gcr.io/cloud-builders/docker'
args:
- 'network'
- 'ls'
$ gcloud builds submit --config cloudbuild.yaml --no-source
...
NETWORK ID NAME DRIVER SCOPE
ed09d11c5bd1 bridge bridge local
a01cfc17c577 cloudbuild bridge local
f3426b77657b host host local
9b756bf55527 none null local
...
Application Default Credentialを使いたい場合には、このうち cloudbuild
ネットワークを渡す必要があります。( host
ではだめです。)
これはドキュメントにも書いてあります。
うまくいく例
steps:
- name: 'gcr.io/cloud-builders/docker'
args:
- 'run'
- '--network=cloudbuild' # 追加
- '-e'
- 'TEST=sm://$PROJECT_ID/TEST'
- 'asia-docker.pkg.dev/berglas/berglas/berglas:latest'
- 'exec'
- '--'
- 'env'
$ gcloud builds submit --config cloudbuild.yaml --no-source
...
TEST=supersecret
...
無事見ることができました。
結論
Cloud Buildのステップ内部でDockerコンテナを使い、コンテナからApplication Default Credentialも使いたいなら --network=cloudbuild
を渡しましょう。