Packer and GCP impersonation

Hi everybody,

I’m currently facing an issue using GCP impersonation in our Packer build pipeline.
This same GCP impersonation mechanism has been successfully put in practice in our Terraform provisioning pipeline.

Here are the IAM and service accounts details:

  1. service_account_high_privileges:
    • Owns all the permissions required to build a GCE image;
  2. service_account_impersonator:
    • Doesn’t own any permission;
    • Owns the role Service Account Token Creator in order to act on behalf of service_account_high_privileges;
    • A JSON key service_account_impersonator_key.json was generated.

My template.pkr.hcl is quite basic:

source "googlecompute" "my_image" {
  project_id                  = "my-project-id"
  zone                        = "europe-west1-b"
  ...
  impersonate_service_account = "service_account_high_privileges@my-project-id.iam.gserviceaccount.com"
  ...
  metadata = {
    enable-oslogin : "true"
  }
  use_os_login      = true
  ...
}

build {
  sources = ["sources.googlecompute.my_image"]

  provisioner "shell" {
    ...
  }
}

And when I try to start a new build with the path to the Google credentials, here’s what I get:

GOOGLE_APPLICATION_CREDENTIALS=/path/to/service_account_impersonator_key.json packer build template.pkr.hcl

googlecompute.my_image: output will be in this color.

==> googlecompute.my_image: Checking image does not exist...
==> googlecompute.my_image: Creating temporary RSA SSH key for instance...
==> googlecompute.my_image: Importing SSH public key for OSLogin...
==> googlecompute.my_image: Error obtaining token information needed for OSLogin: Post "https://www.googleapis.com/oauth2/v2/tokeninfo?alt=json&prettyPrint=false": impersonate: status code 403: {
==> googlecompute.my_image:   "error": {
==> googlecompute.my_image:     "code": 403,
==> googlecompute.my_image:     "message": "Request had insufficient authentication scopes.",
==> googlecompute.my_image:     "status": "PERMISSION_DENIED",
==> googlecompute.my_image:     "details": [
==> googlecompute.my_image:       {
==> googlecompute.my_image:         "@type": "type.googleapis.com/google.rpc.ErrorInfo",
==> googlecompute.my_image:         "reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT",
==> googlecompute.my_image:         "domain": "googleapis.com",
==> googlecompute.my_image:         "metadata": {
==> googlecompute.my_image:           "service": "iamcredentials.googleapis.com",
==> googlecompute.my_image:           "method": "google.iam.credentials.v1.IAMCredentials.GenerateAccessToken"
==> googlecompute.my_image:         }
==> googlecompute.my_image:       }
==> googlecompute.my_image:     ]
==> googlecompute.my_image:   }
==> googlecompute.my_image: }
==> googlecompute.my_image:
==> googlecompute.my_image: Deleting SSH public key for OSLogin...
==> googlecompute.my_image: Error deleting SSH public key for OSLogin. Please delete it manually.
==> googlecompute.my_image: 
==> googlecompute.my_image: Error: googleapi: Error 401: End user credentials not provided.
Build 'googlecompute.my_image' errored after 2 seconds 143 milliseconds: Error obtaining token information needed for OSLogin: Post "https://www.googleapis.com/oauth2/v2/tokeninfo?alt=json&prettyPrint=false": impersonate: status code 403: {
  "error": {
    "code": 403,
    "message": "Request had insufficient authentication scopes.",
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT",
        "domain": "googleapis.com",
        "metadata": {
          "service": "iamcredentials.googleapis.com",
          "method": "google.iam.credentials.v1.IAMCredentials.GenerateAccessToken"
        }
      }
    ]
  }
}

By reading this, I do understand that I miss something related to the credentials (End user credentials not provided / Request had insufficient authentication scopes) but I definitely don’t know what, why and where.

Any help would be greatly appreciated.

Thanks for all.

Regards,
Flavien

Hi,

I’ve finally found the root cause. It is just a misuse of Google impersonation mechanism in googlecompute Packer plugin: a deprecated Google API is being used. I quickly tested with the new API and it works like a charm.
I will submit a PR as soon as possible.

Flavien

Issue #83 raised.

Thanks for bubbling this up, and for opening up a PR with the fix. We will take a look to help get the fix merged.