When using GHA(Github Actions) for CI/CD purposes, the Github-hosted runners are free unless you use it quite a lot. But if I want to use GHA to build a docker container image and save it to my private repository in Google Artifact Registry, I have to grant the permission to some VMs I don’t even know where they are running from. So I would hesitate to load a JSON key of my Google service account to the runner VM.
Things are getting easier now, as the Workload Identity Federation is available for the use case. I followed this blog and got my setup working quickly, then I discovered it’s even quicker to do it with an existing terraform module:
service_accounts: github-runner: roles: - roles/artifactregistry.writer wif: {}
locals { workload_identity_pool = { for k, v in local.manifest.service_accounts : k => { sa_name = "projects/${var.project}/serviceAccounts/${k}@${var.project}.iam.gserviceaccount.com" attribute = try(v.wif.attribute, "*") } if can(v.wif) } } module "gh_oidc" { source = "terraform-google-modules/github-actions-runners/google//modules/gh-oidc" count = length(local.workload_identity_pool) > 0 ? 1 : 0 project_id = var.project pool_id = "github-wif-pool" provider_id = "github-wif-pool-provider" sa_mapping = local.workload_identity_pool } # the provider name will be needed in GHA workflow output "wif_provider_name" { value = try(module.gh_oidc[0].provider_name, "N/a") }
Then in the GHA workflow, only a few additional lines are needed to use this new authentication provider
name: My CI on: workflow_dispatch: push: branches: - 'master' jobs: build-docker: permissions: contents: 'read' id-token: 'write' # this is needed to write a new token runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 # this must be after checkout - id: 'auth' name: 'Authenticate to Google Cloud' uses: 'google-github-actions/auth@v1' with: workload_identity_provider: '<the provider name from the output of the terraform code above>' service_account: '[email protected]' token_format: access_token - name: Login to GCR uses: docker/login-action@v3 with: registry: asia.gcr.io username: oauth2accesstoken password: ${{ steps.auth.outputs.access_token }} # it's authenticated from now on, so do whatever docker build and push stuff that are needed.
I like this keyless approach 🙂