diff --git a/builtin/providers/google/resource_google_project_services.go b/builtin/providers/google/resource_google_project_services.go index 84bcd95ad9..e284565937 100644 --- a/builtin/providers/google/resource_google_project_services.go +++ b/builtin/providers/google/resource_google_project_services.go @@ -31,6 +31,14 @@ func resourceGoogleProjectServices() *schema.Resource { } } +// These services can only be enabled as a side-effect of enabling other services, +// so don't bother storing them in the config or using them for diffing. +var ignore = map[string]struct{}{ + "containeranalysis.googleapis.com": struct{}{}, + "dataproc-control.googleapis.com": struct{}{}, + "source.googleapis.com": struct{}{}, +} + func resourceGoogleProjectServicesCreate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) pid := d.Get("project").(string) @@ -160,7 +168,9 @@ func getApiServices(pid string, config *Config) ([]string, error) { return apiServices, err } for _, v := range svcResp.Services { - apiServices = append(apiServices, v.ServiceName) + if _, ok := ignore[v.ServiceName]; !ok { + apiServices = append(apiServices, v.ServiceName) + } } return apiServices, nil } diff --git a/builtin/providers/google/resource_google_project_services_test.go b/builtin/providers/google/resource_google_project_services_test.go index dff073b285..155a297c73 100644 --- a/builtin/providers/google/resource_google_project_services_test.go +++ b/builtin/providers/google/resource_google_project_services_test.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "log" + "os" "reflect" "sort" "testing" @@ -123,6 +124,46 @@ func TestAccGoogleProjectServices_authoritative2(t *testing.T) { }) } +// Test that services that can't be enabled on their own (such as dataproc-control.googleapis.com) +// don't end up causing diffs when they are enabled as a side-effect of a different service's +// enablement. +func TestAccGoogleProjectServices_ignoreUnenablableServices(t *testing.T) { + skipIfEnvNotSet(t, + []string{ + "GOOGLE_ORG", + "GOOGLE_BILLING_ACCOUNT", + }..., + ) + + billingId := os.Getenv("GOOGLE_BILLING_ACCOUNT") + pid := "terraform-" + acctest.RandString(10) + services := []string{ + "dataproc.googleapis.com", + // The following services are enabled as a side-effect of dataproc's enablement + "storage-component.googleapis.com", + "deploymentmanager.googleapis.com", + "replicapool.googleapis.com", + "replicapoolupdater.googleapis.com", + "resourceviews.googleapis.com", + "compute-component.googleapis.com", + "container.googleapis.com", + "storage-api.googleapis.com", + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccGoogleProjectAssociateServicesBasic_withBilling(services, pid, pname, org, billingId), + Check: resource.ComposeTestCheckFunc( + testProjectServicesMatch(services, pid), + ), + }, + }, + }) +} + func testAccGoogleProjectAssociateServicesBasic(services []string, pid, name, org string) string { return fmt.Sprintf(` resource "google_project" "acceptance" { @@ -137,6 +178,21 @@ resource "google_project_services" "acceptance" { `, pid, name, org, testStringsToString(services)) } +func testAccGoogleProjectAssociateServicesBasic_withBilling(services []string, pid, name, org, billing string) string { + return fmt.Sprintf(` +resource "google_project" "acceptance" { + project_id = "%s" + name = "%s" + org_id = "%s" + billing_account = "%s" +} +resource "google_project_services" "acceptance" { + project = "${google_project.acceptance.project_id}" + services = [%s] +} +`, pid, name, org, billing, testStringsToString(services)) +} + func testProjectServicesMatch(services []string, pid string) resource.TestCheckFunc { return func(s *terraform.State) error { config := testAccProvider.Meta().(*Config)