From d4e297ec44ae1e9ba22cf130c49e64aad8ec569d Mon Sep 17 00:00:00 2001 From: Vincent Roseberry Date: Wed, 6 Dec 2017 09:33:21 -0800 Subject: [PATCH] Add google_kms_key_ring_iam_policy resource and improve iam docs (#814) * Add google_kms_key_ring_iam_policy resource and improve iam docs * Delete iam_binding and iam_member specific doc page for key ring --- google/provider.go | 1 + .../resource_google_kms_key_ring_iam_test.go | 157 +++++++++++------- .../r/google_kms_crypto_key.html.markdown | 2 +- .../docs/r/google_kms_key_ring.html.markdown | 2 +- .../r/google_kms_key_ring_iam.html.markdown | 92 ++++++++++ ...gle_kms_key_ring_iam_binding.html.markdown | 46 ----- ...ogle_kms_key_ring_iam_member.html.markdown | 47 ------ website/google.erb | 11 +- 8 files changed, 199 insertions(+), 159 deletions(-) create mode 100644 website/docs/r/google_kms_key_ring_iam.html.markdown delete mode 100644 website/docs/r/google_kms_key_ring_iam_binding.html.markdown delete mode 100644 website/docs/r/google_kms_key_ring_iam_member.html.markdown diff --git a/google/provider.go b/google/provider.go index 8c969325..42889b2f 100644 --- a/google/provider.go +++ b/google/provider.go @@ -125,6 +125,7 @@ func Provider() terraform.ResourceProvider { "google_kms_key_ring": resourceKmsKeyRing(), "google_kms_key_ring_iam_binding": ResourceIamBinding(IamKmsKeyRingSchema, NewKmsKeyRingIamUpdater), "google_kms_key_ring_iam_member": ResourceIamMember(IamKmsKeyRingSchema, NewKmsKeyRingIamUpdater), + "google_kms_key_ring_iam_policy": ResourceIamPolicy(IamKmsKeyRingSchema, NewKmsKeyRingIamUpdater), "google_kms_crypto_key": resourceKmsCryptoKey(), "google_kms_crypto_key_iam_binding": ResourceIamBinding(IamKmsCryptoKeySchema, NewKmsCryptoKeyIamUpdater), "google_kms_crypto_key_iam_member": ResourceIamMember(IamKmsCryptoKeySchema, NewKmsCryptoKeyIamUpdater), diff --git a/google/resource_google_kms_key_ring_iam_test.go b/google/resource_google_kms_key_ring_iam_test.go index c27e6bf9..54b2fd88 100644 --- a/google/resource_google_kms_key_ring_iam_test.go +++ b/google/resource_google_kms_key_ring_iam_test.go @@ -10,6 +10,8 @@ import ( "testing" ) +const DEFAULT_KMS_TEST_LOCATION = "us-central1" + func TestAccGoogleKmsKeyRingIamBinding(t *testing.T) { t.Parallel() @@ -20,6 +22,12 @@ func TestAccGoogleKmsKeyRingIamBinding(t *testing.T) { roleId := "roles/cloudkms.cryptoKeyDecrypter" keyRingName := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) + keyRingId := &kmsKeyRingId{ + Project: projectId, + Location: DEFAULT_KMS_TEST_LOCATION, + Name: keyRingName, + } + resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -27,14 +35,14 @@ func TestAccGoogleKmsKeyRingIamBinding(t *testing.T) { { // Test Iam Binding creation Config: testAccGoogleKmsKeyRingIamBinding_basic(projectId, orgId, billingAccount, account, keyRingName, roleId), - Check: testAccCheckGoogleKmsKeyRingIamBindingExists("foo", roleId, []string{ + Check: testAccCheckGoogleKmsKeyRingIam(keyRingId.keyRingId(), roleId, []string{ fmt.Sprintf("serviceAccount:%s@%s.iam.gserviceaccount.com", account, projectId), }), }, { // Test Iam Binding update Config: testAccGoogleKmsKeyRingIamBinding_update(projectId, orgId, billingAccount, account, keyRingName, roleId), - Check: testAccCheckGoogleKmsKeyRingIamBindingExists("foo", roleId, []string{ + Check: testAccCheckGoogleKmsKeyRingIam(keyRingId.keyRingId(), roleId, []string{ fmt.Sprintf("serviceAccount:%s@%s.iam.gserviceaccount.com", account, projectId), fmt.Sprintf("serviceAccount:%s-2@%s.iam.gserviceaccount.com", account, projectId), }), @@ -53,6 +61,12 @@ func TestAccGoogleKmsKeyRingIamMember(t *testing.T) { roleId := "roles/cloudkms.cryptoKeyEncrypter" keyRingName := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) + keyRingId := &kmsKeyRingId{ + Project: projectId, + Location: DEFAULT_KMS_TEST_LOCATION, + Name: keyRingName, + } + resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -60,35 +74,54 @@ func TestAccGoogleKmsKeyRingIamMember(t *testing.T) { { // Test Iam Member creation (no update for member, no need to test) Config: testAccGoogleKmsKeyRingIamMember_basic(projectId, orgId, billingAccount, account, keyRingName, roleId), - Check: testAccCheckGoogleKmsKeyRingIamMemberExists("foo", roleId, + Check: testAccCheckGoogleKmsKeyRingIam(keyRingId.keyRingId(), roleId, []string{ fmt.Sprintf("serviceAccount:%s@%s.iam.gserviceaccount.com", account, projectId), - ), + }), }, }, }) } -func testAccCheckGoogleKmsKeyRingIamBindingExists(bindingResourceName, roleId string, members []string) resource.TestCheckFunc { +func TestAccGoogleKmsKeyRingIamPolicy(t *testing.T) { + t.Parallel() + + orgId := getTestOrgFromEnv(t) + projectId := acctest.RandomWithPrefix("tf-test") + billingAccount := getTestBillingAccountFromEnv(t) + account := acctest.RandomWithPrefix("tf-test") + roleId := "roles/cloudkms.cryptoKeyEncrypter" + keyRingName := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) + + keyRingId := &kmsKeyRingId{ + Project: projectId, + Location: DEFAULT_KMS_TEST_LOCATION, + Name: keyRingName, + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccGoogleKmsKeyRingIamPolicy_basic(projectId, orgId, billingAccount, account, keyRingName, roleId), + Check: testAccCheckGoogleKmsKeyRingIam(keyRingId.keyRingId(), roleId, []string{ + fmt.Sprintf("serviceAccount:%s@%s.iam.gserviceaccount.com", account, projectId), + }), + }, + }, + }) +} + +func testAccCheckGoogleKmsKeyRingIam(keyRingId, role string, members []string) resource.TestCheckFunc { return func(s *terraform.State) error { - bindingRs, ok := s.RootModule().Resources[fmt.Sprintf("google_kms_key_ring_iam_binding.%s", bindingResourceName)] - if !ok { - return fmt.Errorf("Not found: %s", bindingResourceName) - } - config := testAccProvider.Meta().(*Config) - keyRingId, err := parseKmsKeyRingId(bindingRs.Primary.Attributes["key_ring_id"], config) - - if err != nil { - return err - } - - p, err := config.clientKms.Projects.Locations.KeyRings.GetIamPolicy(keyRingId.keyRingId()).Do() + p, err := config.clientKms.Projects.Locations.KeyRings.GetIamPolicy(keyRingId).Do() if err != nil { return err } for _, binding := range p.Bindings { - if binding.Role == roleId { + if binding.Role == role { sort.Strings(members) sort.Strings(binding.Members) @@ -100,41 +133,6 @@ func testAccCheckGoogleKmsKeyRingIamBindingExists(bindingResourceName, roleId st } } - return fmt.Errorf("No binding for role %q", roleId) - } -} - -func testAccCheckGoogleKmsKeyRingIamMemberExists(n, role, member string) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources["google_kms_key_ring_iam_member."+n] - if !ok { - return fmt.Errorf("Not found: %s", n) - } - - config := testAccProvider.Meta().(*Config) - keyRingId, err := parseKmsKeyRingId(rs.Primary.Attributes["key_ring_id"], config) - - if err != nil { - return err - } - - p, err := config.clientKms.Projects.Locations.KeyRings.GetIamPolicy(keyRingId.keyRingId()).Do() - if err != nil { - return err - } - - for _, binding := range p.Bindings { - if binding.Role == role { - for _, m := range binding.Members { - if m == member { - return nil - } - } - - return fmt.Errorf("Missing member %q, got %v", member, binding.Members) - } - } - return fmt.Errorf("No binding for role %q", role) } } @@ -211,7 +209,7 @@ resource "google_service_account" "test_account_2" { resource "google_kms_key_ring" "key_ring" { project = "${google_project_services.test_project.project}" - location = "us-central1" + location = "%s" name = "%s" } @@ -223,7 +221,7 @@ resource "google_kms_key_ring_iam_binding" "foo" { "serviceAccount:${google_service_account.test_account_2.email}" ] } -`, projectId, orgId, billingAccount, account, account, keyRingName, roleId) +`, projectId, orgId, billingAccount, account, account, DEFAULT_KMS_TEST_LOCATION, keyRingName, roleId) } func testAccGoogleKmsKeyRingIamMember_basic(projectId, orgId, billingAccount, account, keyRingName, roleId string) string { @@ -252,7 +250,7 @@ resource "google_service_account" "test_account" { resource "google_kms_key_ring" "key_ring" { project = "${google_project_services.test_project.project}" - location = "us-central1" + location = "%s" name = "%s" } @@ -261,5 +259,50 @@ resource "google_kms_key_ring_iam_member" "foo" { role = "%s" member = "serviceAccount:${google_service_account.test_account.email}" } -`, projectId, orgId, billingAccount, account, keyRingName, roleId) +`, projectId, orgId, billingAccount, account, DEFAULT_KMS_TEST_LOCATION, keyRingName, roleId) +} + +func testAccGoogleKmsKeyRingIamPolicy_basic(projectId, orgId, billingAccount, account, keyRingName, roleId string) string { + return fmt.Sprintf(` +resource "google_project" "test_project" { + name = "Test project" + project_id = "%s" + org_id = "%s" + billing_account = "%s" +} + +resource "google_project_services" "test_project" { + project = "${google_project.test_project.project_id}" + + services = [ + "cloudkms.googleapis.com", + "iam.googleapis.com", + ] +} + +resource "google_service_account" "test_account" { + project = "${google_project_services.test_project.project}" + account_id = "%s" + display_name = "Iam Testing Account" +} + +resource "google_kms_key_ring" "key_ring" { + project = "${google_project_services.test_project.project}" + location = "%s" + name = "%s" +} + +data "google_iam_policy" "foo" { + binding { + role = "%s" + + members = ["serviceAccount:${google_service_account.test_account.email}"] + } +} + +resource "google_kms_key_ring_iam_policy" "foo" { + key_ring_id = "${google_kms_key_ring.key_ring.id}" + policy_data = "${data.google_iam_policy.foo.policy_data}" +} +`, projectId, orgId, billingAccount, account, DEFAULT_KMS_TEST_LOCATION, keyRingName, roleId) } diff --git a/website/docs/r/google_kms_crypto_key.html.markdown b/website/docs/r/google_kms_crypto_key.html.markdown index 081f9c48..3ae2182f 100644 --- a/website/docs/r/google_kms_crypto_key.html.markdown +++ b/website/docs/r/google_kms_crypto_key.html.markdown @@ -1,7 +1,7 @@ --- layout: "google" page_title: "Google: google_kms_crypto_key" -sidebar_current: "docs-google-kms-crypto-key" +sidebar_current: "docs-google-kms-crypto-key-x" description: |- Allows creation of a Google Cloud Platform KMS CryptoKey. --- diff --git a/website/docs/r/google_kms_key_ring.html.markdown b/website/docs/r/google_kms_key_ring.html.markdown index 4e9700e6..323c689a 100644 --- a/website/docs/r/google_kms_key_ring.html.markdown +++ b/website/docs/r/google_kms_key_ring.html.markdown @@ -1,7 +1,7 @@ --- layout: "google" page_title: "Google: google_kms_key_ring" -sidebar_current: "docs-google-kms-key-ring" +sidebar_current: "docs-google-kms-key-ring-x" description: |- Allows creation of a Google Cloud Platform KMS KeyRing. --- diff --git a/website/docs/r/google_kms_key_ring_iam.html.markdown b/website/docs/r/google_kms_key_ring_iam.html.markdown new file mode 100644 index 00000000..aab2b01a --- /dev/null +++ b/website/docs/r/google_kms_key_ring_iam.html.markdown @@ -0,0 +1,92 @@ +--- +layout: "google" +page_title: "Google: google_kms_key_ring_iam" +sidebar_current: "docs-google-kms-key-ring-iam" +description: |- + Collection of resources to manage IAM policy for a Google Cloud KMS key ring. +--- + +# IAM policy for Google Cloud KMS key ring + +Three different resources help you manage your IAM policy for KMS key ring. Each of these resources serves a different use case: + +* `google_kms_key_ring_iam_policy`: Authoritative. Sets the IAM policy for the key ring and replaces any existing policy already attached. +* `google_kms_key_ring_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 key ring are preserved. +* `google_kms_key_ring_iam_member`: Non-authoritative. Updates the IAM policy to grant a role to a new member. Other members for the role for the key ring are preserved. + +~> **Note:** `google_kms_key_ring_iam_policy` **cannot** be used in conjunction with `google_kms_key_ring_iam_binding` and `google_kms_key_ring_iam_member` or they will fight over what your policy should be. + +~> **Note:** `google_kms_key_ring_iam_binding` resources **can be** used in conjunction with `google_kms_key_ring_iam_member` resources **only if** they do not grant privilege to the same role. + +## google\_kms\_key\_ring\_iam\_policy + +```hcl +data "google_iam_policy" "admin" { + binding { + role = "roles/editor" + + members = [ + "user:jane@example.com", + ] + } +} + +resource "google_kms_key_ring_iam_policy" "key_ring" { + key_ring_id = "your-key-ring-id" + policy_data = "${data.google_iam_policy.admin.policy_data}" +} +``` + +## google\_kms\_key\_ring\_iam\_binding + +```hcl +resource "google_kms_key_ring_binding" "key_ring" { + key_ring_id = "your-key-ring-id" + role = "roles/editor" + + members = [ + "user:jane@example.com", + ] +} +``` + +## google\_kms\_key\_ring\_iam\_member + +```hcl +resource "google_kms_key_ring_iam_member" "key_ring" { + key_ring_id = "your-key-ring-id" + role = "roles/editor" + member = "user:jane@example.com" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `key_ring_id` - (Required) The key ring ID, in the form + `{project_id}/{location_name}/{key_ring_name}` or + `{location_name}/{key_ring_name}`. In the second form, the provider's + project setting will be used as a fallback. + +* `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 Google Apps domain name that represents all the users of that domain. For example, google.com or example.com. + +* `role` - (Required) The role that should be applied. Only one + `google_kms_key_ring_iam_binding` can be used per role. + +* `policy_data` - (Required only by `google_kms_key_ring_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 key ring's IAM policy. diff --git a/website/docs/r/google_kms_key_ring_iam_binding.html.markdown b/website/docs/r/google_kms_key_ring_iam_binding.html.markdown deleted file mode 100644 index 5e0fda3b..00000000 --- a/website/docs/r/google_kms_key_ring_iam_binding.html.markdown +++ /dev/null @@ -1,46 +0,0 @@ ---- -layout: "google" -page_title: "Google: google_kms_key_ring_iam_binding" -sidebar_current: "docs-google-kms-key-ring-iam-binding" -description: |- - Allows management of a single binding with an IAM policy for a Google Cloud KMS key ring ---- - -# google\_kms\_key\_ring\_iam\_binding - -Allows creation and management of a single binding within IAM policy for -an existing Google Cloud KMS key ring. - -## Example Usage - -```hcl -resource "google_kms_key_ring_binding" "key_ring" { - key_ring_id = "your-key-ring-id" - role = "roles/editor" - - members = [ - "user:jane@example.com", - ] -} -``` - -## Argument Reference - -The following arguments are supported: - -* `members` - (Required) A list of users that the role should apply to. - -* `role` - (Required) The role that should be applied. Only one - `google_kms_key_ring_iam_binding` can be used per role. - -* `key_ring_id` - (Required) The key ring ID, in the form - `{project_id}/{location_name}/{key_ring_name}` or - `{location_name}/{key_ring_name}`. In the second form, the provider's - project setting will be used as a fallback. -## Attributes Reference - -In addition to the arguments listed above, the following computed attributes are -exported: - -* `etag` - (Computed) The etag of the key ring's IAM policy. - diff --git a/website/docs/r/google_kms_key_ring_iam_member.html.markdown b/website/docs/r/google_kms_key_ring_iam_member.html.markdown deleted file mode 100644 index ceab314a..00000000 --- a/website/docs/r/google_kms_key_ring_iam_member.html.markdown +++ /dev/null @@ -1,47 +0,0 @@ ---- -layout: "google" -page_title: "Google: google_kms_key_ring_iam_member" -sidebar_current: "docs-google-kms-key-ring-iam-member" -description: |- - Allows management of a single member for a single binding on the IAM policy for a Google Cloud KMS key ring. ---- - -# google\_kms\_key\_ring\_iam\_member - -Allows creation and management of a single member for a single binding within -the IAM policy for an existing Google Cloud KMS key ring. - -~> **Note:** This resource _must not_ be used in conjunction with - `google_kms_key_ring_iam_policy` or they will fight over what your policy - should be. Similarly, roles controlled by `google_kms_key_ring_iam_binding` - should not be assigned to using `google_kms_key_ring_iam_member`. - -## Example Usage - -```hcl -resource "google_kms_key_ring_iam_member" "key_ring" { - key_ring_id = "your-key-ring-id" - role = "roles/editor" - member = "user:jane@example.com" -} -``` - -## Argument Reference - -The following arguments are supported: - -* `member` - (Required) The user that the role should apply to. - -* `role` - (Required) The role that should be applied. - -* `key_ring_id` - (Required) The key ring ID, in the form - `{project_id}/{location_name}/{key_ring_name}` or - `{location_name}/{key_ring_name}`. In the second form, the provider's - project setting will be used as a fallback. - -## Attributes Reference - -In addition to the arguments listed above, the following computed attributes are -exported: - -* `etag` - (Computed) The etag of the project's IAM policy. diff --git a/website/google.erb b/website/google.erb index 03656704..d4281ba6 100644 --- a/website/google.erb +++ b/website/google.erb @@ -447,16 +447,13 @@ > Google Key Management Service Resources