Skip to content

Instantly share code, notes, and snippets.

@neoakris
Last active September 28, 2022 22:36
Show Gist options
  • Save neoakris/bd53146a7a610253abdbc1234ffb357b to your computer and use it in GitHub Desktop.
Save neoakris/bd53146a7a610253abdbc1234ffb357b to your computer and use it in GitHub Desktop.
Copy Pastable Example of Creating GCP SA for Google Container Registry Image Pull and Push
# This is a tutorial (how to guide optimized for learning)
# This is meant to be copy pasted line by line in bash
# A speed run of this method is available here:
# https://gist.github.com/neoakris/f1c4b329901811360ce6269ca631c80b
# Set Input Vars (likely need to edit)
export PROJECT=my-gcp-project
export SA_SHORT_NAME=gcr-sa
# Additional Input Vars (can skip editing)
export SA_NAME=$SA_SHORT_NAME@$PROJECT.iam.gserviceaccount.com
export SA_KEY_FILE=$HOME/Downloads/$SA_SHORT_NAME.auth.json
export TEST_IMAGE=gcr.io/$PROJECT/test
################################################################
# Prep work that will help make the full process easier to understand
# Login to your account with rights
gcloud auth login
# delete docker config for testability
mv $HOME/.docker/config.json $HOME/.docker/old-config.json
# Generate some test data
docker image pull busybox
docker image tag busybox "$TEST_IMAGE"1
docker image tag busybox "$TEST_IMAGE"2
docker image push "$TEST_IMAGE"1
# Unauthorized is expected, this is to improve testability
# Config docker as your admin user to upload test data
gcloud auth configure-docker
# Verify your human account can create an image
docker image push "$TEST_IMAGE"1
# delete docker config for testability
rm $HOME/.docker/config.json
################################################################
# Creating an SA with Image pull rights
# Create SA
gcloud iam service-accounts create $SA_SHORT_NAME --description="SA for GCR" --display-name="$SA_SHORT_NAME" --project=$PROJECT
# Create SA Auth Key in Downloads Folder
gcloud iam service-accounts keys create $SA_KEY_FILE --iam-account=$SA_NAME
# Add Image Pull rights
gcloud projects add-iam-policy-binding $PROJECT --member=serviceAccount:$SA_NAME --role=roles/containerregistry.ServiceAgent
# Verify Rights
gcloud projects get-iam-policy $PROJECT \
--flatten="bindings[].members" \
--format='table(bindings.role)' \
--filter="bindings.members:$SA_NAME"
# Login as the SA
gcloud auth activate-service-account $SA_NAME --key-file=$SA_KEY_FILE
# Config docker as your SA user
gcloud auth configure-docker
# Verify that SA can pull from but not push to gcr.io
docker image pull "$TEST_IMAGE"1
# ^-- pull successful
docker image push "$TEST_IMAGE"2
# ^-- push complains about permissions
###################################################################
# Adding Image Push rights to SA
# Logout of all accounts (human and service accounts)
gcloud auth revoke --all
rm $HOME/.docker/config.json
docker image pull "$TEST_IMAGE"1
# ^-- fails, which verifies that this requires authentication
# Login as human to add image push rights to SA
gcloud auth login
# Alternative method of docker login as the SA:
# (It allows us to be logged in as SA from docker perspective, but logged
# in as human from gcloud perspective, which makes testing easier.)
cat $SA_KEY_FILE | docker login -u _json_key --password-stdin https://gcr.io
# Confirm that we have the same access as SA from docker perspective
# but admin access from gcloud perspective
docker image pull "$TEST_IMAGE"1
# ^-- pull successful (expected for SA)
docker image push "$TEST_IMAGE"2
# ^-- push complains about permissions (expected for SA)
gcloud projects get-iam-policy $PROJECT \
--flatten="bindings[].members" \
--format='table(bindings.role)' \
--filter="bindings.members:$SA_NAME"
# Shows the SA has roles/containerregistry.ServiceAgent
# ^-- this is an admin operation which shows gcloud is using human user rights
# Add Image Push rights
gcloud projects add-iam-policy-binding $PROJECT --member=serviceAccount:$SA_NAME --role=roles/storage.admin
gcloud projects add-iam-policy-binding $PROJECT --member=serviceAccount:$SA_NAME --role=roles/storage.objectViewer
# Test that SA has image push rights
docker image push "$TEST_IMAGE"2
# Success
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment