With Cloud Build
--Using Docker in steps --I also want to use Application Default Credential from Docker
Then, let's pass --network = cloudbuild
.
For an example, use berglas.
berglas will fetch the value if you put a reference to the secret information in a specific format in the environment variable.
For example, if you execute FOO = sm: // $ PROJECT_ID / $ SECRET_NAME berglas exec --bar
, the value fetched from Secret Manager will be put into the environment variable FOO
and bar
will be executed.
First, in Secret Manager, enter a value in the secret called TEST
.
$ echo -n "supersecret" | gcloud beta secrets create TEST --replication-policy automatic --data-file=-
Also, add the Secret Accesor role to the Cloud Build execution service account.
$ 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
The environment variable is output by env
to simplify the experiment, but it will be recorded in the log, so please be careful not to use it as it is if you really handle secret information.
First, let's use the image of berglas directly.
cloudbuild.yaml
steps:
- name: 'asia-docker.pkg.dev/berglas/berglas/berglas:latest'
args:
- 'exec'
- '--'
- 'env'
env:
- 'TEST=sm://$PROJECT_ID/TEST'
Let's run it now.
$ gcloud builds submit --config cloudbuild.yaml --no-source
...
TEST=supersecret
...
I was able to see the restored TEST.
Next, try using berglas via docker run
in the build step.
cloudbuild.yaml
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'
Then ...
$ 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
...
I get an error. It seems that you cannot request to get Application Default Credential from the Docker container.
Let's see what kind of network there is.
cloudbuild.yaml
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
...
If you want to use the Application Default Credential, you need to pass the cloudbuild
network. (Host
is no good.)
This is also documented.
cloudbuild.yaml
steps:
- name: 'gcr.io/cloud-builders/docker'
args:
- 'run'
- '--network=cloudbuild' #add to
- '-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
...
I was able to see it safely.
If you want to use the Docker container inside the Cloud Build step and also use the Application Default Credential from the container, pass --network = cloudbuild
.