The service account key can only be retrieved the first time the sa is created especially in case you did it via GCP console, it's a security mechanism. But it's not a big deal you can delete the old one and create a new one and that's it, the SA still remains the same, it's good to rotate keys.
In case you use IaC like GDM (Google Deployment Manager) or Terraform you can retrieve it as many times as you need.
For Terraform just configure the necessary output like this...
### Resources
resource "google_service_account" "my_service_account_name" {
account_id = "my-sa"
display_name = "my-sa"
description = "This is for descriptions"
}
resource "google_service_account_key" "my_service_account_key" {
service_account_id = google_service_account.my_service_account_name.name
}
### Outputs
output "my_service_account_key" {
description = "This is for descriptions (for single use)."
# sensitive = true # you can add sensitive to avoid showing it in plain text each time you run the code in case you don't need to retrieve it each time
value = base64decode(google_service_account_key.my_service_account_key.private_key)
}
For GDM, remember it's not anymore recommended from GCP to be used for IaC management, you can still retrieve it with the CLI describing the resource and adding a basic jq query for the sa key resource...
gcloud deployment-manager deployments describe my-gdm-deployment-name \
--project project-name \
--format json | jq -r '.outputs[] | select(.name==my-sa-key-resource-name") | .finalValue'| base64 --decode