0
votes

I have:

  • a service account
  • a GCE instance using that service account
  • a container image uploaded to GCR

I cannot seem to grant read-only GCR access to that instance. All resources are in the same project. I have tried granting the storage.admin and storage.objectViewer roles to the service account, and in each case accessing the container registry results in https://eu.gcr.io/v2/<project>/<image>/manifests/latest: 401 Unauthorized.

All documentation I've read says I need the storage-rw scope and storage.objectViewer granted on the bucket for GCR in that region, all of which I have.

I'm configuring all this with Terraform. How have you configured GCR access to a service account using Terraform?

Here's my code:

locals {
  gcr-region = "eu"
}

resource "google_service_account" "service_account" {
    account_id = "k3s-master"
    display_name = "k3s-master"
}

resource "google_project_iam_member" "project" {
  role    = "roles/logging.logWriter"
  member = "serviceAccount:${google_service_account.service_account.email}"
}

resource "google_compute_instance" "instance" {
    name = "${var.service_name}"
    machine_type = "f1-micro"

    allow_stopping_for_update = true

    service_account {
        email = "${google_service_account.service_account.email}"
        scopes = [
            "storage-rw",
      "https://www.googleapis.com/auth/cloud-platform",
      "https://www.googleapis.com/auth/compute",
        ]
    }

    boot_disk {
        initialize_params {
            image = "debian-9"
        }
    }

    network_interface {
        network = "${google_compute_network.k3s-network.self_link}"
        access_config { }
    }
}

resource "google_storage_bucket_iam_binding" "eu-binding" {
  bucket     = "eu.artifacts.${var.project}.appspot.com"
  role        = "roles/storage.objectViewer"

  members = [
    "serviceAccount:${google_service_account.service_account.email}",
  ]
}

resource "google_storage_bucket_iam_binding" "binding" {
  bucket     = "${var.project}.appspot.com"
  role        = "roles/storage.objectViewer"

  members = [
    "serviceAccount:${google_service_account.service_account.email}",
  ]
}
1

1 Answers

2
votes

Right, this turned out to be something else entirely.

To debug further I used curl and gsutil from the compute instance and found that I could access the underlying buckets.

I am running k3s on the instance involved and this needs to be explicitly configured to use the service account to authenticate to GCR (even though the compute instance is running under the same service account, this is still required).

Thus, a kubectl create secret docker-registry ... followed by setting imagePullSecrets for the (kubernetes) service account I'm using fixed it. More details about that here.