diff --git a/google/data_source_google_storage_project_service_account.go b/google/data_source_google_storage_project_service_account.go index 96543973..04fa4a43 100644 --- a/google/data_source_google_storage_project_service_account.go +++ b/google/data_source_google_storage_project_service_account.go @@ -14,6 +14,15 @@ func dataSourceGoogleStorageProjectServiceAccount() *schema.Resource { Optional: true, ForceNew: true, }, + "user_project": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "email_address": { + Type: schema.TypeString, + Computed: true, + }, }, } } @@ -26,12 +35,19 @@ func dataSourceGoogleStorageProjectServiceAccountRead(d *schema.ResourceData, me return err } - serviceAccount, err := config.clientStorage.Projects.ServiceAccount.Get(project).Do() + serviceAccountGetRequest := config.clientStorage.Projects.ServiceAccount.Get(project) + + if v, ok := d.GetOk("user_project"); ok { + serviceAccountGetRequest = serviceAccountGetRequest.UserProject(v.(string)) + } + + serviceAccount, err := serviceAccountGetRequest.Do() if err != nil { return handleNotFoundError(err, d, "GCS service account not found") } d.Set("project", project) + d.Set("email_address", serviceAccount.EmailAddress) d.SetId(serviceAccount.EmailAddress) diff --git a/google/data_source_google_storage_project_service_account_test.go b/google/data_source_google_storage_project_service_account_test.go index 57445531..bedbd735 100644 --- a/google/data_source_google_storage_project_service_account_test.go +++ b/google/data_source_google_storage_project_service_account_test.go @@ -18,7 +18,7 @@ func TestAccDataSourceGoogleStorageProjectServiceAccount_basic(t *testing.T) { { Config: testAccCheckGoogleStorageProjectServiceAccount_basic, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet(resourceName, "id"), + resource.TestCheckResourceAttrSet(resourceName, "email_address"), ), }, }, @@ -26,5 +26,6 @@ func TestAccDataSourceGoogleStorageProjectServiceAccount_basic(t *testing.T) { } const testAccCheckGoogleStorageProjectServiceAccount_basic = ` -data "google_storage_project_service_account" "gcs_account" { } +data "google_storage_project_service_account" "gcs_account" { +} ` diff --git a/google/resource_storage_notification_test.go b/google/resource_storage_notification_test.go index 810648a1..6a6b8f11 100644 --- a/google/resource_storage_notification_test.go +++ b/google/resource_storage_notification_test.go @@ -13,8 +13,7 @@ import ( ) var ( - gcsServiceAccount = fmt.Sprintf("serviceAccount:%s@gs-project-accounts.iam.gserviceaccount.com", os.Getenv("GOOGLE_PROJECT")) - payload = "JSON_API_V1" + payload = "JSON_API_V1" ) func TestAccStorageNotification_basic(t *testing.T) { @@ -185,14 +184,17 @@ resource "google_storage_bucket" "bucket" { resource "google_pubsub_topic" "topic" { name = "%s" } + // We have to provide GCS default storage account with the permission // to publish to a Cloud Pub/Sub topic from this project // Otherwise notification configuration won't work +data "google_storage_project_service_account" "gcs_account" {} + resource "google_pubsub_topic_iam_binding" "binding" { topic = "${google_pubsub_topic.topic.name}" role = "roles/pubsub.publisher" - members = ["%s"] + members = ["serviceAccount:${data.google_storage_project_service_account.gcs_account.email_address}"] } resource "google_storage_notification" "notification" { @@ -210,7 +212,7 @@ resource "google_storage_notification" "notification_with_prefix" { depends_on = ["google_pubsub_topic_iam_binding.binding"] } -`, bucketName, topicName, gcsServiceAccount) +`, bucketName, topicName) } func testGoogleStorageNotificationOptionalEventsAttributes(bucketName, topicName, topic, eventType1, eventType2 string) string { @@ -222,14 +224,17 @@ resource "google_storage_bucket" "bucket" { resource "google_pubsub_topic" "topic" { name = "%s" } + // We have to provide GCS default storage account with the permission // to publish to a Cloud Pub/Sub topic from this project // Otherwise notification configuration won't work +data "google_storage_project_service_account" "gcs_account" {} + resource "google_pubsub_topic_iam_binding" "binding" { topic = "${google_pubsub_topic.topic.name}" role = "roles/pubsub.publisher" - members = ["%s"] + members = ["serviceAccount:${data.google_storage_project_service_account.gcs_account.email_address}"] } resource "google_storage_notification" "notification" { @@ -243,5 +248,5 @@ resource "google_storage_notification" "notification" { depends_on = ["google_pubsub_topic_iam_binding.binding"] } -`, bucketName, topicName, gcsServiceAccount, eventType1, eventType2) +`, bucketName, topicName, eventType1, eventType2) } diff --git a/website/docs/d/google_storage_project_service_account.html.markdown b/website/docs/d/google_storage_project_service_account.html.markdown index 11f339b0..6c9bf86d 100644 --- a/website/docs/d/google_storage_project_service_account.html.markdown +++ b/website/docs/d/google_storage_project_service_account.html.markdown @@ -8,9 +8,13 @@ description: |- # google\_storage\_project\_service\_account -Use this data source to get the email address of the project's Google Cloud Storage service account. - For more information see -[API](https://cloud.google.com/storage/docs/json_api/v1/projects/serviceAccount). +Get the email address of a project's unique Google Cloud Storage service account. + +Each Google Cloud project has a unique service account for use with Google Cloud Storage. Only this +special service account can be used to set up `google_storage_notification` resources. + +For more information see +[the API reference](https://cloud.google.com/storage/docs/json_api/v1/projects/serviceAccount). ## Example Usage @@ -21,7 +25,7 @@ resource "google_pubsub_topic_iam_binding" "binding" { topic = "${google_pubsub_topic.topic.name}" role = "roles/pubsub.publisher" - members = ["${data.google_storage_project_service_account.gcs_account.id}"] + members = ["serviceAccount:${data.google_storage_project_service_account.gcs_account.email_address}"] } ``` @@ -29,10 +33,14 @@ resource "google_pubsub_topic_iam_binding" "binding" { The following arguments are supported: -* `project` - (Optional) The project in which the resource belongs. If it is not provided, the provider project is used. +* `project` - (Optional) The project the unique service account was created for. If it is not provided, the provider project is used. + +* `user_project` - (Optional) The project the lookup originates from. This field is used if you are making the request +from a different account than the one you are finding the service account for. ## Attributes Reference The following attributes are exported: -* `id` - The ID of the service account, which is its email address +* `email_address` - The email address of the service account. This value is often used to refer to the service account +in order to grant IAM permissions. diff --git a/website/docs/r/storage_notification.html.markdown b/website/docs/r/storage_notification.html.markdown index 6076e269..15985f29 100644 --- a/website/docs/r/storage_notification.html.markdown +++ b/website/docs/r/storage_notification.html.markdown @@ -14,29 +14,15 @@ Creates a new notification configuration on a specified bucket, establishing a f and [API](https://cloud.google.com/storage/docs/json_api/v1/notifications). +In order to enable notifications, a special Google Cloud Storage service account unique to the project +must have the IAM permission "projects.topics.publish" for a Cloud Pub/Sub topic in the project. To get the service +account's email address, use the `google_storage_project_service_account` datasource's `email_address` value, and see below +for an example of enabling notifications by granting the correct IAM permission. See +[the notifications documentation](https://cloud.google.com/storage/docs/gsutil/commands/notification) for more details. + ## Example Usage ```hcl -data "google_storage_project_service_account" "gs_account" {} - -resource "google_storage_bucket" "bucket" { - name = "default_bucket" -} - -resource "google_pubsub_topic" "topic" { - name = "default_topic" -} - -// In order to enable notifications, the Google Cloud Storage service account unique to each project -// must have the IAM permission "projects.topics.publish" to a Cloud Pub/Sub topic from this project. -// https://cloud.google.com/storage/docs/gsutil/commands/notification - -resource "google_pubsub_topic_iam_binding" "binding" { - topic = "${google_pubsub_topic.topic.name}" - role = "roles/pubsub.publisher" - members = ["serviceAccount:${data.google_storage_project_service_account.gs_account.id}"] -} - resource "google_storage_notification" "notification" { bucket = "${google_storage_bucket.bucket.name}" payload_format = "JSON_API_V1" @@ -47,6 +33,27 @@ resource "google_storage_notification" "notification" { } depends_on = ["google_pubsub_topic_iam_binding.binding"] } + +// Enable notifications by giving the correct IAM permission to the unique service account. + +data "google_storage_project_service_account" "gcs_account" {} + +resource "google_pubsub_topic_iam_binding" "binding" { + topic = "${google_pubsub_topic.topic.name}" + role = "roles/pubsub.publisher" + members = ["serviceAccount:${data.google_storage_project_service_account.gcs_account.email_address}"] +} + +// End enabling notifications + + +resource "google_storage_bucket" "bucket" { + name = "default_bucket" +} + +resource "google_pubsub_topic" "topic" { + name = "default_topic" +} ``` ## Argument Reference