buildlet: use a dedicated service account on GCE

buildlet should use a specific service account, allowing fine-grained
permission control that is different from the default service account
for whichever project they are run in.

Change-Id: I7a86308d6b65f370dfc49649ef10686d1d8b2974
Reviewed-on: https://go-review.googlesource.com/c/build/+/210958
Run-TryBot: Alexander Rakoczy <alex@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
diff --git a/buildenv/envs.go b/buildenv/envs.go
index f048485..89ba60b 100644
--- a/buildenv/envs.go
+++ b/buildenv/envs.go
@@ -126,6 +126,11 @@
 	// golang.org/x/crypto/acme/autocert (LetsEncrypt) cache.
 	// If empty, LetsEncrypt isn't used.
 	AutoCertCacheBucket string
+
+	// COSServiceAccount (Container Optimized OS) is the service
+	// account that will be assigned to a VM instance that hosts
+	// a container when the instance is created.
+	COSServiceAccount string
 }
 
 // ComputePrefix returns the URI prefix for Compute Engine resources in a project.
@@ -244,12 +249,13 @@
 		Name:        "go",
 		MachineType: "n1-standard-4",
 	},
-	DashURL:         "https://go-dashboard-dev.appspot.com/",
-	PerfDataURL:     "https://perfdata.golang.org",
-	CoordinatorName: "farmer",
-	BuildletBucket:  "dev-go-builder-data",
-	LogBucket:       "dev-go-build-log",
-	SnapBucket:      "dev-go-build-snap",
+	DashURL:           "https://go-dashboard-dev.appspot.com/",
+	PerfDataURL:       "https://perfdata.golang.org",
+	CoordinatorName:   "farmer",
+	BuildletBucket:    "dev-go-builder-data",
+	LogBucket:         "dev-go-build-log",
+	SnapBucket:        "dev-go-build-snap",
+	COSServiceAccount: "linux-cos-builders@go-dashboard-dev.iam.gserviceaccount.com",
 }
 
 // Production defines the environment that the coordinator and build
@@ -282,6 +288,7 @@
 	LogBucket:           "go-build-log",
 	SnapBucket:          "go-build-snap",
 	AutoCertCacheBucket: "farmer-golang-org-autocert-cache",
+	COSServiceAccount:   "linux-cos-builders@symbolic-datum-552.iam.gserviceaccount.com",
 }
 
 var Development = &Environment{
diff --git a/buildlet/gce.go b/buildlet/gce.go
index 417c481..e31b39e 100644
--- a/buildlet/gce.go
+++ b/buildlet/gce.go
@@ -195,16 +195,12 @@
 		Scheduling: &compute.Scheduling{Preemptible: false},
 	}
 
-	// Container builders use the COS image, which defaults to
-	// logging to Cloud Logging, which requires the default
-	// service account. So enable it when needed.
-	// TODO: reduce this scope in the future, when we go wild with IAM.
-	if hconf.IsContainer() {
+	// Container builders use the COS image, which defaults to logging to Cloud Logging.
+	// Permission is granted to this service account.
+	if hconf.IsContainer() && buildEnv.COSServiceAccount != "" {
 		instance.ServiceAccounts = []*compute.ServiceAccount{
 			{
-				// This funky email address is the
-				// "default service account" for GCE VMs:
-				Email:  fmt.Sprintf("%v-compute@developer.gserviceaccount.com", buildEnv.ProjectNumber),
+				Email:  buildEnv.COSServiceAccount,
 				Scopes: []string{compute.CloudPlatformScope},
 			},
 		}