diff --git a/.changelog/5270.txt b/.changelog/5270.txt new file mode 100644 index 0000000000..d3c0fabb04 --- /dev/null +++ b/.changelog/5270.txt @@ -0,0 +1,6 @@ +```release-note:enhancement +apigee: Added IAM support for `google_apigee_environment`. +``` +```release-note:breaking-change +apigee: Replaced `org_id` with `org_name` for `google_apigee_environment`. +``` diff --git a/google-beta/iam_apigee_environment.go b/google-beta/iam_apigee_environment.go new file mode 100644 index 0000000000..7dbe271c0f --- /dev/null +++ b/google-beta/iam_apigee_environment.go @@ -0,0 +1,181 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// 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" + + "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "google.golang.org/api/cloudresourcemanager/v1" +) + +var ApigeeEnvironmentIamSchema = map[string]*schema.Schema{ + "org_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "env_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + }, +} + +type ApigeeEnvironmentIamUpdater struct { + orgId string + envId string + d TerraformResourceData + Config *Config +} + +func ApigeeEnvironmentIamUpdaterProducer(d TerraformResourceData, config *Config) (ResourceIamUpdater, error) { + values := make(map[string]string) + + if v, ok := d.GetOk("org_id"); ok { + values["org_id"] = v.(string) + } + + if v, ok := d.GetOk("env_id"); ok { + values["env_id"] = v.(string) + } + + // We may have gotten either a long or short name, so attempt to parse long name if possible + m, err := getImportIdQualifiers([]string{"(?P.+)/environments/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Get("env_id").(string)) + if err != nil { + return nil, err + } + + for k, v := range m { + values[k] = v + } + + u := &ApigeeEnvironmentIamUpdater{ + orgId: values["org_id"], + envId: values["env_id"], + d: d, + Config: config, + } + + if err := d.Set("org_id", u.orgId); err != nil { + return nil, fmt.Errorf("Error setting org_id: %s", err) + } + if err := d.Set("env_id", u.GetResourceId()); err != nil { + return nil, fmt.Errorf("Error setting env_id: %s", err) + } + + return u, nil +} + +func ApigeeEnvironmentIdParseFunc(d *schema.ResourceData, config *Config) error { + values := make(map[string]string) + + m, err := getImportIdQualifiers([]string{"(?P.+)/environments/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Id()) + if err != nil { + return err + } + + for k, v := range m { + values[k] = v + } + + u := &ApigeeEnvironmentIamUpdater{ + orgId: values["org_id"], + envId: values["env_id"], + d: d, + Config: config, + } + if err := d.Set("env_id", u.GetResourceId()); err != nil { + return fmt.Errorf("Error setting env_id: %s", err) + } + d.SetId(u.GetResourceId()) + return nil +} + +func (u *ApigeeEnvironmentIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { + url, err := u.qualifyEnvironmentUrl("getIamPolicy") + if err != nil { + return nil, err + } + + var obj map[string]interface{} + + userAgent, err := generateUserAgentString(u.d, u.Config.userAgent) + if err != nil { + return nil, err + } + + policy, err := sendRequest(u.Config, "GET", "", url, userAgent, 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("Cannot convert a policy to a resource manager policy: {{err}}", err) + } + + return out, nil +} + +func (u *ApigeeEnvironmentIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Policy) error { + json, err := ConvertToMap(policy) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + obj["policy"] = json + + url, err := u.qualifyEnvironmentUrl("setIamPolicy") + if err != nil { + return err + } + + userAgent, err := generateUserAgentString(u.d, u.Config.userAgent) + if err != nil { + return err + } + + _, err = sendRequestWithTimeout(u.Config, "POST", "", url, userAgent, obj, u.d.Timeout(schema.TimeoutCreate)) + if err != nil { + return errwrap.Wrapf(fmt.Sprintf("Error setting IAM policy for %s: {{err}}", u.DescribeResource()), err) + } + + return nil +} + +func (u *ApigeeEnvironmentIamUpdater) qualifyEnvironmentUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{ApigeeBasePath}}%s:%s", fmt.Sprintf("%s/environments/%s", u.orgId, u.envId), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil +} + +func (u *ApigeeEnvironmentIamUpdater) GetResourceId() string { + return fmt.Sprintf("%s/environments/%s", u.orgId, u.envId) +} + +func (u *ApigeeEnvironmentIamUpdater) GetMutexKey() string { + return fmt.Sprintf("iam-apigee-environment-%s", u.GetResourceId()) +} + +func (u *ApigeeEnvironmentIamUpdater) DescribeResource() string { + return fmt.Sprintf("apigee environment %q", u.GetResourceId()) +} diff --git a/google-beta/iam_apigee_environment_generated_test.go b/google-beta/iam_apigee_environment_generated_test.go new file mode 100644 index 0000000000..1ea4261177 --- /dev/null +++ b/google-beta/iam_apigee_environment_generated_test.go @@ -0,0 +1,491 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// 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/v2/helper/resource" +) + +func TestAccApigeeEnvironmentIamBindingGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": randString(t, 10), + "role": "roles/viewer", + "org_id": getTestOrgFromEnv(t), + "billing_account": getTestBillingAccountFromEnv(t), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccApigeeEnvironmentIamBinding_basicGenerated(context), + }, + { + ResourceName: "google_apigee_environment_iam_binding.foo", + ImportStateId: fmt.Sprintf("%s/environments/%s roles/viewer", fmt.Sprintf("organizations/tf-test%s", context["random_suffix"]), fmt.Sprintf("tf-test%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + { + // Test Iam Binding update + Config: testAccApigeeEnvironmentIamBinding_updateGenerated(context), + }, + { + ResourceName: "google_apigee_environment_iam_binding.foo", + ImportStateId: fmt.Sprintf("%s/environments/%s roles/viewer", fmt.Sprintf("organizations/tf-test%s", context["random_suffix"]), fmt.Sprintf("tf-test%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccApigeeEnvironmentIamMemberGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": randString(t, 10), + "role": "roles/viewer", + "org_id": getTestOrgFromEnv(t), + "billing_account": getTestBillingAccountFromEnv(t), + } + + vcrTest(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: testAccApigeeEnvironmentIamMember_basicGenerated(context), + }, + { + ResourceName: "google_apigee_environment_iam_member.foo", + ImportStateId: fmt.Sprintf("%s/environments/%s roles/viewer user:admin@hashicorptest.com", fmt.Sprintf("organizations/tf-test%s", context["random_suffix"]), fmt.Sprintf("tf-test%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccApigeeEnvironmentIamPolicyGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": randString(t, 10), + "role": "roles/viewer", + "org_id": getTestOrgFromEnv(t), + "billing_account": getTestBillingAccountFromEnv(t), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccApigeeEnvironmentIamPolicy_basicGenerated(context), + }, + { + ResourceName: "google_apigee_environment_iam_policy.foo", + ImportStateId: fmt.Sprintf("%s/environments/%s", fmt.Sprintf("organizations/tf-test%s", context["random_suffix"]), fmt.Sprintf("tf-test%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccApigeeEnvironmentIamPolicy_emptyBinding(context), + }, + { + ResourceName: "google_apigee_environment_iam_policy.foo", + ImportStateId: fmt.Sprintf("%s/environments/%s", fmt.Sprintf("organizations/tf-test%s", context["random_suffix"]), fmt.Sprintf("tf-test%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccApigeeEnvironmentIamMember_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_account}" +} + +resource "google_project_service" "apigee" { + project = google_project.project.project_id + service = "apigee.googleapis.com" +} + +resource "google_project_service" "compute" { + project = google_project.project.project_id + service = "compute.googleapis.com" +} + +resource "google_project_service" "servicenetworking" { + project = google_project.project.project_id + service = "servicenetworking.googleapis.com" +} + +resource "google_compute_network" "apigee_network" { + name = "apigee-network" + project = google_project.project.project_id + depends_on = [google_project_service.compute] +} + +resource "google_compute_global_address" "apigee_range" { + name = "apigee-range" + purpose = "VPC_PEERING" + address_type = "INTERNAL" + prefix_length = 16 + network = google_compute_network.apigee_network.id + project = google_project.project.project_id +} + +resource "google_service_networking_connection" "apigee_vpc_connection" { + network = google_compute_network.apigee_network.id + service = "servicenetworking.googleapis.com" + reserved_peering_ranges = [google_compute_global_address.apigee_range.name] + depends_on = [google_project_service.servicenetworking] +} + +resource "google_apigee_organization" "apigee_org" { + analytics_region = "us-central1" + project_id = google_project.project.project_id + authorized_network = google_compute_network.apigee_network.id + depends_on = [ + google_service_networking_connection.apigee_vpc_connection, + google_project_service.apigee, + ] +} + +resource "google_apigee_environment" "apigee_environment" { + org_id = google_apigee_organization.apigee_org.id + name = "tf-test%{random_suffix}" + description = "Apigee Environment" + display_name = "environment-1" +} + +resource "google_apigee_environment_iam_member" "foo" { + org_id = google_apigee_environment.apigee_environment.org_id + env_id = google_apigee_environment.apigee_environment.name + role = "%{role}" + member = "user:admin@hashicorptest.com" +} +`, context) +} + +func testAccApigeeEnvironmentIamPolicy_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_account}" +} + +resource "google_project_service" "apigee" { + project = google_project.project.project_id + service = "apigee.googleapis.com" +} + +resource "google_project_service" "compute" { + project = google_project.project.project_id + service = "compute.googleapis.com" +} + +resource "google_project_service" "servicenetworking" { + project = google_project.project.project_id + service = "servicenetworking.googleapis.com" +} + +resource "google_compute_network" "apigee_network" { + name = "apigee-network" + project = google_project.project.project_id + depends_on = [google_project_service.compute] +} + +resource "google_compute_global_address" "apigee_range" { + name = "apigee-range" + purpose = "VPC_PEERING" + address_type = "INTERNAL" + prefix_length = 16 + network = google_compute_network.apigee_network.id + project = google_project.project.project_id +} + +resource "google_service_networking_connection" "apigee_vpc_connection" { + network = google_compute_network.apigee_network.id + service = "servicenetworking.googleapis.com" + reserved_peering_ranges = [google_compute_global_address.apigee_range.name] + depends_on = [google_project_service.servicenetworking] +} + +resource "google_apigee_organization" "apigee_org" { + analytics_region = "us-central1" + project_id = google_project.project.project_id + authorized_network = google_compute_network.apigee_network.id + depends_on = [ + google_service_networking_connection.apigee_vpc_connection, + google_project_service.apigee, + ] +} + +resource "google_apigee_environment" "apigee_environment" { + org_id = google_apigee_organization.apigee_org.id + name = "tf-test%{random_suffix}" + description = "Apigee Environment" + display_name = "environment-1" +} + +data "google_iam_policy" "foo" { + binding { + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + } +} + +resource "google_apigee_environment_iam_policy" "foo" { + org_id = google_apigee_environment.apigee_environment.org_id + env_id = google_apigee_environment.apigee_environment.name + policy_data = data.google_iam_policy.foo.policy_data +} +`, context) +} + +func testAccApigeeEnvironmentIamPolicy_emptyBinding(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_account}" +} + +resource "google_project_service" "apigee" { + project = google_project.project.project_id + service = "apigee.googleapis.com" +} + +resource "google_project_service" "compute" { + project = google_project.project.project_id + service = "compute.googleapis.com" +} + +resource "google_project_service" "servicenetworking" { + project = google_project.project.project_id + service = "servicenetworking.googleapis.com" +} + +resource "google_compute_network" "apigee_network" { + name = "apigee-network" + project = google_project.project.project_id + depends_on = [google_project_service.compute] +} + +resource "google_compute_global_address" "apigee_range" { + name = "apigee-range" + purpose = "VPC_PEERING" + address_type = "INTERNAL" + prefix_length = 16 + network = google_compute_network.apigee_network.id + project = google_project.project.project_id +} + +resource "google_service_networking_connection" "apigee_vpc_connection" { + network = google_compute_network.apigee_network.id + service = "servicenetworking.googleapis.com" + reserved_peering_ranges = [google_compute_global_address.apigee_range.name] + depends_on = [google_project_service.servicenetworking] +} + +resource "google_apigee_organization" "apigee_org" { + analytics_region = "us-central1" + project_id = google_project.project.project_id + authorized_network = google_compute_network.apigee_network.id + depends_on = [ + google_service_networking_connection.apigee_vpc_connection, + google_project_service.apigee, + ] +} + +resource "google_apigee_environment" "apigee_environment" { + org_id = google_apigee_organization.apigee_org.id + name = "tf-test%{random_suffix}" + description = "Apigee Environment" + display_name = "environment-1" +} + +data "google_iam_policy" "foo" { +} + +resource "google_apigee_environment_iam_policy" "foo" { + org_id = google_apigee_environment.apigee_environment.org_id + env_id = google_apigee_environment.apigee_environment.name + policy_data = data.google_iam_policy.foo.policy_data +} +`, context) +} + +func testAccApigeeEnvironmentIamBinding_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_account}" +} + +resource "google_project_service" "apigee" { + project = google_project.project.project_id + service = "apigee.googleapis.com" +} + +resource "google_project_service" "compute" { + project = google_project.project.project_id + service = "compute.googleapis.com" +} + +resource "google_project_service" "servicenetworking" { + project = google_project.project.project_id + service = "servicenetworking.googleapis.com" +} + +resource "google_compute_network" "apigee_network" { + name = "apigee-network" + project = google_project.project.project_id + depends_on = [google_project_service.compute] +} + +resource "google_compute_global_address" "apigee_range" { + name = "apigee-range" + purpose = "VPC_PEERING" + address_type = "INTERNAL" + prefix_length = 16 + network = google_compute_network.apigee_network.id + project = google_project.project.project_id +} + +resource "google_service_networking_connection" "apigee_vpc_connection" { + network = google_compute_network.apigee_network.id + service = "servicenetworking.googleapis.com" + reserved_peering_ranges = [google_compute_global_address.apigee_range.name] + depends_on = [google_project_service.servicenetworking] +} + +resource "google_apigee_organization" "apigee_org" { + analytics_region = "us-central1" + project_id = google_project.project.project_id + authorized_network = google_compute_network.apigee_network.id + depends_on = [ + google_service_networking_connection.apigee_vpc_connection, + google_project_service.apigee, + ] +} + +resource "google_apigee_environment" "apigee_environment" { + org_id = google_apigee_organization.apigee_org.id + name = "tf-test%{random_suffix}" + description = "Apigee Environment" + display_name = "environment-1" +} + +resource "google_apigee_environment_iam_binding" "foo" { + org_id = google_apigee_environment.apigee_environment.org_id + env_id = google_apigee_environment.apigee_environment.name + role = "%{role}" + members = ["user:admin@hashicorptest.com"] +} +`, context) +} + +func testAccApigeeEnvironmentIamBinding_updateGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_account}" +} + +resource "google_project_service" "apigee" { + project = google_project.project.project_id + service = "apigee.googleapis.com" +} + +resource "google_project_service" "compute" { + project = google_project.project.project_id + service = "compute.googleapis.com" +} + +resource "google_project_service" "servicenetworking" { + project = google_project.project.project_id + service = "servicenetworking.googleapis.com" +} + +resource "google_compute_network" "apigee_network" { + name = "apigee-network" + project = google_project.project.project_id + depends_on = [google_project_service.compute] +} + +resource "google_compute_global_address" "apigee_range" { + name = "apigee-range" + purpose = "VPC_PEERING" + address_type = "INTERNAL" + prefix_length = 16 + network = google_compute_network.apigee_network.id + project = google_project.project.project_id +} + +resource "google_service_networking_connection" "apigee_vpc_connection" { + network = google_compute_network.apigee_network.id + service = "servicenetworking.googleapis.com" + reserved_peering_ranges = [google_compute_global_address.apigee_range.name] + depends_on = [google_project_service.servicenetworking] +} + +resource "google_apigee_organization" "apigee_org" { + analytics_region = "us-central1" + project_id = google_project.project.project_id + authorized_network = google_compute_network.apigee_network.id + depends_on = [ + google_service_networking_connection.apigee_vpc_connection, + google_project_service.apigee, + ] +} + +resource "google_apigee_environment" "apigee_environment" { + org_id = google_apigee_organization.apigee_org.id + name = "tf-test%{random_suffix}" + description = "Apigee Environment" + display_name = "environment-1" +} + +resource "google_apigee_environment_iam_binding" "foo" { + org_id = google_apigee_environment.apigee_environment.org_id + env_id = google_apigee_environment.apigee_environment.name + role = "%{role}" + members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"] +} +`, context) +} diff --git a/google-beta/provider.go b/google-beta/provider.go index 0434493f97..095b3de62f 100644 --- a/google-beta/provider.go +++ b/google-beta/provider.go @@ -895,8 +895,8 @@ func Provider() *schema.Provider { } // Generated resources: 240 -// Generated IAM resources: 117 -// Total generated resources: 357 +// Generated IAM resources: 120 +// Total generated resources: 360 func ResourceMap() map[string]*schema.Resource { resourceMap, _ := ResourceMapWithErrors() return resourceMap @@ -933,6 +933,9 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_apigee_organization": resourceApigeeOrganization(), "google_apigee_instance": resourceApigeeInstance(), "google_apigee_environment": resourceApigeeEnvironment(), + "google_apigee_environment_iam_binding": ResourceIamBinding(ApigeeEnvironmentIamSchema, ApigeeEnvironmentIamUpdaterProducer, ApigeeEnvironmentIdParseFunc), + "google_apigee_environment_iam_member": ResourceIamMember(ApigeeEnvironmentIamSchema, ApigeeEnvironmentIamUpdaterProducer, ApigeeEnvironmentIdParseFunc), + "google_apigee_environment_iam_policy": ResourceIamPolicy(ApigeeEnvironmentIamSchema, ApigeeEnvironmentIamUpdaterProducer, ApigeeEnvironmentIdParseFunc), "google_apigee_envgroup": resourceApigeeEnvgroup(), "google_apigee_instance_attachment": resourceApigeeInstanceAttachment(), "google_apigee_envgroup_attachment": resourceApigeeEnvgroupAttachment(), diff --git a/website/docs/r/apigee_environment_iam.html.markdown b/website/docs/r/apigee_environment_iam.html.markdown new file mode 100644 index 0000000000..05acdf74b0 --- /dev/null +++ b/website/docs/r/apigee_environment_iam.html.markdown @@ -0,0 +1,139 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# 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: "Apigee" +layout: "google" +page_title: "Google: google_apigee_environment_iam" +sidebar_current: "docs-google-apigee-environment-iam" +description: |- + Collection of resources to manage IAM policy for Apigee Environment +--- + +# IAM policy for Apigee Environment +Three different resources help you manage your IAM policy for Apigee Environment. Each of these resources serves a different use case: + +* `google_apigee_environment_iam_policy`: Authoritative. Sets the IAM policy for the environment and replaces any existing policy already attached. +* `google_apigee_environment_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 environment are preserved. +* `google_apigee_environment_iam_member`: Non-authoritative. Updates the IAM policy to grant a role to a new member. Other members for the role for the environment are preserved. + +~> **Note:** `google_apigee_environment_iam_policy` **cannot** be used in conjunction with `google_apigee_environment_iam_binding` and `google_apigee_environment_iam_member` or they will fight over what your policy should be. + +~> **Note:** `google_apigee_environment_iam_binding` resources **can be** used in conjunction with `google_apigee_environment_iam_member` resources **only if** they do not grant privilege to the same role. + + + + +## google\_apigee\_environment\_iam\_policy + +```hcl +data "google_iam_policy" "admin" { + binding { + role = "roles/viewer" + members = [ + "user:jane@example.com", + ] + } +} + +resource "google_apigee_environment_iam_policy" "policy" { + org_id = google_apigee_environment.apigee_environment.org_id + env_id = google_apigee_environment.apigee_environment.name + policy_data = data.google_iam_policy.admin.policy_data +} +``` + +## google\_apigee\_environment\_iam\_binding + +```hcl +resource "google_apigee_environment_iam_binding" "binding" { + org_id = google_apigee_environment.apigee_environment.org_id + env_id = google_apigee_environment.apigee_environment.name + role = "roles/viewer" + members = [ + "user:jane@example.com", + ] +} +``` + +## google\_apigee\_environment\_iam\_member + +```hcl +resource "google_apigee_environment_iam_member" "member" { + org_id = google_apigee_environment.apigee_environment.org_id + env_id = google_apigee_environment.apigee_environment.name + role = "roles/viewer" + member = "user:jane@example.com" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `env_id` - (Required) Used to find the parent resource to bind the IAM policy to + +* `member/members` - (Required) Identities that will be granted the privilege in `role`. + Each entry can have one of the following values: + * **allUsers**: A special identifier that represents anyone who is on the internet; with or without a Google account. + * **allAuthenticatedUsers**: A special identifier that represents anyone who is authenticated with a Google account or a service account. + * **user:{emailid}**: An email address that represents a specific Google account. For example, alice@gmail.com or joe@example.com. + * **serviceAccount:{emailid}**: An email address that represents a service account. For example, my-other-app@appspot.gserviceaccount.com. + * **group:{emailid}**: An email address that represents a Google group. For example, admins@example.com. + * **domain:{domain}**: A G Suite domain (primary, instead of alias) name that represents all the users of that domain. For example, google.com or example.com. + * **projectOwner:projectid**: Owners of the given project. For example, "projectOwner:my-example-project" + * **projectEditor:projectid**: Editors of the given project. For example, "projectEditor:my-example-project" + * **projectViewer:projectid**: Viewers of the given project. For example, "projectViewer:my-example-project" + +* `role` - (Required) The role that should be applied. Only one + `google_apigee_environment_iam_binding` can be used per role. Note that custom roles must be of the format + `[projects|organizations]/{parent-name}/roles/{role-name}`. + +* `policy_data` - (Required only by `google_apigee_environment_iam_policy`) The policy data generated by + a `google_iam_policy` data source. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are +exported: + +* `etag` - (Computed) The etag of the IAM policy. + +## Import + +For all import syntaxes, the "resource in question" can take any of the following forms: + +* {{org_id}}/environments/{{name}} +* {{name}} + +Any variables not passed in the import command will be taken from the provider configuration. + +Apigee environment 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_apigee_environment_iam_member.editor "{{org_id}}/environments/{{environment}} roles/viewer user:jane@example.com" +``` + +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` +$ terraform import google_apigee_environment_iam_binding.editor "{{org_id}}/environments/{{environment}} roles/viewer" +``` + +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_apigee_environment_iam_policy.editor {{org_id}}/environments/{{environment}} +``` + +-> **Custom Roles**: If you're importing a IAM resource with a custom role, make sure to use the + full name of the custom role, e.g. `[projects/my-project|organizations/my-org]/roles/my-custom-role`. diff --git a/website/google.erb b/website/google.erb index 40542fb5ff..c6182fe741 100644 --- a/website/google.erb +++ b/website/google.erb @@ -169,6 +169,10 @@ google_apigee_environment +
  • + google_apigee_environment_iam +
  • +
  • google_apigee_instance