diff --git a/google-beta/iam_binary_authorization_attestor.go b/google-beta/iam_binary_authorization_attestor.go index b3433e6928..ed0746e680 100644 --- a/google-beta/iam_binary_authorization_attestor.go +++ b/google-beta/iam_binary_authorization_attestor.go @@ -159,7 +159,7 @@ func (u *BinaryAuthorizationAttestorIamUpdater) qualifyAttestorUrl(methodIdentif } func (u *BinaryAuthorizationAttestorIamUpdater) GetResourceId() string { - return fmt.Sprintf("%s/%s", u.project, u.attestor) + return fmt.Sprintf("projects/%s/attestors/%s", u.project, u.attestor) } func (u *BinaryAuthorizationAttestorIamUpdater) GetMutexKey() string { diff --git a/google-beta/iam_cloud_functions_cloud_function.go b/google-beta/iam_cloud_functions_cloud_function.go index b662a5f5e8..17782fadd7 100644 --- a/google-beta/iam_cloud_functions_cloud_function.go +++ b/google-beta/iam_cloud_functions_cloud_function.go @@ -179,7 +179,7 @@ func (u *CloudFunctionsCloudFunctionIamUpdater) qualifyCloudFunctionUrl(methodId } func (u *CloudFunctionsCloudFunctionIamUpdater) GetResourceId() string { - return fmt.Sprintf("%s/%s/%s", u.project, u.region, u.cloudFunction) + return fmt.Sprintf("projects/%s/locations/%s/functions/%s", u.project, u.region, u.cloudFunction) } func (u *CloudFunctionsCloudFunctionIamUpdater) GetMutexKey() string { diff --git a/google-beta/iam_compute_instance.go b/google-beta/iam_compute_instance.go index 0a6be8899c..c8ffb4fb5a 100644 --- a/google-beta/iam_compute_instance.go +++ b/google-beta/iam_compute_instance.go @@ -1,132 +1,176 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- package google import ( "fmt" - "strings" "github.com/hashicorp/errwrap" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "google.golang.org/api/cloudresourcemanager/v1" - "google.golang.org/api/compute/v1" ) -var IamComputeInstanceSchema = map[string]*schema.Schema{ - "instance_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - +var ComputeInstanceIamSchema = map[string]*schema.Schema{ "project": { Type: schema.TypeString, - Optional: true, Computed: true, + Optional: true, ForceNew: true, }, - "zone": { Type: schema.TypeString, - Optional: true, Computed: true, + Optional: true, ForceNew: true, }, + "instance_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + }, } type ComputeInstanceIamUpdater struct { - project string - zone string - resourceId string - Config *Config + project string + zone string + instanceName string + d *schema.ResourceData + Config *Config } -func NewComputeInstanceIamUpdater(d *schema.ResourceData, config *Config) (ResourceIamUpdater, error) { +func ComputeInstanceIamUpdaterProducer(d *schema.ResourceData, config *Config) (ResourceIamUpdater, error) { + values := make(map[string]string) + project, err := getProject(d, config) if err != nil { return nil, err } - + values["project"] = project zone, err := getZone(d, config) if err != nil { return nil, err } + values["zone"] = zone + if v, ok := d.GetOk("instance_name"); ok { + values["instance_name"] = v.(string) + } - return &ComputeInstanceIamUpdater{ - project: project, - zone: zone, - resourceId: d.Get("instance_name").(string), - Config: config, - }, nil + // We may have gotten either a long or short name, so attempt to parse long name if possible + m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/zones/(?P[^/]+)/instances/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Get("instance_name").(string)) + if err != nil { + return nil, err + } + + for k, v := range m { + values[k] = v + } + + u := &ComputeInstanceIamUpdater{ + project: values["project"], + zone: values["zone"], + instanceName: values["instance_name"], + d: d, + Config: config, + } + + d.Set("project", u.project) + d.Set("zone", u.zone) + d.Set("instance_name", u.GetResourceId()) + + return u, nil } func ComputeInstanceIdParseFunc(d *schema.ResourceData, config *Config) error { - parts := strings.Split(d.Id(), "/") - var fv *ZonalFieldValue - if len(parts) == 3 { - // {project}/{zone}/{name} syntax - fv = &ZonalFieldValue{ - Project: parts[0], - Zone: parts[1], - Name: parts[2], - resourceType: "instances", - } - } else if len(parts) == 2 { - // /{zone}/{name} syntax - project, err := getProject(d, config) - if err != nil { - return err - } - fv = &ZonalFieldValue{ - Project: project, - Zone: parts[0], - Name: parts[1], - resourceType: "instances", - } - } else { - // We either have a name or a full self link, so use the field helper - var err error - fv, err = ParseInstanceFieldValue(d.Id(), d, config) - if err != nil { - return err - } - } - - d.Set("project", fv.Project) - d.Set("zone", fv.Zone) - d.Set("instance_name", fv.Name) - - // Explicitly set the id so imported resources have the same ID format as non-imported ones. - d.SetId(fv.RelativeLink()) + values := make(map[string]string) + + project, err := getProject(d, config) + if err != nil { + return err + } + values["project"] = project + zone, err := getZone(d, config) + if err != nil { + return err + } + values["zone"] = zone + + m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/zones/(?P[^/]+)/instances/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Id()) + if err != nil { + return err + } + + for k, v := range m { + values[k] = v + } + + u := &ComputeInstanceIamUpdater{ + project: values["project"], + zone: values["zone"], + instanceName: values["instance_name"], + d: d, + Config: config, + } + d.Set("instance_name", u.GetResourceId()) + d.SetId(u.GetResourceId()) return nil } func (u *ComputeInstanceIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - p, err := u.Config.clientCompute.Instances.GetIamPolicy(u.project, u.zone, u.resourceId).Do() + url := u.qualifyInstanceUrl("getIamPolicy") + project, err := getProject(u.d, u.Config) if err != nil { - return nil, errwrap.Wrapf(fmt.Sprintf("Error retrieving IAM policy for %s: {{err}}", u.DescribeResource()), err) + return nil, err + } + var obj map[string]interface{} + url, err = addQueryParams(url, map[string]string{"optionsRequestedPolicyVersion": fmt.Sprintf("%d", iamPolicyVersion)}) + if err != nil { + return nil, err } - cloudResourcePolicy, err := computeToResourceManagerPolicy(p) + policy, err := sendRequest(u.Config, "GET", project, url, obj) + if err != nil { + return nil, errwrap.Wrapf(fmt.Sprintf("Error retrieving IAM policy for %s: {{err}}", u.DescribeResource()), err) + } + out := &cloudresourcemanager.Policy{} + err = Convert(policy, out) if err != nil { - return nil, errwrap.Wrapf(fmt.Sprintf("Invalid IAM policy for %s: {{err}}", u.DescribeResource()), err) + return nil, errwrap.Wrapf("Cannot convert a policy to a resource manager policy: {{err}}", err) } - return cloudResourcePolicy, nil + return out, nil } func (u *ComputeInstanceIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Policy) error { - computePolicy, err := resourceManagerToComputePolicy(policy) - + json, err := ConvertToMap(policy) if err != nil { - return errwrap.Wrapf(fmt.Sprintf("Invalid IAM policy for %s: {{err}}", u.DescribeResource()), err) + return err } - req := &compute.ZoneSetPolicyRequest{ - Policy: computePolicy, + obj := make(map[string]interface{}) + obj["policy"] = json + + url := u.qualifyInstanceUrl("setIamPolicy") + + project, err := getProject(u.d, u.Config) + if err != nil { + return err } - _, err = u.Config.clientCompute.Instances.SetIamPolicy(u.project, u.zone, u.resourceId, req).Do() + _, err = sendRequestWithTimeout(u.Config, "POST", project, url, obj, u.d.Timeout(schema.TimeoutCreate)) if err != nil { return errwrap.Wrapf(fmt.Sprintf("Error setting IAM policy for %s: {{err}}", u.DescribeResource()), err) } @@ -134,14 +178,18 @@ func (u *ComputeInstanceIamUpdater) SetResourceIamPolicy(policy *cloudresourcema return nil } +func (u *ComputeInstanceIamUpdater) qualifyInstanceUrl(methodIdentifier string) string { + return fmt.Sprintf("https://www.googleapis.com/compute/beta/%s/%s", fmt.Sprintf("projects/%s/zones/%s/instances/%s", u.project, u.zone, u.instanceName), methodIdentifier) +} + func (u *ComputeInstanceIamUpdater) GetResourceId() string { - return fmt.Sprintf("projects/%s/zones/%s/instances/%s", u.project, u.zone, u.resourceId) + return fmt.Sprintf("projects/%s/zones/%s/instances/%s", u.project, u.zone, u.instanceName) } func (u *ComputeInstanceIamUpdater) GetMutexKey() string { - return fmt.Sprintf("iam-compute-Instance-%s-%s-%s", u.project, u.zone, u.resourceId) + return fmt.Sprintf("iam-compute-instance-%s", u.GetResourceId()) } func (u *ComputeInstanceIamUpdater) DescribeResource() string { - return fmt.Sprintf("Compute Instance %s/%s/%s", u.project, u.zone, u.resourceId) + return fmt.Sprintf("compute instance %q", u.GetResourceId()) } diff --git a/google-beta/iam_compute_instance_generated_test.go b/google-beta/iam_compute_instance_generated_test.go new file mode 100644 index 0000000000..c14b5b0ea0 --- /dev/null +++ b/google-beta/iam_compute_instance_generated_test.go @@ -0,0 +1,567 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccComputeInstanceIamBindingGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/compute.osLogin", + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccComputeInstanceIamBinding_basicGenerated(context), + }, + { + ResourceName: "google_compute_instance_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/zones/%s/instances/%s roles/compute.osLogin", getTestProjectFromEnv(), getTestZoneFromEnv(), fmt.Sprintf("my-instance%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + { + // Test Iam Binding update + Config: testAccComputeInstanceIamBinding_updateGenerated(context), + }, + { + ResourceName: "google_compute_instance_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/zones/%s/instances/%s roles/compute.osLogin", getTestProjectFromEnv(), getTestZoneFromEnv(), fmt.Sprintf("my-instance%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccComputeInstanceIamMemberGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/compute.osLogin", + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + // Test Iam Member creation (no update for member, no need to test) + Config: testAccComputeInstanceIamMember_basicGenerated(context), + }, + { + ResourceName: "google_compute_instance_iam_member.foo", + ImportStateId: fmt.Sprintf("projects/%s/zones/%s/instances/%s roles/compute.osLogin user:admin@hashicorptest.com", getTestProjectFromEnv(), getTestZoneFromEnv(), fmt.Sprintf("my-instance%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccComputeInstanceIamPolicyGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/compute.osLogin", + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccComputeInstanceIamPolicy_basicGenerated(context), + }, + { + ResourceName: "google_compute_instance_iam_policy.foo", + ImportStateId: fmt.Sprintf("projects/%s/zones/%s/instances/%s", getTestProjectFromEnv(), getTestZoneFromEnv(), fmt.Sprintf("my-instance%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccComputeInstanceIamBindingGenerated_withCondition(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/compute.osLogin", + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccComputeInstanceIamBinding_withConditionGenerated(context), + }, + { + ResourceName: "google_compute_instance_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/zones/%s/instances/%s roles/compute.osLogin %s", getTestProjectFromEnv(), getTestZoneFromEnv(), fmt.Sprintf("my-instance%s", context["random_suffix"]), context["condition_title"]), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccComputeInstanceIamBindingGenerated_withAndWithoutCondition(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/compute.osLogin", + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccComputeInstanceIamBinding_withAndWithoutConditionGenerated(context), + }, + { + ResourceName: "google_compute_instance_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/zones/%s/instances/%s roles/compute.osLogin", getTestProjectFromEnv(), getTestZoneFromEnv(), fmt.Sprintf("my-instance%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + { + ResourceName: "google_compute_instance_iam_binding.foo2", + ImportStateId: fmt.Sprintf("projects/%s/zones/%s/instances/%s roles/compute.osLogin %s", getTestProjectFromEnv(), getTestZoneFromEnv(), fmt.Sprintf("my-instance%s", context["random_suffix"]), context["condition_title"]), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccComputeInstanceIamMemberGenerated_withCondition(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/compute.osLogin", + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccComputeInstanceIamMember_withConditionGenerated(context), + }, + { + ResourceName: "google_compute_instance_iam_member.foo", + ImportStateId: fmt.Sprintf("projects/%s/zones/%s/instances/%s roles/compute.osLogin user:admin@hashicorptest.com %s", getTestProjectFromEnv(), getTestZoneFromEnv(), fmt.Sprintf("my-instance%s", context["random_suffix"]), context["condition_title"]), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccComputeInstanceIamMemberGenerated_withAndWithoutCondition(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/compute.osLogin", + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccComputeInstanceIamMember_withAndWithoutConditionGenerated(context), + }, + { + ResourceName: "google_compute_instance_iam_member.foo", + ImportStateId: fmt.Sprintf("projects/%s/zones/%s/instances/%s roles/compute.osLogin user:admin@hashicorptest.com", getTestProjectFromEnv(), getTestZoneFromEnv(), fmt.Sprintf("my-instance%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + { + ResourceName: "google_compute_instance_iam_member.foo2", + ImportStateId: fmt.Sprintf("projects/%s/zones/%s/instances/%s roles/compute.osLogin user:admin@hashicorptest.com %s", getTestProjectFromEnv(), getTestZoneFromEnv(), fmt.Sprintf("my-instance%s", context["random_suffix"]), context["condition_title"]), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccComputeInstanceIamPolicyGenerated_withCondition(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/compute.osLogin", + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccComputeInstanceIamPolicy_withConditionGenerated(context), + }, + { + ResourceName: "google_compute_instance_iam_policy.foo", + ImportStateId: fmt.Sprintf("projects/%s/zones/%s/instances/%s", getTestProjectFromEnv(), getTestZoneFromEnv(), fmt.Sprintf("my-instance%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccComputeInstanceIamMember_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_instance" "default" { + name = "my-instance%{random_suffix}" + zone = "" + machine_type = "n1-standard-1" + + boot_disk { + initialize_params { + image = "debian-cloud/debian-9" + } + } + + network_interface { + network = "default" + } +} + +resource "google_compute_instance_iam_member" "foo" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + role = "%{role}" + member = "user:admin@hashicorptest.com" +} +`, context) +} + +func testAccComputeInstanceIamPolicy_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_instance" "default" { + name = "my-instance%{random_suffix}" + zone = "" + machine_type = "n1-standard-1" + + boot_disk { + initialize_params { + image = "debian-cloud/debian-9" + } + } + + network_interface { + network = "default" + } +} + +data "google_iam_policy" "foo" { + binding { + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + } +} + +resource "google_compute_instance_iam_policy" "foo" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + policy_data = "${data.google_iam_policy.foo.policy_data}" +} +`, context) +} + +func testAccComputeInstanceIamBinding_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_instance" "default" { + name = "my-instance%{random_suffix}" + zone = "" + machine_type = "n1-standard-1" + + boot_disk { + initialize_params { + image = "debian-cloud/debian-9" + } + } + + network_interface { + network = "default" + } +} + +resource "google_compute_instance_iam_binding" "foo" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + role = "%{role}" + members = ["user:admin@hashicorptest.com"] +} +`, context) +} + +func testAccComputeInstanceIamBinding_updateGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_instance" "default" { + name = "my-instance%{random_suffix}" + zone = "" + machine_type = "n1-standard-1" + + boot_disk { + initialize_params { + image = "debian-cloud/debian-9" + } + } + + network_interface { + network = "default" + } +} + +resource "google_compute_instance_iam_binding" "foo" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + role = "%{role}" + members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"] +} +`, context) +} + +func testAccComputeInstanceIamBinding_withConditionGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_instance" "default" { + name = "my-instance%{random_suffix}" + zone = "" + machine_type = "n1-standard-1" + + boot_disk { + initialize_params { + image = "debian-cloud/debian-9" + } + } + + network_interface { + network = "default" + } +} + +resource "google_compute_instance_iam_binding" "foo" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + condition { + title = "%{condition_title}" + description = "Expiring at midnight of 2019-12-31" + expression = "%{condition_expr}" + } +} +`, context) +} + +func testAccComputeInstanceIamBinding_withAndWithoutConditionGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_instance" "default" { + name = "my-instance%{random_suffix}" + zone = "" + machine_type = "n1-standard-1" + + boot_disk { + initialize_params { + image = "debian-cloud/debian-9" + } + } + + network_interface { + network = "default" + } +} + +resource "google_compute_instance_iam_binding" "foo" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + role = "%{role}" + members = ["user:admin@hashicorptest.com"] +} + +resource "google_compute_instance_iam_binding" "foo2" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + condition { + title = "%{condition_title}" + description = "Expiring at midnight of 2019-12-31" + expression = "%{condition_expr}" + } +} +`, context) +} + +func testAccComputeInstanceIamMember_withConditionGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_instance" "default" { + name = "my-instance%{random_suffix}" + zone = "" + machine_type = "n1-standard-1" + + boot_disk { + initialize_params { + image = "debian-cloud/debian-9" + } + } + + network_interface { + network = "default" + } +} + +resource "google_compute_instance_iam_member" "foo" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + role = "%{role}" + member = "user:admin@hashicorptest.com" + condition { + title = "%{condition_title}" + description = "Expiring at midnight of 2019-12-31" + expression = "%{condition_expr}" + } +} +`, context) +} + +func testAccComputeInstanceIamMember_withAndWithoutConditionGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_instance" "default" { + name = "my-instance%{random_suffix}" + zone = "" + machine_type = "n1-standard-1" + + boot_disk { + initialize_params { + image = "debian-cloud/debian-9" + } + } + + network_interface { + network = "default" + } +} + +resource "google_compute_instance_iam_member" "foo" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + role = "%{role}" + member = "user:admin@hashicorptest.com" +} + +resource "google_compute_instance_iam_member" "foo2" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + role = "%{role}" + member = "user:admin@hashicorptest.com" + condition { + title = "%{condition_title}" + description = "Expiring at midnight of 2019-12-31" + expression = "%{condition_expr}" + } +} +`, context) +} + +func testAccComputeInstanceIamPolicy_withConditionGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_instance" "default" { + name = "my-instance%{random_suffix}" + zone = "" + machine_type = "n1-standard-1" + + boot_disk { + initialize_params { + image = "debian-cloud/debian-9" + } + } + + network_interface { + network = "default" + } +} + +data "google_iam_policy" "foo" { + binding { + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + condition { + title = "%{condition_title}" + description = "Expiring at midnight of 2019-12-31" + expression = "%{condition_expr}" + } + } +} + +resource "google_compute_instance_iam_policy" "foo" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + policy_data = "${data.google_iam_policy.foo.policy_data}" +} +`, context) +} diff --git a/google-beta/iam_compute_subnetwork.go b/google-beta/iam_compute_subnetwork.go index 2bbd0a5aeb..fcfafde6e4 100644 --- a/google-beta/iam_compute_subnetwork.go +++ b/google-beta/iam_compute_subnetwork.go @@ -1,131 +1,172 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- package google import ( "fmt" - "strings" "github.com/hashicorp/errwrap" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "google.golang.org/api/cloudresourcemanager/v1" - "google.golang.org/api/compute/v1" ) -var IamComputeSubnetworkSchema = map[string]*schema.Schema{ - "subnetwork": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - +var ComputeSubnetworkIamSchema = map[string]*schema.Schema{ "project": { Type: schema.TypeString, - Optional: true, Computed: true, + Optional: true, ForceNew: true, }, - "region": { Type: schema.TypeString, - Optional: true, Computed: true, + Optional: true, ForceNew: true, }, + "subnetwork": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + }, } type ComputeSubnetworkIamUpdater struct { project string region string - resourceId string + subnetwork string + d *schema.ResourceData Config *Config } -func NewComputeSubnetworkIamUpdater(d *schema.ResourceData, config *Config) (ResourceIamUpdater, error) { +func ComputeSubnetworkIamUpdaterProducer(d *schema.ResourceData, config *Config) (ResourceIamUpdater, error) { + values := make(map[string]string) + project, err := getProject(d, config) if err != nil { return nil, err } - + values["project"] = project region, err := getRegion(d, config) if err != nil { return nil, err } + values["region"] = region + if v, ok := d.GetOk("subnetwork"); ok { + values["subnetwork"] = v.(string) + } + + // We may have gotten either a long or short name, so attempt to parse long name if possible + m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/regions/(?P[^/]+)/subnetworks/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Get("subnetwork").(string)) + if err != nil { + return nil, err + } + + for k, v := range m { + values[k] = v + } - return &ComputeSubnetworkIamUpdater{ - project: project, - region: region, - resourceId: d.Get("subnetwork").(string), + u := &ComputeSubnetworkIamUpdater{ + project: values["project"], + region: values["region"], + subnetwork: values["subnetwork"], + d: d, Config: config, - }, nil + } + + d.Set("project", u.project) + d.Set("region", u.region) + d.Set("subnetwork", u.GetResourceId()) + + return u, nil } func ComputeSubnetworkIdParseFunc(d *schema.ResourceData, config *Config) error { - parts := strings.Split(d.Id(), "/") - var fv *RegionalFieldValue - if len(parts) == 3 { - // {project}/{region}/{name} syntax - fv = &RegionalFieldValue{ - Project: parts[0], - Region: parts[1], - Name: parts[2], - resourceType: "subnetworks", - } - } else if len(parts) == 2 { - // /{region}/{name} syntax - project, err := getProject(d, config) - if err != nil { - return err - } - fv = &RegionalFieldValue{ - Project: project, - Region: parts[0], - Name: parts[1], - resourceType: "subnetworks", - } - } else { - // We either have a name or a full self link, so use the field helper - var err error - fv, err = ParseSubnetworkFieldValue(d.Id(), d, config) - if err != nil { - return err - } - } - d.Set("subnetwork", fv.Name) - d.Set("project", fv.Project) - d.Set("region", fv.Region) - - // Explicitly set the id so imported resources have the same ID format as non-imported ones. - d.SetId(fv.RelativeLink()) + values := make(map[string]string) + + project, err := getProject(d, config) + if err != nil { + return err + } + values["project"] = project + region, err := getRegion(d, config) + if err != nil { + return err + } + values["region"] = region + + m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/regions/(?P[^/]+)/subnetworks/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Id()) + if err != nil { + return err + } + + for k, v := range m { + values[k] = v + } + + u := &ComputeSubnetworkIamUpdater{ + project: values["project"], + region: values["region"], + subnetwork: values["subnetwork"], + d: d, + Config: config, + } + d.Set("subnetwork", u.GetResourceId()) + d.SetId(u.GetResourceId()) return nil } func (u *ComputeSubnetworkIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - p, err := u.Config.clientCompute.Subnetworks.GetIamPolicy(u.project, u.region, u.resourceId).Do() + url := u.qualifySubnetworkUrl("getIamPolicy") + project, err := getProject(u.d, u.Config) if err != nil { - return nil, errwrap.Wrapf(fmt.Sprintf("Error retrieving IAM policy for %s: {{err}}", u.DescribeResource()), err) + return nil, err } + var obj map[string]interface{} - cloudResourcePolicy, err := computeToResourceManagerPolicy(p) + policy, err := sendRequest(u.Config, "GET", project, url, obj) + if err != nil { + return nil, errwrap.Wrapf(fmt.Sprintf("Error retrieving IAM policy for %s: {{err}}", u.DescribeResource()), err) + } + out := &cloudresourcemanager.Policy{} + err = Convert(policy, out) if err != nil { - return nil, errwrap.Wrapf(fmt.Sprintf("Invalid IAM policy for %s: {{err}}", u.DescribeResource()), err) + return nil, errwrap.Wrapf("Cannot convert a policy to a resource manager policy: {{err}}", err) } - return cloudResourcePolicy, nil + return out, nil } func (u *ComputeSubnetworkIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Policy) error { - computePolicy, err := resourceManagerToComputePolicy(policy) - + json, err := ConvertToMap(policy) if err != nil { - return errwrap.Wrapf(fmt.Sprintf("Invalid IAM policy for %s: {{err}}", u.DescribeResource()), err) + return err } - req := &compute.RegionSetPolicyRequest{ - Policy: computePolicy, + obj := make(map[string]interface{}) + obj["policy"] = json + + url := u.qualifySubnetworkUrl("setIamPolicy") + + project, err := getProject(u.d, u.Config) + if err != nil { + return err } - _, err = u.Config.clientCompute.Subnetworks.SetIamPolicy(u.project, u.region, u.resourceId, req).Do() + _, err = sendRequestWithTimeout(u.Config, "POST", project, url, obj, u.d.Timeout(schema.TimeoutCreate)) if err != nil { return errwrap.Wrapf(fmt.Sprintf("Error setting IAM policy for %s: {{err}}", u.DescribeResource()), err) } @@ -133,32 +174,18 @@ func (u *ComputeSubnetworkIamUpdater) SetResourceIamPolicy(policy *cloudresource return nil } +func (u *ComputeSubnetworkIamUpdater) qualifySubnetworkUrl(methodIdentifier string) string { + return fmt.Sprintf("https://www.googleapis.com/compute/beta/%s/%s", fmt.Sprintf("projects/%s/regions/%s/subnetworks/%s", u.project, u.region, u.subnetwork), methodIdentifier) +} + func (u *ComputeSubnetworkIamUpdater) GetResourceId() string { - return fmt.Sprintf("projects/%s/regions/%s/subnetworks/%s", u.project, u.region, u.resourceId) + return fmt.Sprintf("projects/%s/regions/%s/subnetworks/%s", u.project, u.region, u.subnetwork) } func (u *ComputeSubnetworkIamUpdater) GetMutexKey() string { - return fmt.Sprintf("iam-compute-subnetwork-%s-%s-%s", u.project, u.region, u.resourceId) + return fmt.Sprintf("iam-compute-subnetwork-%s", u.GetResourceId()) } func (u *ComputeSubnetworkIamUpdater) DescribeResource() string { - return fmt.Sprintf("Compute Subnetwork %s/%s/%s", u.project, u.region, u.resourceId) -} - -func resourceManagerToComputePolicy(p *cloudresourcemanager.Policy) (*compute.Policy, error) { - out := &compute.Policy{} - err := Convert(p, out) - if err != nil { - return nil, errwrap.Wrapf("Cannot convert a resourcemanager policy to a compute policy: {{err}}", err) - } - return out, nil -} - -func computeToResourceManagerPolicy(p *compute.Policy) (*cloudresourcemanager.Policy, error) { - out := &cloudresourcemanager.Policy{} - err := Convert(p, out) - if err != nil { - return nil, errwrap.Wrapf("Cannot convert a compute policy to a resourcemanager policy: {{err}}", err) - } - return out, nil + return fmt.Sprintf("compute subnetwork %q", u.GetResourceId()) } diff --git a/google-beta/iam_compute_subnetwork_generated_test.go b/google-beta/iam_compute_subnetwork_generated_test.go new file mode 100644 index 0000000000..b18ac373f8 --- /dev/null +++ b/google-beta/iam_compute_subnetwork_generated_test.go @@ -0,0 +1,227 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccComputeSubnetworkIamBindingGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/compute.networkUser", + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccComputeSubnetworkIamBinding_basicGenerated(context), + }, + { + ResourceName: "google_compute_subnetwork_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/regions/%s/subnetworks/%s roles/compute.networkUser", getTestProjectFromEnv(), getTestRegionFromEnv(), fmt.Sprintf("test-subnetwork%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + { + // Test Iam Binding update + Config: testAccComputeSubnetworkIamBinding_updateGenerated(context), + }, + { + ResourceName: "google_compute_subnetwork_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/regions/%s/subnetworks/%s roles/compute.networkUser", getTestProjectFromEnv(), getTestRegionFromEnv(), fmt.Sprintf("test-subnetwork%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccComputeSubnetworkIamMemberGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/compute.networkUser", + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + // Test Iam Member creation (no update for member, no need to test) + Config: testAccComputeSubnetworkIamMember_basicGenerated(context), + }, + { + ResourceName: "google_compute_subnetwork_iam_member.foo", + ImportStateId: fmt.Sprintf("projects/%s/regions/%s/subnetworks/%s roles/compute.networkUser user:admin@hashicorptest.com", getTestProjectFromEnv(), getTestRegionFromEnv(), fmt.Sprintf("test-subnetwork%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccComputeSubnetworkIamPolicyGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/compute.networkUser", + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccComputeSubnetworkIamPolicy_basicGenerated(context), + }, + { + ResourceName: "google_compute_subnetwork_iam_policy.foo", + ImportStateId: fmt.Sprintf("projects/%s/regions/%s/subnetworks/%s", getTestProjectFromEnv(), getTestRegionFromEnv(), fmt.Sprintf("test-subnetwork%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccComputeSubnetworkIamMember_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_subnetwork" "network-with-private-secondary-ip-ranges" { + name = "test-subnetwork%{random_suffix}" + ip_cidr_range = "10.2.0.0/16" + region = "us-central1" + network = "${google_compute_network.custom-test.self_link}" + secondary_ip_range { + range_name = "tf-test-secondary-range-update1" + ip_cidr_range = "192.168.10.0/24" + } +} + +resource "google_compute_network" "custom-test" { + name = "test-network%{random_suffix}" + auto_create_subnetworks = false +} + +resource "google_compute_subnetwork_iam_member" "foo" { + project = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.project}" + region = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.region}" + subnetwork = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.name}" + role = "%{role}" + member = "user:admin@hashicorptest.com" +} +`, context) +} + +func testAccComputeSubnetworkIamPolicy_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_subnetwork" "network-with-private-secondary-ip-ranges" { + name = "test-subnetwork%{random_suffix}" + ip_cidr_range = "10.2.0.0/16" + region = "us-central1" + network = "${google_compute_network.custom-test.self_link}" + secondary_ip_range { + range_name = "tf-test-secondary-range-update1" + ip_cidr_range = "192.168.10.0/24" + } +} + +resource "google_compute_network" "custom-test" { + name = "test-network%{random_suffix}" + auto_create_subnetworks = false +} + +data "google_iam_policy" "foo" { + binding { + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + } +} + +resource "google_compute_subnetwork_iam_policy" "foo" { + project = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.project}" + region = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.region}" + subnetwork = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.name}" + policy_data = "${data.google_iam_policy.foo.policy_data}" +} +`, context) +} + +func testAccComputeSubnetworkIamBinding_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_subnetwork" "network-with-private-secondary-ip-ranges" { + name = "test-subnetwork%{random_suffix}" + ip_cidr_range = "10.2.0.0/16" + region = "us-central1" + network = "${google_compute_network.custom-test.self_link}" + secondary_ip_range { + range_name = "tf-test-secondary-range-update1" + ip_cidr_range = "192.168.10.0/24" + } +} + +resource "google_compute_network" "custom-test" { + name = "test-network%{random_suffix}" + auto_create_subnetworks = false +} + +resource "google_compute_subnetwork_iam_binding" "foo" { + project = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.project}" + region = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.region}" + subnetwork = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.name}" + role = "%{role}" + members = ["user:admin@hashicorptest.com"] +} +`, context) +} + +func testAccComputeSubnetworkIamBinding_updateGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_subnetwork" "network-with-private-secondary-ip-ranges" { + name = "test-subnetwork%{random_suffix}" + ip_cidr_range = "10.2.0.0/16" + region = "us-central1" + network = "${google_compute_network.custom-test.self_link}" + secondary_ip_range { + range_name = "tf-test-secondary-range-update1" + ip_cidr_range = "192.168.10.0/24" + } +} + +resource "google_compute_network" "custom-test" { + name = "test-network%{random_suffix}" + auto_create_subnetworks = false +} + +resource "google_compute_subnetwork_iam_binding" "foo" { + project = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.project}" + region = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.region}" + subnetwork = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.name}" + role = "%{role}" + members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"] +} +`, context) +} diff --git a/google-beta/iam_source_repo_repository.go b/google-beta/iam_source_repo_repository.go index 8ed6c08863..d62ae4c488 100644 --- a/google-beta/iam_source_repo_repository.go +++ b/google-beta/iam_source_repo_repository.go @@ -159,7 +159,7 @@ func (u *SourceRepoRepositoryIamUpdater) qualifyRepositoryUrl(methodIdentifier s } func (u *SourceRepoRepositoryIamUpdater) GetResourceId() string { - return fmt.Sprintf("%s/%s", u.project, u.repository) + return fmt.Sprintf("projects/%s/repos/%s", u.project, u.repository) } func (u *SourceRepoRepositoryIamUpdater) GetMutexKey() string { diff --git a/google-beta/provider.go b/google-beta/provider.go index 37a15347c1..88bf7ecf5c 100644 --- a/google-beta/provider.go +++ b/google-beta/provider.go @@ -483,8 +483,8 @@ func Provider() terraform.ResourceProvider { } // Generated resources: 100 -// Generated IAM resources: 33 -// Total generated resources: 133 +// Generated IAM resources: 39 +// Total generated resources: 139 func ResourceMap() map[string]*schema.Resource { resourceMap, _ := ResourceMapWithErrors() return resourceMap @@ -532,6 +532,9 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_compute_https_health_check": resourceComputeHttpsHealthCheck(), "google_compute_health_check": resourceComputeHealthCheck(), "google_compute_image": resourceComputeImage(), + "google_compute_instance_iam_binding": ResourceIamBinding(ComputeInstanceIamSchema, ComputeInstanceIamUpdaterProducer, ComputeInstanceIdParseFunc), + "google_compute_instance_iam_member": ResourceIamMember(ComputeInstanceIamSchema, ComputeInstanceIamUpdaterProducer, ComputeInstanceIdParseFunc), + "google_compute_instance_iam_policy": ResourceIamPolicy(ComputeInstanceIamSchema, ComputeInstanceIamUpdaterProducer, ComputeInstanceIdParseFunc), "google_compute_interconnect_attachment": resourceComputeInterconnectAttachment(), "google_compute_network": resourceComputeNetwork(), "google_compute_network_endpoint": resourceComputeNetworkEndpoint(), @@ -553,6 +556,9 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_compute_reservation": resourceComputeReservation(), "google_compute_ssl_policy": resourceComputeSslPolicy(), "google_compute_subnetwork": resourceComputeSubnetwork(), + "google_compute_subnetwork_iam_binding": ResourceIamBinding(ComputeSubnetworkIamSchema, ComputeSubnetworkIamUpdaterProducer, ComputeSubnetworkIdParseFunc), + "google_compute_subnetwork_iam_member": ResourceIamMember(ComputeSubnetworkIamSchema, ComputeSubnetworkIamUpdaterProducer, ComputeSubnetworkIdParseFunc), + "google_compute_subnetwork_iam_policy": ResourceIamPolicy(ComputeSubnetworkIamSchema, ComputeSubnetworkIamUpdaterProducer, ComputeSubnetworkIdParseFunc), "google_compute_target_http_proxy": resourceComputeTargetHttpProxy(), "google_compute_target_https_proxy": resourceComputeTargetHttpsProxy(), "google_compute_region_target_http_proxy": resourceComputeRegionTargetHttpProxy(), @@ -647,9 +653,6 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_compute_instance_from_template": resourceComputeInstanceFromTemplate(), "google_compute_instance_group": resourceComputeInstanceGroup(), "google_compute_instance_group_manager": resourceComputeInstanceGroupManager(), - "google_compute_instance_iam_binding": ResourceIamBinding(IamComputeInstanceSchema, NewComputeInstanceIamUpdater, ComputeInstanceIdParseFunc), - "google_compute_instance_iam_member": ResourceIamMember(IamComputeInstanceSchema, NewComputeInstanceIamUpdater, ComputeInstanceIdParseFunc), - "google_compute_instance_iam_policy": ResourceIamPolicy(IamComputeInstanceSchema, NewComputeInstanceIamUpdater, ComputeInstanceIdParseFunc), "google_compute_instance_template": resourceComputeInstanceTemplate(), "google_compute_network_peering": resourceComputeNetworkPeering(), "google_compute_project_default_network_tier": resourceComputeProjectDefaultNetworkTier(), @@ -661,9 +664,6 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_compute_security_policy": resourceComputeSecurityPolicy(), "google_compute_shared_vpc_host_project": resourceComputeSharedVpcHostProject(), "google_compute_shared_vpc_service_project": resourceComputeSharedVpcServiceProject(), - "google_compute_subnetwork_iam_binding": ResourceIamBinding(IamComputeSubnetworkSchema, NewComputeSubnetworkIamUpdater, ComputeSubnetworkIdParseFunc), - "google_compute_subnetwork_iam_member": ResourceIamMember(IamComputeSubnetworkSchema, NewComputeSubnetworkIamUpdater, ComputeSubnetworkIdParseFunc), - "google_compute_subnetwork_iam_policy": ResourceIamPolicy(IamComputeSubnetworkSchema, NewComputeSubnetworkIamUpdater, ComputeSubnetworkIdParseFunc), "google_compute_target_pool": resourceComputeTargetPool(), "google_container_cluster": resourceContainerCluster(), "google_container_node_pool": resourceContainerNodePool(), diff --git a/google-beta/resource_compute_instance_iam_test.go b/google-beta/resource_compute_instance_iam_test.go index cadd44c5f3..98f4002a09 100644 --- a/google-beta/resource_compute_instance_iam_test.go +++ b/google-beta/resource_compute_instance_iam_test.go @@ -8,67 +8,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/resource" ) -func TestAccComputeInstanceIamBinding(t *testing.T) { - t.Parallel() - - project := getTestProjectFromEnv() - role := "roles/compute.osLogin" - zone := getTestZoneFromEnv() - instanceName := fmt.Sprintf("tf-test-instance-%s", acctest.RandString(10)) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - Config: testAccComputeInstanceIamBinding_basic(zone, instanceName, role), - }, - { - ResourceName: "google_compute_instance_iam_binding.foo", - ImportStateId: fmt.Sprintf("%s/%s/%s %s", project, zone, instanceName, role), - ImportState: true, - ImportStateVerify: true, - }, - { - // Test Iam Binding update - Config: testAccComputeInstanceIamBinding_update(zone, instanceName, role), - }, - { - ResourceName: "google_compute_instance_iam_binding.foo", - ImportStateId: fmt.Sprintf("%s/%s/%s %s", project, zone, instanceName, role), - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccComputeInstanceIamMember(t *testing.T) { - t.Parallel() - - project := getTestProjectFromEnv() - role := "roles/compute.osLogin" - zone := getTestZoneFromEnv() - instanceName := fmt.Sprintf("tf-test-instance-%s", acctest.RandString(10)) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - // Test Iam Member creation (no update for member, no need to test) - Config: testAccComputeInstanceIamMember_basic(zone, instanceName, role), - }, - { - ResourceName: "google_compute_instance_iam_member.foo", - ImportStateId: fmt.Sprintf("%s/%s/%s %s user:admin@hashicorptest.com", project, zone, instanceName, role), - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - +// Even though the resource has generated tests, keep this one around until we are able to generate +// checking the different import formats func TestAccComputeInstanceIamPolicy(t *testing.T) { t.Parallel() @@ -103,39 +44,16 @@ func TestAccComputeInstanceIamPolicy(t *testing.T) { ImportState: true, ImportStateVerify: true, }, + { + ResourceName: "google_compute_instance_iam_policy.foo", + ImportStateId: fmt.Sprintf("%s", instanceName), + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func testAccComputeInstanceIamMember_basic(zone, instanceName, roleId string) string { - return fmt.Sprintf(` - resource "google_compute_instance" "test_vm" { - zone = "%s" - name = "%s" - machine_type = "n1-standard-1" - - boot_disk { - initialize_params { - image = "debian-cloud/debian-9" - } - } - - network_interface { - network = "default" - } - } - - resource "google_compute_instance_iam_member" "foo" { - project = "${google_compute_instance.test_vm.project}" - zone = "${google_compute_instance.test_vm.zone}" - instance_name = "${google_compute_instance.test_vm.name}" - role = "%s" - member = "user:Admin@hashicorptest.com" - } - -`, zone, instanceName, roleId) -} - func testAccComputeInstanceIamPolicy_basic(zone, instanceName, roleId string) string { return fmt.Sprintf(` resource "google_compute_instance" "test_vm" { @@ -170,61 +88,3 @@ func testAccComputeInstanceIamPolicy_basic(zone, instanceName, roleId string) st `, zone, instanceName, roleId) } - -func testAccComputeInstanceIamBinding_basic(zone, instanceName, roleId string) string { - return fmt.Sprintf(` - resource "google_compute_instance" "test_vm" { - zone = "%s" - name = "%s" - machine_type = "n1-standard-1" - - boot_disk { - initialize_params { - image = "debian-cloud/debian-9" - } - } - - network_interface { - network = "default" - } - } - - resource "google_compute_instance_iam_binding" "foo" { - project = "${google_compute_instance.test_vm.project}" - zone = "${google_compute_instance.test_vm.zone}" - instance_name = "${google_compute_instance.test_vm.name}" - role = "%s" - members = ["user:Admin@hashicorptest.com"] - } - -`, zone, instanceName, roleId) -} - -func testAccComputeInstanceIamBinding_update(zone, instanceName, roleId string) string { - return fmt.Sprintf(` - resource "google_compute_instance" "test_vm" { - zone = "%s" - name = "%s" - machine_type = "n1-standard-1" - - boot_disk { - initialize_params { - image = "debian-cloud/debian-9" - } - } - - network_interface { - network = "default" - } - } - - resource "google_compute_instance_iam_binding" "foo" { - project = "${google_compute_instance.test_vm.project}" - zone = "${google_compute_instance.test_vm.zone}" - instance_name = "${google_compute_instance.test_vm.name}" - role = "%s" - members = ["user:Admin@hashicorptest.com", "user:paddy@hashicorp.com"] - } - -`, zone, instanceName, roleId) -} diff --git a/google-beta/resource_compute_subnetwork_iam_test.go b/google-beta/resource_compute_subnetwork_iam_test.go index 7b63eff893..973f39016d 100644 --- a/google-beta/resource_compute_subnetwork_iam_test.go +++ b/google-beta/resource_compute_subnetwork_iam_test.go @@ -8,68 +8,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/resource" ) -func TestAccComputeSubnetworkIamBinding(t *testing.T) { - t.Parallel() - - account := acctest.RandomWithPrefix("tf-test") - role := "roles/compute.networkUser" - region := getTestRegionFromEnv() - subnetwork := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - Config: testAccComputeSubnetworkIamBinding_basic(account, region, subnetwork, role), - }, - { - ResourceName: "google_compute_subnetwork_iam_binding.foo", - ImportStateId: fmt.Sprintf("%s/%s %s", region, subnetwork, role), - ImportState: true, - ImportStateVerify: true, - }, - { - // Test Iam Binding update - Config: testAccComputeSubnetworkIamBinding_update(account, region, subnetwork, role), - }, - { - ResourceName: "google_compute_subnetwork_iam_binding.foo", - ImportStateId: fmt.Sprintf("%s/%s %s", region, subnetwork, role), - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccComputeSubnetworkIamMember(t *testing.T) { - t.Parallel() - - project := getTestProjectFromEnv() - account := acctest.RandomWithPrefix("tf-test") - role := "roles/compute.networkUser" - region := getTestRegionFromEnv() - subnetwork := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - // Test Iam Member creation (no update for member, no need to test) - Config: testAccComputeSubnetworkIamMember_basic(account, region, subnetwork, role), - }, - { - ResourceName: "google_compute_subnetwork_iam_member.foo", - ImportStateId: fmt.Sprintf("%s/%s %s serviceAccount:%s@%s.iam.gserviceaccount.com", region, subnetwork, role, account, project), - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - +// Even though the resource has generated tests, keep this one around until we are able to generate +// checking the different import formats func TestAccComputeSubnetworkIamPolicy(t *testing.T) { t.Parallel() @@ -115,101 +55,6 @@ func TestAccComputeSubnetworkIamPolicy(t *testing.T) { }) } -func testAccComputeSubnetworkIamBinding_basic(account, region, subnetworkName, roleId string) string { - return fmt.Sprintf(` -resource "google_service_account" "test_account" { - account_id = "%s" - display_name = "Subnetwork Iam Testing Account" -} - -resource "google_compute_network" "network" { - name = "%s" - auto_create_subnetworks = false -} - -resource "google_compute_subnetwork" "subnetwork" { - name = "%s" - region = "%s" - ip_cidr_range = "10.1.0.0/16" - network = "${google_compute_network.network.name}" -} - -resource "google_compute_subnetwork_iam_binding" "foo" { - project = "${google_compute_subnetwork.subnetwork.project}" - region = "${google_compute_subnetwork.subnetwork.region}" - subnetwork = "${google_compute_subnetwork.subnetwork.name}" - role = "%s" - members = ["serviceAccount:${google_service_account.test_account.email}"] -} -`, account, subnetworkName, subnetworkName, region, roleId) -} - -func testAccComputeSubnetworkIamBinding_update(account, region, subnetworkName, roleId string) string { - return fmt.Sprintf(` -resource "google_service_account" "test_account" { - account_id = "%s" - display_name = "Subnetwork Iam Testing Account" -} - -resource "google_service_account" "test_account_2" { - account_id = "%s-2" - display_name = "Subnetwork Iam Testing Account" -} - -resource "google_compute_network" "network" { - name = "%s" - auto_create_subnetworks = false -} - -resource "google_compute_subnetwork" "subnetwork" { - name = "%s" - region = "%s" - ip_cidr_range = "10.1.0.0/16" - network = "${google_compute_network.network.name}" -} - -resource "google_compute_subnetwork_iam_binding" "foo" { - project = "${google_compute_subnetwork.subnetwork.project}" - region = "${google_compute_subnetwork.subnetwork.region}" - subnetwork = "${google_compute_subnetwork.subnetwork.name}" - role = "%s" - members = [ - "serviceAccount:${google_service_account.test_account.email}", - "serviceAccount:${google_service_account.test_account_2.email}" - ] -} -`, account, account, subnetworkName, subnetworkName, region, roleId) -} - -func testAccComputeSubnetworkIamMember_basic(account, region, subnetworkName, roleId string) string { - return fmt.Sprintf(` -resource "google_service_account" "test_account" { - account_id = "%s" - display_name = "Subnetwork Iam Testing Account" -} - -resource "google_compute_network" "network" { - name = "%s" - auto_create_subnetworks = false -} - -resource "google_compute_subnetwork" "subnetwork" { - name = "%s" - region = "%s" - ip_cidr_range = "10.1.0.0/16" - network = "${google_compute_network.network.name}" -} - -resource "google_compute_subnetwork_iam_member" "foo" { - project = "${google_compute_subnetwork.subnetwork.project}" - region = "${google_compute_subnetwork.subnetwork.region}" - subnetwork = "${google_compute_subnetwork.subnetwork.name}" - role = "%s" - member = "serviceAccount:${google_service_account.test_account.email}" -} -`, account, subnetworkName, subnetworkName, region, roleId) -} - func testAccComputeSubnetworkIamPolicy_basic(account, region, subnetworkName, roleId string) string { return fmt.Sprintf(` resource "google_service_account" "test_account" { diff --git a/website/docs/r/binary_authorization_attestor_iam.html.markdown b/website/docs/r/binary_authorization_attestor_iam.html.markdown index eff8a52ff1..754e09ba6b 100644 --- a/website/docs/r/binary_authorization_attestor_iam.html.markdown +++ b/website/docs/r/binary_authorization_attestor_iam.html.markdown @@ -110,14 +110,29 @@ exported: ## Import -BinaryAuthorization attestor IAM resources can be imported using the project, resource identifiers, role and member. +For all import syntaxes, the "resource in question" can take any of the following forms: +* projects/{{project}}/attestors/{{name}} +* {{project}}/{{name}} +* {{name}} + +Any variables not passed in the import command will be taken from the provider configuration. + +BinaryAuthorization attestor IAM resources can be imported using the resource identifiers, role, and member. + +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. +``` +$ terraform import google_binary_authorization_attestor_iam_member.editor "{{project}}/{{attestor}} roles/viewer jane@example.com" ``` -$ terraform import google_binary_authorization_attestor_iam_policy.editor {{project}}/{{attestor}} +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` $ terraform import google_binary_authorization_attestor_iam_binding.editor "{{project}}/{{attestor}} roles/viewer" +``` -$ terraform import google_binary_authorization_attestor_iam_member.editor "{{project}}/{{attestor}} roles/viewer jane@example.com" +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_binary_authorization_attestor_iam_policy.editor {{project}}/{{attestor}} ``` -> If you're importing a resource with beta features, make sure to include `-provider=google-beta` diff --git a/website/docs/r/cloudfunctions_cloud_function_iam.html.markdown b/website/docs/r/cloudfunctions_cloud_function_iam.html.markdown index f7aa608498..e54181d538 100644 --- a/website/docs/r/cloudfunctions_cloud_function_iam.html.markdown +++ b/website/docs/r/cloudfunctions_cloud_function_iam.html.markdown @@ -84,7 +84,9 @@ resource "google_cloudfunctions_function_iam_member" "editor" { The following arguments are supported: * `cloud_function` - (Required) Used to find the parent resource to bind the IAM policy to -* `region` - (Required) The location of this cloud function. Used to find the parent resource to bind the IAM policy to +* `region` - (Optional) The location of this cloud function. Used to find the parent resource to bind the IAM policy to. If not specified, + the value will be parsed from the identifier of the parent resource. If no region is provided in the parent identifier and no + region is specified, it is taken from the provider configuration. * `project` - (Optional) The ID of the project in which the resource belongs. If it is not provided, the project will be parsed from the identifier of the parent resource. If no project is provided in the parent identifier and no project is specified, the provider project is used. @@ -114,14 +116,30 @@ exported: ## Import -CloudFunctions cloudfunction IAM resources can be imported using the project, resource identifiers, role and member. +For all import syntaxes, the "resource in question" can take any of the following forms: +* projects/{{project}}/locations/{{region}}/functions/{{cloud_function}} +* {{project}}/{{region}}/{{cloud_function}} +* {{region}}/{{cloud_function}} +* {{cloud_function}} + +Any variables not passed in the import command will be taken from the provider configuration. + +CloudFunctions cloudfunction IAM resources can be imported using the resource identifiers, role, and member. + +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. +``` +$ terraform import google_cloudfunctions_function_iam_member.editor "{{project}}/{{region}}/{{cloud_function}} roles/viewer jane@example.com" ``` -$ terraform import google_cloudfunctions_function_iam_policy.editor {{project}}/{{region}}/{{cloud_function}} +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` $ terraform import google_cloudfunctions_function_iam_binding.editor "{{project}}/{{region}}/{{cloud_function}} roles/viewer" +``` -$ terraform import google_cloudfunctions_function_iam_member.editor "{{project}}/{{region}}/{{cloud_function}} roles/viewer jane@example.com" +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_cloudfunctions_function_iam_policy.editor {{project}}/{{region}}/{{cloud_function}} ``` -> If you're importing a resource with beta features, make sure to include `-provider=google-beta` diff --git a/website/docs/r/compute_instance_iam.html.markdown b/website/docs/r/compute_instance_iam.html.markdown index 9e30d21f78..116d8412ab 100644 --- a/website/docs/r/compute_instance_iam.html.markdown +++ b/website/docs/r/compute_instance_iam.html.markdown @@ -1,15 +1,27 @@ --- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- subcategory: "Compute Engine" layout: "google" page_title: "Google: google_compute_instance_iam" sidebar_current: "docs-google-compute-instance-iam" description: |- - Collection of resources to manage IAM policy for a GCE instance. + Collection of resources to manage IAM policy for ComputeInstance --- -# IAM policy for GCE instance - -Three different resources help you manage your IAM policy for GCE instance. Each of these resources serves a different use case: +# IAM policy for ComputeInstance +Three different resources help you manage your IAM policy for Compute Instance. Each of these resources serves a different use case: * `google_compute_instance_iam_policy`: Authoritative. Sets the IAM policy for the instance and replaces any existing policy already attached. * `google_compute_instance_iam_binding`: Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. Other roles within the IAM policy for the instance are preserved. @@ -19,53 +31,126 @@ Three different resources help you manage your IAM policy for GCE instance. Each ~> **Note:** `google_compute_instance_iam_binding` resources **can be** used in conjunction with `google_compute_instance_iam_member` resources **only if** they do not grant privilege to the same role. + + ## google\_compute\_instance\_iam\_policy +```hcl +data "google_iam_policy" "admin" { + binding { + role = "roles/compute.osLogin" + members = [ + "user:jane@example.com", + ] + } +} + +resource "google_compute_instance_iam_policy" "editor" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + policy_data = "${data.google_iam_policy.admin.policy_data}" +} +``` + +With IAM Conditions ([beta](https://terraform.io/docs/providers/google/provider_versions.html), Whitelist-only): + ```hcl data "google_iam_policy" "admin" { binding { role = "roles/compute.osLogin" - members = [ "user:jane@example.com", ] + + condition { + title = "expires_after_2019_12_31" + description = "Expiring at midnight of 2019-12-31" + expression = "request.time < timestamp(\"2020-01-01T00:00:00Z\")" + } } } -resource "google_compute_instance_iam_policy" "instance" { - instance_name = "your-instance-name" +resource "google_compute_instance_iam_policy" "editor" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" policy_data = "${data.google_iam_policy.admin.policy_data}" } ``` - ## google\_compute\_instance\_iam\_binding ```hcl -resource "google_compute_instance_iam_binding" "instance" { - instance_name = "your-instance-name" - role = "roles/compute.osLogin" +resource "google_compute_instance_iam_binding" "editor" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + role = "roles/compute.osLogin" + members = [ + "user:jane@example.com", + ] +} +``` + +With IAM Conditions ([beta](https://terraform.io/docs/providers/google/provider_versions.html), Whitelist-only): +```hcl +resource "google_compute_instance_iam_binding" "editor" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + role = "roles/compute.osLogin" members = [ "user:jane@example.com", ] + + condition { + title = "expires_after_2019_12_31" + description = "Expiring at midnight of 2019-12-31" + expression = "request.time < timestamp(\"2020-01-01T00:00:00Z\")" + } } ``` - ## google\_compute\_instance\_iam\_member ```hcl -resource "google_compute_instance_iam_member" "instance" { - instance_name = "your-instance-name" - role = "roles/compute.osLogin" - member = "user:jane@example.com" +resource "google_compute_instance_iam_member" "editor" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + role = "roles/compute.osLogin" + member = "user:jane@example.com" } ``` +With IAM Conditions ([beta](https://terraform.io/docs/providers/google/provider_versions.html), Whitelist-only): + +```hcl +resource "google_compute_instance_iam_member" "editor" { + project = "${google_compute_instance.default.project}" + zone = "${google_compute_instance.default.zone}" + instance_name = "${google_compute_instance.default.name}" + role = "roles/compute.osLogin" + member = "user:jane@example.com" + + condition { + title = "expires_after_2019_12_31" + description = "Expiring at midnight of 2019-12-31" + expression = "request.time < timestamp(\"2020-01-01T00:00:00Z\")" + } +} +``` ## Argument Reference The following arguments are supported: -* `instance_name` - (Required) The name of the instance. +* `instance_name` - (Required) Used to find the parent resource to bind the IAM policy to +* `zone` - (Optional) A reference to the zone where the machine resides. Used to find the parent resource to bind the IAM policy to. If not specified, + the value will be parsed from the identifier of the parent resource. If no zone is provided in the parent identifier and no + zone is specified, it is taken from the provider configuration. + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the project will be parsed from the identifier of the parent resource. If no project is provided in the parent identifier and no project is specified, the provider project is used. * `member/members` - (Required) Identities that will be granted the privilege in `role`. Each entry can have one of the following values: @@ -83,42 +168,60 @@ The following arguments are supported: * `policy_data` - (Required only by `google_compute_instance_iam_policy`) The policy data generated by a `google_iam_policy` data source. -* `project` - (Optional) The ID of the project in which the resource belongs. If it - is not provided, the provider project is used. +* `condition` - (Optional, [Beta](https://terraform.io/docs/providers/google/provider_versions.html)) An [IAM Condition](https://cloud.google.com/iam/docs/conditions-overview) for a given binding. You must be whitelisted for the IAM Conditions private beta in order to use them in Terraform. + Structure is documented below. + +--- -* `zone` - (Optional) The zone of the instance. If - unspecified, this defaults to the zone configured in the provider. +The `condition` block supports: +* `expression` - (Required) Textual representation of an expression in Common Expression Language syntax. + +* `title` - (Required) A title for the expression, i.e. a short string describing its purpose. + +* `description` - (Optional) An optional description of the expression. This is a longer text which describes the expression, e.g. when hovered over it in a UI. + +~> **Warning:** Terraform considers the `role` and condition contents (`title`+`description`+`expression`) as the + identifier for the binding. This means that if any part of the condition is changed out-of-band, Terraform will + consider it to be an entirely different resource and will treat it as such. ## Attributes Reference In addition to the arguments listed above, the following computed attributes are exported: -* `etag` - (Computed) The etag of the instance's IAM policy. +* `etag` - (Computed) The etag of the IAM policy. ## Import For all import syntaxes, the "resource in question" can take any of the following forms: -* full self link or relative link (projects/{{project}}/zones/{{zone}}/instances/{{name}}) +* projects/{{project}}/zones/{{zone}}/instances/{{name}} * {{project}}/{{zone}}/{{name}} -* {{zone}}/{{name}} (project is taken from provider project) -* {{name}} (project and zone are taken from provider project) +* {{zone}}/{{name}} +* {{name}} -IAM member imports use space-delimited identifiers; the resource in question, the role, and the member identity, e.g. +Any variables not passed in the import command will be taken from the provider configuration. +Compute instance IAM resources can be imported using the resource identifiers, role, and member. + +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. ``` -$ terraform import google_compute_instance_iam_member.instance "project-name/zone-name/instance-name roles/compute.osLogin user:foo@example.com" +$ terraform import google_compute_instance_iam_member.editor "{{instance}} roles/compute.osLogin jane@example.com" ``` -IAM binding imports use space-delimited identifiers; the resource in question and the role, e.g. - +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. ``` -$ terraform import google_compute_instance_iam_binding.instance "project-name/zone-name/instance-name roles/compute.osLogin" +$ terraform import google_compute_instance_iam_binding.editor "{{instance}} roles/compute.osLogin" ``` IAM policy imports use the identifier of the resource in question, e.g. - ``` -$ terraform import google_compute_instance_iam_policy.instance project-name/zone-name/instance-name +$ terraform import google_compute_instance_iam_policy.editor {{instance}} ``` + +-> If you're importing a resource with beta features, make sure to include `-provider=google-beta` +as an argument so that Terraform uses the correct provider to import your resource. + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/docs/r/compute_subnetwork_iam.html.markdown b/website/docs/r/compute_subnetwork_iam.html.markdown index 0964035c6c..10233ab1c5 100644 --- a/website/docs/r/compute_subnetwork_iam.html.markdown +++ b/website/docs/r/compute_subnetwork_iam.html.markdown @@ -1,18 +1,27 @@ --- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- subcategory: "Compute Engine" layout: "google" page_title: "Google: google_compute_subnetwork_iam" sidebar_current: "docs-google-compute-subnetwork-iam" description: |- - Collection of resources to manage IAM policy for a GCE subnetwork. + Collection of resources to manage IAM policy for ComputeSubnetwork --- -# IAM policy for GCE subnetwork - -~> **Warning:** These resources are in beta, and should be used with the terraform-provider-google-beta provider. -See [Provider Versions](https://terraform.io/docs/providers/google/guides/provider_versions.html) for more details on beta resources. - -Three different resources help you manage your IAM policy for GCE subnetwork. Each of these resources serves a different use case: +# IAM policy for ComputeSubnetwork +Three different resources help you manage your IAM policy for Compute Subnetwork. Each of these resources serves a different use case: * `google_compute_subnetwork_iam_policy`: Authoritative. Sets the IAM policy for the subnetwork and replaces any existing policy already attached. * `google_compute_subnetwork_iam_binding`: Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. Other roles within the IAM policy for the subnetwork are preserved. @@ -22,21 +31,24 @@ Three different resources help you manage your IAM policy for GCE subnetwork. Ea ~> **Note:** `google_compute_subnetwork_iam_binding` resources **can be** used in conjunction with `google_compute_subnetwork_iam_member` resources **only if** they do not grant privilege to the same role. + + ## google\_compute\_subnetwork\_iam\_policy ```hcl data "google_iam_policy" "admin" { - binding { - role = "roles/editor" - - members = [ - "user:jane@example.com", - ] - } + binding { + role = "roles/compute.networkUser" + members = [ + "user:jane@example.com", + ] + } } -resource "google_compute_subnetwork_iam_policy" "subnet" { - subnetwork = "your-subnetwork-id" +resource "google_compute_subnetwork_iam_policy" "editor" { + project = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.project}" + region = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.region}" + subnetwork = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.name}" policy_data = "${data.google_iam_policy.admin.policy_data}" } ``` @@ -44,23 +56,26 @@ resource "google_compute_subnetwork_iam_policy" "subnet" { ## google\_compute\_subnetwork\_iam\_binding ```hcl -resource "google_compute_subnetwork_iam_binding" "subnet" { - subnetwork = "your-subnetwork-id" - role = "roles/compute.networkUser" - - members = [ - "user:jane@example.com", - ] +resource "google_compute_subnetwork_iam_binding" "editor" { + project = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.project}" + region = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.region}" + subnetwork = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.name}" + role = "roles/compute.networkUser" + members = [ + "user:jane@example.com", + ] } ``` ## google\_compute\_subnetwork\_iam\_member ```hcl -resource "google_compute_subnetwork_iam_member" "subnet" { - subnetwork = "your-subnetwork-id" - role = "roles/compute.networkUser" - member = "user:jane@example.com" +resource "google_compute_subnetwork_iam_member" "editor" { + project = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.project}" + region = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.region}" + subnetwork = "${google_compute_subnetwork.network-with-private-secondary-ip-ranges.name}" + role = "roles/compute.networkUser" + member = "user:jane@example.com" } ``` @@ -68,7 +83,14 @@ resource "google_compute_subnetwork_iam_member" "subnet" { The following arguments are supported: -* `subnetwork` - (Required) The name of the subnetwork. +* `subnetwork` - (Required) Used to find the parent resource to bind the IAM policy to +* `region` - (Optional) URL of the GCP region for this subnetwork. + Used to find the parent resource to bind the IAM policy to. If not specified, + the value will be parsed from the identifier of the parent resource. If no region is provided in the parent identifier and no + region is specified, it is taken from the provider configuration. + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the project will be parsed from the identifier of the parent resource. If no project is provided in the parent identifier and no project is specified, the provider project is used. * `member/members` - (Required) Identities that will be granted the privilege in `role`. Each entry can have one of the following values: @@ -86,42 +108,44 @@ The following arguments are supported: * `policy_data` - (Required only by `google_compute_subnetwork_iam_policy`) The policy data generated by a `google_iam_policy` data source. -* `project` - (Optional) The ID of the project in which the resource belongs. If it - is not provided, the provider project is used. - -* `region` - (Optional) The region of the subnetwork. If - unspecified, this defaults to the region configured in the provider. - ## Attributes Reference In addition to the arguments listed above, the following computed attributes are exported: -* `etag` - (Computed) The etag of the subnetwork's IAM policy. +* `etag` - (Computed) The etag of the IAM policy. ## Import For all import syntaxes, the "resource in question" can take any of the following forms: -* full self link or relative link (projects/{{project}}/region/{{region}}/subnetworks/{{name}}) +* projects/{{project}}/regions/{{region}}/subnetworks/{{name}} * {{project}}/{{region}}/{{name}} -* {{region}}/{{name}} (project is taken from provider project) -* {{name}} (project and region are taken from provider project) +* {{region}}/{{name}} +* {{name}} + +Any variables not passed in the import command will be taken from the provider configuration. -IAM member imports use space-delimited identifiers; the resource in question, the role, and the member identity, e.g. +Compute subnetwork IAM resources can be imported using the resource identifiers, role, and member. +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. ``` -$ terraform import google_compute_subnetwork_iam_member.subnet "project-name/region-name/subnetwork-name roles/compute.networkUser user:foo@example.com" +$ terraform import google_compute_subnetwork_iam_member.editor "{{region}}/{{subnetwork}} roles/compute.networkUser jane@example.com" ``` -IAM binding imports use space-delimited identifiers; the resource in question and the role, e.g. - +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. ``` -$ terraform import google_compute_subnetwork_iam_binding.subnet "project-name/region-name/subnetwork-name roles/compute.networkUser" +$ terraform import google_compute_subnetwork_iam_binding.editor "{{region}}/{{subnetwork}} roles/compute.networkUser" ``` IAM policy imports use the identifier of the resource in question, e.g. - ``` -$ terraform import google_compute_subnetwork_iam_policy.subnet project-name/region-name/subnetwork-name +$ terraform import google_compute_subnetwork_iam_policy.editor {{region}}/{{subnetwork}} ``` + +-> If you're importing a resource with beta features, make sure to include `-provider=google-beta` +as an argument so that Terraform uses the correct provider to import your resource. + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/docs/r/iap_app_engine_service_iam.html.markdown b/website/docs/r/iap_app_engine_service_iam.html.markdown index 493e40d26f..488bba452d 100644 --- a/website/docs/r/iap_app_engine_service_iam.html.markdown +++ b/website/docs/r/iap_app_engine_service_iam.html.markdown @@ -114,14 +114,30 @@ exported: ## Import -Iap appengineservice IAM resources can be imported using the project, resource identifiers, role and member. +For all import syntaxes, the "resource in question" can take any of the following forms: +* projects/{{project}}/iap_web/appengine-{{appId}}/services/{{service}} +* {{project}}/{{appId}}/{{service}} +* {{appId}}/{{service}} +* {{service}} + +Any variables not passed in the import command will be taken from the provider configuration. + +Iap appengineservice IAM resources can be imported using the resource identifiers, role, and member. + +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. +``` +$ terraform import google_iap_app_engine_service_iam_member.editor "projects/{{project}}/iap_web/appengine-{{appId}}/services/{{service}} roles/iap.httpsResourceAccessor jane@example.com" ``` -$ terraform import google_iap_app_engine_service_iam_policy.editor projects/{{project}}/iap_web/appengine-{{appId}}/services/{{service}} +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` $ terraform import google_iap_app_engine_service_iam_binding.editor "projects/{{project}}/iap_web/appengine-{{appId}}/services/{{service}} roles/iap.httpsResourceAccessor" +``` -$ terraform import google_iap_app_engine_service_iam_member.editor "projects/{{project}}/iap_web/appengine-{{appId}}/services/{{service}} roles/iap.httpsResourceAccessor jane@example.com" +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_iap_app_engine_service_iam_policy.editor projects/{{project}}/iap_web/appengine-{{appId}}/services/{{service}} ``` -> If you're importing a resource with beta features, make sure to include `-provider=google-beta` diff --git a/website/docs/r/iap_app_engine_version_iam.html.markdown b/website/docs/r/iap_app_engine_version_iam.html.markdown index a786fed772..8a34953619 100644 --- a/website/docs/r/iap_app_engine_version_iam.html.markdown +++ b/website/docs/r/iap_app_engine_version_iam.html.markdown @@ -198,14 +198,30 @@ exported: ## Import -Iap appengineversion IAM resources can be imported using the project, resource identifiers, role and member. +For all import syntaxes, the "resource in question" can take any of the following forms: +* projects/{{project}}/iap_web/appengine-{{appId}}/services/{{service}}/versions/{{versionId}} +* {{project}}/{{appId}}/{{service}}/{{versionId}} +* {{appId}}/{{service}}/{{versionId}} +* {{version}} + +Any variables not passed in the import command will be taken from the provider configuration. + +Iap appengineversion IAM resources can be imported using the resource identifiers, role, and member. + +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. +``` +$ terraform import google_iap_app_engine_version_iam_member.editor "projects/{{project}}/iap_web/appengine-{{appId}}/services/{{service}}/versions/{{versionId}} roles/iap.httpsResourceAccessor jane@example.com" ``` -$ terraform import google_iap_app_engine_version_iam_policy.editor projects/{{project}}/iap_web/appengine-{{appId}}/services/{{service}}/versions/{{versionId}} +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` $ terraform import google_iap_app_engine_version_iam_binding.editor "projects/{{project}}/iap_web/appengine-{{appId}}/services/{{service}}/versions/{{versionId}} roles/iap.httpsResourceAccessor" +``` -$ terraform import google_iap_app_engine_version_iam_member.editor "projects/{{project}}/iap_web/appengine-{{appId}}/services/{{service}}/versions/{{versionId}} roles/iap.httpsResourceAccessor jane@example.com" +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_iap_app_engine_version_iam_policy.editor projects/{{project}}/iap_web/appengine-{{appId}}/services/{{service}}/versions/{{versionId}} ``` -> If you're importing a resource with beta features, make sure to include `-provider=google-beta` diff --git a/website/docs/r/iap_web_backend_service_iam.html.markdown b/website/docs/r/iap_web_backend_service_iam.html.markdown index 6067b31ad3..f24ea3e075 100644 --- a/website/docs/r/iap_web_backend_service_iam.html.markdown +++ b/website/docs/r/iap_web_backend_service_iam.html.markdown @@ -184,14 +184,29 @@ exported: ## Import -Iap webbackendservice IAM resources can be imported using the project, resource identifiers, role and member. +For all import syntaxes, the "resource in question" can take any of the following forms: +* projects/{{project}}/iap_web/compute/services/{{name}} +* {{project}}/{{name}} +* {{name}} + +Any variables not passed in the import command will be taken from the provider configuration. + +Iap webbackendservice IAM resources can be imported using the resource identifiers, role, and member. + +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. +``` +$ terraform import google_iap_web_backend_service_iam_member.editor "projects/{{project}}/iap_web/compute/services/{{web_backend_service}} roles/iap.httpsResourceAccessor jane@example.com" ``` -$ terraform import google_iap_web_backend_service_iam_policy.editor projects/{{project}}/iap_web/compute/services/{{web_backend_service}} +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` $ terraform import google_iap_web_backend_service_iam_binding.editor "projects/{{project}}/iap_web/compute/services/{{web_backend_service}} roles/iap.httpsResourceAccessor" +``` -$ terraform import google_iap_web_backend_service_iam_member.editor "projects/{{project}}/iap_web/compute/services/{{web_backend_service}} roles/iap.httpsResourceAccessor jane@example.com" +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_iap_web_backend_service_iam_policy.editor projects/{{project}}/iap_web/compute/services/{{web_backend_service}} ``` -> If you're importing a resource with beta features, make sure to include `-provider=google-beta` diff --git a/website/docs/r/iap_web_iam.html.markdown b/website/docs/r/iap_web_iam.html.markdown index a79f0216d9..267af4f9c8 100644 --- a/website/docs/r/iap_web_iam.html.markdown +++ b/website/docs/r/iap_web_iam.html.markdown @@ -106,14 +106,28 @@ exported: ## Import -Iap web IAM resources can be imported using the project, resource identifiers, role and member. +For all import syntaxes, the "resource in question" can take any of the following forms: +* projects/{{project}}/iap_web +* {{project}} + +Any variables not passed in the import command will be taken from the provider configuration. + +Iap web IAM resources can be imported using the resource identifiers, role, and member. + +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. +``` +$ terraform import google_iap_web_iam_member.editor "projects/{{project}}/iap_web roles/iap.httpsResourceAccessor jane@example.com" ``` -$ terraform import google_iap_web_iam_policy.editor projects/{{project}}/iap_web +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` $ terraform import google_iap_web_iam_binding.editor "projects/{{project}}/iap_web roles/iap.httpsResourceAccessor" +``` -$ terraform import google_iap_web_iam_member.editor "projects/{{project}}/iap_web roles/iap.httpsResourceAccessor jane@example.com" +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_iap_web_iam_policy.editor projects/{{project}}/iap_web ``` -> If you're importing a resource with beta features, make sure to include `-provider=google-beta` diff --git a/website/docs/r/iap_web_type_app_engine_iam.html.markdown b/website/docs/r/iap_web_type_app_engine_iam.html.markdown index 26e09f6466..399bbd4341 100644 --- a/website/docs/r/iap_web_type_app_engine_iam.html.markdown +++ b/website/docs/r/iap_web_type_app_engine_iam.html.markdown @@ -110,14 +110,29 @@ exported: ## Import -Iap webtypeappengine IAM resources can be imported using the project, resource identifiers, role and member. +For all import syntaxes, the "resource in question" can take any of the following forms: +* projects/{{project}}/iap_web/appengine-{{appId}} +* {{project}}/{{appId}} +* {{appId}} + +Any variables not passed in the import command will be taken from the provider configuration. + +Iap webtypeappengine IAM resources can be imported using the resource identifiers, role, and member. + +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. +``` +$ terraform import google_iap_web_type_app_engine_iam_member.editor "projects/{{project}}/iap_web/appengine-{{appId}} roles/iap.httpsResourceAccessor jane@example.com" ``` -$ terraform import google_iap_web_type_app_engine_iam_policy.editor projects/{{project}}/iap_web/appengine-{{appId}} +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` $ terraform import google_iap_web_type_app_engine_iam_binding.editor "projects/{{project}}/iap_web/appengine-{{appId}} roles/iap.httpsResourceAccessor" +``` -$ terraform import google_iap_web_type_app_engine_iam_member.editor "projects/{{project}}/iap_web/appengine-{{appId}} roles/iap.httpsResourceAccessor jane@example.com" +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_iap_web_type_app_engine_iam_policy.editor projects/{{project}}/iap_web/appengine-{{appId}} ``` -> If you're importing a resource with beta features, make sure to include `-provider=google-beta` diff --git a/website/docs/r/iap_web_type_compute_iam.html.markdown b/website/docs/r/iap_web_type_compute_iam.html.markdown index e93bbab907..5dc6e59d50 100644 --- a/website/docs/r/iap_web_type_compute_iam.html.markdown +++ b/website/docs/r/iap_web_type_compute_iam.html.markdown @@ -106,14 +106,28 @@ exported: ## Import -Iap webtypecompute IAM resources can be imported using the project, resource identifiers, role and member. +For all import syntaxes, the "resource in question" can take any of the following forms: +* projects/{{project}}/iap_web/compute +* {{project}} + +Any variables not passed in the import command will be taken from the provider configuration. + +Iap webtypecompute IAM resources can be imported using the resource identifiers, role, and member. + +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. +``` +$ terraform import google_iap_web_type_compute_iam_member.editor "projects/{{project}}/iap_web/compute roles/iap.httpsResourceAccessor jane@example.com" ``` -$ terraform import google_iap_web_type_compute_iam_policy.editor projects/{{project}}/iap_web/compute +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` $ terraform import google_iap_web_type_compute_iam_binding.editor "projects/{{project}}/iap_web/compute roles/iap.httpsResourceAccessor" +``` -$ terraform import google_iap_web_type_compute_iam_member.editor "projects/{{project}}/iap_web/compute roles/iap.httpsResourceAccessor jane@example.com" +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_iap_web_type_compute_iam_policy.editor projects/{{project}}/iap_web/compute ``` -> If you're importing a resource with beta features, make sure to include `-provider=google-beta` diff --git a/website/docs/r/pubsub_topic_iam.html.markdown b/website/docs/r/pubsub_topic_iam.html.markdown index 754c9608c1..e6da5e8b83 100644 --- a/website/docs/r/pubsub_topic_iam.html.markdown +++ b/website/docs/r/pubsub_topic_iam.html.markdown @@ -110,14 +110,29 @@ exported: ## Import -Pubsub topic IAM resources can be imported using the project, resource identifiers, role and member. +For all import syntaxes, the "resource in question" can take any of the following forms: +* projects/{{project}}/topics/{{name}} +* {{project}}/{{name}} +* {{name}} + +Any variables not passed in the import command will be taken from the provider configuration. + +Pubsub topic IAM resources can be imported using the resource identifiers, role, and member. + +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. +``` +$ terraform import google_pubsub_topic_iam_member.editor "projects/{{project}}/topics/{{topic}} roles/viewer jane@example.com" ``` -$ terraform import google_pubsub_topic_iam_policy.editor projects/{{project}}/topics/{{topic}} +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` $ terraform import google_pubsub_topic_iam_binding.editor "projects/{{project}}/topics/{{topic}} roles/viewer" +``` -$ terraform import google_pubsub_topic_iam_member.editor "projects/{{project}}/topics/{{topic}} roles/viewer jane@example.com" +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_pubsub_topic_iam_policy.editor projects/{{project}}/topics/{{topic}} ``` -> If you're importing a resource with beta features, make sure to include `-provider=google-beta` diff --git a/website/docs/r/runtimeconfig_config_iam.html.markdown b/website/docs/r/runtimeconfig_config_iam.html.markdown index 7de64252d3..4d3871215d 100644 --- a/website/docs/r/runtimeconfig_config_iam.html.markdown +++ b/website/docs/r/runtimeconfig_config_iam.html.markdown @@ -110,14 +110,29 @@ exported: ## Import -RuntimeConfig config IAM resources can be imported using the project, resource identifiers, role and member. +For all import syntaxes, the "resource in question" can take any of the following forms: +* projects/{{project}}/configs/{{config}} +* {{project}}/{{config}} +* {{config}} + +Any variables not passed in the import command will be taken from the provider configuration. + +RuntimeConfig config IAM resources can be imported using the resource identifiers, role, and member. + +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. +``` +$ terraform import google_runtimeconfig_config_iam_member.editor "projects/{{project}}/configs/{{config}} roles/viewer jane@example.com" ``` -$ terraform import google_runtimeconfig_config_iam_policy.editor projects/{{project}}/configs/{{config}} +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` $ terraform import google_runtimeconfig_config_iam_binding.editor "projects/{{project}}/configs/{{config}} roles/viewer" +``` -$ terraform import google_runtimeconfig_config_iam_member.editor "projects/{{project}}/configs/{{config}} roles/viewer jane@example.com" +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_runtimeconfig_config_iam_policy.editor projects/{{project}}/configs/{{config}} ``` -> If you're importing a resource with beta features, make sure to include `-provider=google-beta` diff --git a/website/docs/r/sourcerepo_repository_iam.html.markdown b/website/docs/r/sourcerepo_repository_iam.html.markdown index 8f0467714a..21d465e98d 100644 --- a/website/docs/r/sourcerepo_repository_iam.html.markdown +++ b/website/docs/r/sourcerepo_repository_iam.html.markdown @@ -110,14 +110,29 @@ exported: ## Import -SourceRepo repository IAM resources can be imported using the project, resource identifiers, role and member. +For all import syntaxes, the "resource in question" can take any of the following forms: +* projects/{{project}}/repos/{{name}} +* {{project}}/{{name}} +* {{name}} + +Any variables not passed in the import command will be taken from the provider configuration. + +SourceRepo repository IAM resources can be imported using the resource identifiers, role, and member. + +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. +``` +$ terraform import google_sourcerepo_repository_iam_member.editor "{{project}}/{{repository}} roles/viewer jane@example.com" ``` -$ terraform import google_sourcerepo_repository_iam_policy.editor {{project}}/{{repository}} +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` $ terraform import google_sourcerepo_repository_iam_binding.editor "{{project}}/{{repository}} roles/viewer" +``` -$ terraform import google_sourcerepo_repository_iam_member.editor "{{project}}/{{repository}} roles/viewer jane@example.com" +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_sourcerepo_repository_iam_policy.editor {{project}}/{{repository}} ``` -> If you're importing a resource with beta features, make sure to include `-provider=google-beta`