mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-01 16:21:06 +00:00
Consistent IAM resource imports. (#835)
Add consistency for for IAM imports. - Adds imports for projects, folders, crypto keys, organizations, and key rings. - Anything else with IAM can implement a simple method and begin working immediately. - Add tests for all the IAM imports. - Import documentation for IAM resources.
This commit is contained in:
parent
bf235ebc04
commit
ced8cb506c
@ -34,6 +34,14 @@ type ResourceIamUpdater interface {
|
|||||||
type newResourceIamUpdaterFunc func(d *schema.ResourceData, config *Config) (ResourceIamUpdater, error)
|
type newResourceIamUpdaterFunc func(d *schema.ResourceData, config *Config) (ResourceIamUpdater, error)
|
||||||
type iamPolicyModifyFunc func(p *cloudresourcemanager.Policy) error
|
type iamPolicyModifyFunc func(p *cloudresourcemanager.Policy) error
|
||||||
|
|
||||||
|
// This method parses identifiers specific to the resource (d.GetId()) into the ResourceData
|
||||||
|
// object, so that it can be given to the resource's Read method. Externally, this is wrapped
|
||||||
|
// into schema.StateFunc functions - one each for a _member, a _binding, and a _policy. Any
|
||||||
|
// GCP resource supporting IAM policy might support one, two, or all of these. Any GCP resource
|
||||||
|
// for which an implementation of this interface exists could support any of the three.
|
||||||
|
|
||||||
|
type resourceIdParserFunc func(d *schema.ResourceData, config *Config) error
|
||||||
|
|
||||||
func iamPolicyReadModifyWrite(updater ResourceIamUpdater, modify iamPolicyModifyFunc) error {
|
func iamPolicyReadModifyWrite(updater ResourceIamUpdater, modify iamPolicyModifyFunc) error {
|
||||||
mutexKey := updater.GetMutexKey()
|
mutexKey := updater.GetMutexKey()
|
||||||
mutexKV.Lock(mutexKey)
|
mutexKV.Lock(mutexKey)
|
||||||
|
@ -28,6 +28,11 @@ func NewFolderIamUpdater(d *schema.ResourceData, config *Config) (ResourceIamUpd
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FolderIdParseFunc(d *schema.ResourceData, _ *Config) error {
|
||||||
|
d.Set("folder", d.Id())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (u *FolderIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) {
|
func (u *FolderIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) {
|
||||||
p, err := u.Config.clientResourceManagerV2Beta1.Folders.GetIamPolicy(u.folderId,
|
p, err := u.Config.clientResourceManagerV2Beta1.Folders.GetIamPolicy(u.folderId,
|
||||||
&resourceManagerV2Beta1.GetIamPolicyRequest{}).Do()
|
&resourceManagerV2Beta1.GetIamPolicyRequest{}).Do()
|
||||||
|
@ -34,6 +34,11 @@ func NewKmsCryptoKeyIamUpdater(d *schema.ResourceData, config *Config) (Resource
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CryptoIdParseFunc(d *schema.ResourceData, _ *Config) error {
|
||||||
|
d.Set("crypto_key_id", d.Id())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (u *KmsCryptoKeyIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) {
|
func (u *KmsCryptoKeyIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) {
|
||||||
p, err := u.Config.clientKms.Projects.Locations.KeyRings.CryptoKeys.GetIamPolicy(u.resourceId).Do()
|
p, err := u.Config.clientKms.Projects.Locations.KeyRings.CryptoKeys.GetIamPolicy(u.resourceId).Do()
|
||||||
|
|
||||||
|
@ -34,6 +34,11 @@ func NewKmsKeyRingIamUpdater(d *schema.ResourceData, config *Config) (ResourceIa
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func KeyRingIdParseFunc(d *schema.ResourceData, _ *Config) error {
|
||||||
|
d.Set("key_ring_id", d.Id())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func resourceManagerToKmsPolicy(p *cloudresourcemanager.Policy) (policy *cloudkms.Policy, err error) {
|
func resourceManagerToKmsPolicy(p *cloudresourcemanager.Policy) (policy *cloudkms.Policy, err error) {
|
||||||
policy = &cloudkms.Policy{}
|
policy = &cloudkms.Policy{}
|
||||||
|
|
||||||
|
@ -26,6 +26,11 @@ func NewOrganizationIamUpdater(d *schema.ResourceData, config *Config) (Resource
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func OrgIdParseFunc(d *schema.ResourceData, _ *Config) error {
|
||||||
|
d.Set("org_id", d.Id())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (u *OrganizationIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) {
|
func (u *OrganizationIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) {
|
||||||
p, err := u.Config.clientResourceManager.Organizations.GetIamPolicy("organizations/"+u.resourceId, &cloudresourcemanager.GetIamPolicyRequest{}).Do()
|
p, err := u.Config.clientResourceManager.Organizations.GetIamPolicy("organizations/"+u.resourceId, &cloudresourcemanager.GetIamPolicyRequest{}).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -31,6 +31,11 @@ func NewProjectIamUpdater(d *schema.ResourceData, config *Config) (ResourceIamUp
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ProjectIdParseFunc(d *schema.ResourceData, _ *Config) error {
|
||||||
|
d.Set("project", d.Id())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (u *ProjectIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) {
|
func (u *ProjectIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) {
|
||||||
p, err := u.Config.clientResourceManager.Projects.GetIamPolicy(u.resourceId,
|
p, err := u.Config.clientResourceManager.Projects.GetIamPolicy(u.resourceId,
|
||||||
&cloudresourcemanager.GetIamPolicyRequest{}).Do()
|
&cloudresourcemanager.GetIamPolicyRequest{}).Do()
|
||||||
|
75
google/import_google_kms_crypto_key_iam_test.go
Normal file
75
google/import_google_kms_crypto_key_iam_test.go
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/acctest"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccKmsCryptoKeyIamMember_importBasic(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,
|
||||||
|
}
|
||||||
|
cryptoKeyName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGoogleKmsCryptoKeyIamMember_basic(projectId, orgId, billingAccount, account, keyRingName, cryptoKeyName, roleId),
|
||||||
|
},
|
||||||
|
|
||||||
|
resource.TestStep{
|
||||||
|
ResourceName: "google_kms_crypto_key_iam_member.foo",
|
||||||
|
ImportStateId: fmt.Sprintf("%s/%s %s serviceAccount:%s@%s.iam.gserviceaccount.com", keyRingId.terraformId(), cryptoKeyName, roleId, account, projectId),
|
||||||
|
ImportState: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccKmsCryptoKeyIamBinding_importBasic(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,
|
||||||
|
}
|
||||||
|
cryptoKeyName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGoogleKmsCryptoKeyIamBinding_basic(projectId, orgId, billingAccount, account, keyRingName, cryptoKeyName, roleId),
|
||||||
|
},
|
||||||
|
|
||||||
|
resource.TestStep{
|
||||||
|
ResourceName: "google_kms_crypto_key_iam_binding.foo",
|
||||||
|
ImportStateId: fmt.Sprintf("%s/%s %s", keyRingId.terraformId(), cryptoKeyName, roleId),
|
||||||
|
ImportState: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
104
google/import_google_kms_key_ring_iam_test.go
Normal file
104
google/import_google_kms_key_ring_iam_test.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/acctest"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccKmsKeyRingIamMember_importBasic(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{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGoogleKmsKeyRingIamMember_basic(projectId, orgId, billingAccount, account, keyRingName, roleId),
|
||||||
|
},
|
||||||
|
|
||||||
|
resource.TestStep{
|
||||||
|
ResourceName: "google_kms_key_ring_iam_member.foo",
|
||||||
|
ImportStateId: fmt.Sprintf("%s %s serviceAccount:%s@%s.iam.gserviceaccount.com", keyRingId.terraformId(), roleId, account, projectId),
|
||||||
|
ImportState: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccKmsKeyRingIamPolicy_importBasic(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{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGoogleKmsKeyRingIamPolicy_basic(projectId, orgId, billingAccount, account, keyRingName, roleId),
|
||||||
|
},
|
||||||
|
|
||||||
|
resource.TestStep{
|
||||||
|
ResourceName: "google_kms_key_ring_iam_policy.foo",
|
||||||
|
ImportStateId: keyRingId.terraformId(),
|
||||||
|
ImportState: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccKmsKeyRingIamBinding_importBasic(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{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGoogleKmsKeyRingIamBinding_basic(projectId, orgId, billingAccount, account, keyRingName, roleId),
|
||||||
|
},
|
||||||
|
|
||||||
|
resource.TestStep{
|
||||||
|
ResourceName: "google_kms_key_ring_iam_binding.foo",
|
||||||
|
ImportStateId: fmt.Sprintf("%s %s", keyRingId.terraformId(), roleId),
|
||||||
|
ImportState: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
57
google/import_google_organization_iam_test.go
Normal file
57
google/import_google_organization_iam_test.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/acctest"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccGoogleOrganizationIamMember_importBasic(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
orgId := getTestOrgFromEnv(t)
|
||||||
|
account := acctest.RandomWithPrefix("tf-test")
|
||||||
|
projectId := getTestProjectFromEnv()
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGoogleOrganizationIamMember_basic(account, orgId),
|
||||||
|
},
|
||||||
|
|
||||||
|
resource.TestStep{
|
||||||
|
ResourceName: "google_organization_iam_member.foo",
|
||||||
|
ImportStateId: fmt.Sprintf("%s roles/browser serviceAccount:%s@%s.iam.gserviceaccount.com", orgId, account, projectId),
|
||||||
|
ImportState: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccGoogleOrganizationIamBinding_importBasic(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
orgId := getTestOrgFromEnv(t)
|
||||||
|
account := acctest.RandomWithPrefix("tf-test")
|
||||||
|
roleId := "tfIamTest" + acctest.RandString(10)
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGoogleOrganizationIamBinding_basic(account, roleId, orgId),
|
||||||
|
},
|
||||||
|
|
||||||
|
resource.TestStep{
|
||||||
|
ResourceName: "google_organization_iam_binding.foo",
|
||||||
|
ImportStateId: fmt.Sprintf("%s organizations/%s/roles/%s", orgId, orgId, roleId),
|
||||||
|
ImportState: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
57
google/import_google_project_iam_test.go
Normal file
57
google/import_google_project_iam_test.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/acctest"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccGoogleProjectIamMember_importBasic(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
resourceName := "google_project_iam_member.acceptance"
|
||||||
|
org := getTestOrgFromEnv(t)
|
||||||
|
pid := "terraform-" + acctest.RandString(10)
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGoogleProjectAssociateMemberBasic(pid, "Acceptance", org),
|
||||||
|
},
|
||||||
|
|
||||||
|
resource.TestStep{
|
||||||
|
ResourceName: resourceName,
|
||||||
|
ImportStateId: fmt.Sprintf("%s %s %s", pid, "roles/compute.instanceAdmin", "user:admin@hashicorptest.com"),
|
||||||
|
ImportState: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccGoogleProjectIamBinding_importBasic(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
resourceName := "google_project_iam_binding.acceptance"
|
||||||
|
org := getTestOrgFromEnv(t)
|
||||||
|
pid := "terraform-" + acctest.RandString(10)
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGoogleProjectAssociateBindingBasic(pid, "Acceptance", org),
|
||||||
|
},
|
||||||
|
|
||||||
|
resource.TestStep{
|
||||||
|
ResourceName: resourceName,
|
||||||
|
ImportStateId: fmt.Sprintf("%s %s", pid, "roles/compute.instanceAdmin"),
|
||||||
|
ImportState: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
@ -129,32 +129,32 @@ func Provider() terraform.ResourceProvider {
|
|||||||
"google_dns_managed_zone": resourceDnsManagedZone(),
|
"google_dns_managed_zone": resourceDnsManagedZone(),
|
||||||
"google_dns_record_set": resourceDnsRecordSet(),
|
"google_dns_record_set": resourceDnsRecordSet(),
|
||||||
"google_folder": resourceGoogleFolder(),
|
"google_folder": resourceGoogleFolder(),
|
||||||
"google_folder_iam_policy": ResourceIamPolicy(IamFolderSchema, NewFolderIamUpdater),
|
"google_folder_iam_policy": ResourceIamPolicyWithImport(IamFolderSchema, NewFolderIamUpdater, FolderIdParseFunc),
|
||||||
"google_folder_organization_policy": resourceGoogleFolderOrganizationPolicy(),
|
"google_folder_organization_policy": resourceGoogleFolderOrganizationPolicy(),
|
||||||
"google_logging_billing_account_sink": resourceLoggingBillingAccountSink(),
|
"google_logging_billing_account_sink": resourceLoggingBillingAccountSink(),
|
||||||
"google_logging_folder_sink": resourceLoggingFolderSink(),
|
"google_logging_folder_sink": resourceLoggingFolderSink(),
|
||||||
"google_logging_project_sink": resourceLoggingProjectSink(),
|
"google_logging_project_sink": resourceLoggingProjectSink(),
|
||||||
"google_kms_key_ring": resourceKmsKeyRing(),
|
"google_kms_key_ring": resourceKmsKeyRing(),
|
||||||
"google_kms_key_ring_iam_binding": ResourceIamBinding(IamKmsKeyRingSchema, NewKmsKeyRingIamUpdater),
|
"google_kms_key_ring_iam_binding": ResourceIamBindingWithImport(IamKmsKeyRingSchema, NewKmsKeyRingIamUpdater, KeyRingIdParseFunc),
|
||||||
"google_kms_key_ring_iam_member": ResourceIamMember(IamKmsKeyRingSchema, NewKmsKeyRingIamUpdater),
|
"google_kms_key_ring_iam_member": ResourceIamMemberWithImport(IamKmsKeyRingSchema, NewKmsKeyRingIamUpdater, KeyRingIdParseFunc),
|
||||||
"google_kms_key_ring_iam_policy": ResourceIamPolicy(IamKmsKeyRingSchema, NewKmsKeyRingIamUpdater),
|
"google_kms_key_ring_iam_policy": ResourceIamPolicyWithImport(IamKmsKeyRingSchema, NewKmsKeyRingIamUpdater, KeyRingIdParseFunc),
|
||||||
"google_kms_crypto_key": resourceKmsCryptoKey(),
|
"google_kms_crypto_key": resourceKmsCryptoKey(),
|
||||||
"google_kms_crypto_key_iam_binding": ResourceIamBinding(IamKmsCryptoKeySchema, NewKmsCryptoKeyIamUpdater),
|
"google_kms_crypto_key_iam_binding": ResourceIamBindingWithImport(IamKmsCryptoKeySchema, NewKmsCryptoKeyIamUpdater, CryptoIdParseFunc),
|
||||||
"google_kms_crypto_key_iam_member": ResourceIamMember(IamKmsCryptoKeySchema, NewKmsCryptoKeyIamUpdater),
|
"google_kms_crypto_key_iam_member": ResourceIamMemberWithImport(IamKmsCryptoKeySchema, NewKmsCryptoKeyIamUpdater, CryptoIdParseFunc),
|
||||||
"google_sourcerepo_repository": resourceSourceRepoRepository(),
|
"google_sourcerepo_repository": resourceSourceRepoRepository(),
|
||||||
"google_spanner_instance": resourceSpannerInstance(),
|
"google_spanner_instance": resourceSpannerInstance(),
|
||||||
"google_spanner_database": resourceSpannerDatabase(),
|
"google_spanner_database": resourceSpannerDatabase(),
|
||||||
"google_sql_database": resourceSqlDatabase(),
|
"google_sql_database": resourceSqlDatabase(),
|
||||||
"google_sql_database_instance": resourceSqlDatabaseInstance(),
|
"google_sql_database_instance": resourceSqlDatabaseInstance(),
|
||||||
"google_sql_user": resourceSqlUser(),
|
"google_sql_user": resourceSqlUser(),
|
||||||
"google_organization_iam_binding": ResourceIamBinding(IamOrganizationSchema, NewOrganizationIamUpdater),
|
"google_organization_iam_binding": ResourceIamBindingWithImport(IamOrganizationSchema, NewOrganizationIamUpdater, OrgIdParseFunc),
|
||||||
"google_organization_iam_custom_role": resourceGoogleOrganizationIamCustomRole(),
|
"google_organization_iam_custom_role": resourceGoogleOrganizationIamCustomRole(),
|
||||||
"google_organization_iam_member": ResourceIamMember(IamOrganizationSchema, NewOrganizationIamUpdater),
|
"google_organization_iam_member": ResourceIamMemberWithImport(IamOrganizationSchema, NewOrganizationIamUpdater, OrgIdParseFunc),
|
||||||
"google_organization_policy": resourceGoogleOrganizationPolicy(),
|
"google_organization_policy": resourceGoogleOrganizationPolicy(),
|
||||||
"google_project": resourceGoogleProject(),
|
"google_project": resourceGoogleProject(),
|
||||||
"google_project_iam_policy": resourceGoogleProjectIamPolicy(),
|
"google_project_iam_policy": resourceGoogleProjectIamPolicy(),
|
||||||
"google_project_iam_binding": ResourceIamBinding(IamProjectSchema, NewProjectIamUpdater),
|
"google_project_iam_binding": ResourceIamBindingWithImport(IamProjectSchema, NewProjectIamUpdater, ProjectIdParseFunc),
|
||||||
"google_project_iam_member": ResourceIamMember(IamProjectSchema, NewProjectIamUpdater),
|
"google_project_iam_member": ResourceIamMemberWithImport(IamProjectSchema, NewProjectIamUpdater, ProjectIdParseFunc),
|
||||||
"google_project_service": resourceGoogleProjectService(),
|
"google_project_service": resourceGoogleProjectService(),
|
||||||
"google_project_iam_custom_role": resourceGoogleProjectIamCustomRole(),
|
"google_project_iam_custom_role": resourceGoogleProjectIamCustomRole(),
|
||||||
"google_project_services": resourceGoogleProjectServices(),
|
"google_project_services": resourceGoogleProjectServices(),
|
||||||
|
@ -17,6 +17,9 @@ func resourceGoogleProjectIamPolicy() *schema.Resource {
|
|||||||
Read: resourceGoogleProjectIamPolicyRead,
|
Read: resourceGoogleProjectIamPolicyRead,
|
||||||
Update: resourceGoogleProjectIamPolicyUpdate,
|
Update: resourceGoogleProjectIamPolicyUpdate,
|
||||||
Delete: resourceGoogleProjectIamPolicyDelete,
|
Delete: resourceGoogleProjectIamPolicyDelete,
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: schema.ImportStatePassthrough,
|
||||||
|
},
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
"project": &schema.Schema{
|
"project": &schema.Schema{
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
package google
|
package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
"google.golang.org/api/cloudresourcemanager/v1"
|
"google.golang.org/api/cloudresourcemanager/v1"
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var iamBindingSchema = map[string]*schema.Schema{
|
var iamBindingSchema = map[string]*schema.Schema{
|
||||||
@ -31,11 +34,18 @@ func ResourceIamBinding(parentSpecificSchema map[string]*schema.Schema, newUpdat
|
|||||||
Read: resourceIamBindingRead(newUpdaterFunc),
|
Read: resourceIamBindingRead(newUpdaterFunc),
|
||||||
Update: resourceIamBindingUpdate(newUpdaterFunc),
|
Update: resourceIamBindingUpdate(newUpdaterFunc),
|
||||||
Delete: resourceIamBindingDelete(newUpdaterFunc),
|
Delete: resourceIamBindingDelete(newUpdaterFunc),
|
||||||
|
|
||||||
Schema: mergeSchemas(iamBindingSchema, parentSpecificSchema),
|
Schema: mergeSchemas(iamBindingSchema, parentSpecificSchema),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ResourceIamBindingWithImport(parentSpecificSchema map[string]*schema.Schema, newUpdaterFunc newResourceIamUpdaterFunc, resourceIdParser resourceIdParserFunc) *schema.Resource {
|
||||||
|
r := ResourceIamBinding(parentSpecificSchema, newUpdaterFunc)
|
||||||
|
r.Importer = &schema.ResourceImporter{
|
||||||
|
State: iamBindingImport(resourceIdParser),
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
func resourceIamBindingCreate(newUpdaterFunc newResourceIamUpdaterFunc) schema.CreateFunc {
|
func resourceIamBindingCreate(newUpdaterFunc newResourceIamUpdaterFunc) schema.CreateFunc {
|
||||||
return func(d *schema.ResourceData, meta interface{}) error {
|
return func(d *schema.ResourceData, meta interface{}) error {
|
||||||
config := meta.(*Config)
|
config := meta.(*Config)
|
||||||
@ -96,6 +106,38 @@ func resourceIamBindingRead(newUpdaterFunc newResourceIamUpdaterFunc) schema.Rea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func iamBindingImport(resourceIdParser resourceIdParserFunc) schema.StateFunc {
|
||||||
|
return func(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
|
||||||
|
if resourceIdParser == nil {
|
||||||
|
return nil, errors.New("Import not supported for this IAM resource.")
|
||||||
|
}
|
||||||
|
config := m.(*Config)
|
||||||
|
s := strings.Split(d.Id(), " ")
|
||||||
|
if len(s) != 2 {
|
||||||
|
d.SetId("")
|
||||||
|
return nil, fmt.Errorf("Wrong number of parts to Binding id %s; expected 'resource_name role'.", s)
|
||||||
|
}
|
||||||
|
id, role := s[0], s[1]
|
||||||
|
d.SetId(id)
|
||||||
|
d.Set("role", role)
|
||||||
|
err := resourceIdParser(d, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// It is possible to return multiple bindings, since we can learn about all the bindings
|
||||||
|
// for this resource here. Unfortunately, `terraform import` has some messy behavior here -
|
||||||
|
// there's no way to know at this point which resource is being imported, so it's not possible
|
||||||
|
// to order this list in a useful way. In the event of a complex set of bindings, the user
|
||||||
|
// will have a terribly confusing set of imported resources and no way to know what matches
|
||||||
|
// up to what. And since the only users who will do a terraform import on their IAM bindings
|
||||||
|
// are users who aren't too familiar with Google Cloud IAM (because a "create" for bindings or
|
||||||
|
// members is idempotent), it's reasonable to expect that the user will be very alarmed by the
|
||||||
|
// plan that terraform will output which mentions destroying a dozen-plus IAM bindings. With
|
||||||
|
// that in mind, we return only the binding that matters.
|
||||||
|
return []*schema.ResourceData{d}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func resourceIamBindingUpdate(newUpdaterFunc newResourceIamUpdaterFunc) schema.UpdateFunc {
|
func resourceIamBindingUpdate(newUpdaterFunc newResourceIamUpdaterFunc) schema.UpdateFunc {
|
||||||
return func(d *schema.ResourceData, meta interface{}) error {
|
return func(d *schema.ResourceData, meta interface{}) error {
|
||||||
config := meta.(*Config)
|
config := meta.(*Config)
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
package google
|
package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
"google.golang.org/api/cloudresourcemanager/v1"
|
"google.golang.org/api/cloudresourcemanager/v1"
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var IamMemberBaseSchema = map[string]*schema.Schema{
|
var IamMemberBaseSchema = map[string]*schema.Schema{
|
||||||
@ -23,6 +26,29 @@ var IamMemberBaseSchema = map[string]*schema.Schema{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func iamMemberImport(resourceIdParser resourceIdParserFunc) schema.StateFunc {
|
||||||
|
return func(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
|
||||||
|
if resourceIdParser == nil {
|
||||||
|
return nil, errors.New("Import not supported for this IAM resource.")
|
||||||
|
}
|
||||||
|
config := m.(*Config)
|
||||||
|
s := strings.Split(d.Id(), " ")
|
||||||
|
if len(s) != 3 {
|
||||||
|
d.SetId("")
|
||||||
|
return nil, fmt.Errorf("Wrong number of parts to Member id %s; expected 'resource_name role username'.", s)
|
||||||
|
}
|
||||||
|
id, role, member := s[0], s[1], s[2]
|
||||||
|
d.SetId(id)
|
||||||
|
d.Set("role", role)
|
||||||
|
d.Set("member", member)
|
||||||
|
err := resourceIdParser(d, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []*schema.ResourceData{d}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ResourceIamMember(parentSpecificSchema map[string]*schema.Schema, newUpdaterFunc newResourceIamUpdaterFunc) *schema.Resource {
|
func ResourceIamMember(parentSpecificSchema map[string]*schema.Schema, newUpdaterFunc newResourceIamUpdaterFunc) *schema.Resource {
|
||||||
return &schema.Resource{
|
return &schema.Resource{
|
||||||
Create: resourceIamMemberCreate(newUpdaterFunc),
|
Create: resourceIamMemberCreate(newUpdaterFunc),
|
||||||
@ -33,6 +59,14 @@ func ResourceIamMember(parentSpecificSchema map[string]*schema.Schema, newUpdate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ResourceIamMemberWithImport(parentSpecificSchema map[string]*schema.Schema, newUpdaterFunc newResourceIamUpdaterFunc, resourceIdParser resourceIdParserFunc) *schema.Resource {
|
||||||
|
r := ResourceIamMember(parentSpecificSchema, newUpdaterFunc)
|
||||||
|
r.Importer = &schema.ResourceImporter{
|
||||||
|
State: iamMemberImport(resourceIdParser),
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
func getResourceIamMember(d *schema.ResourceData) *cloudresourcemanager.Binding {
|
func getResourceIamMember(d *schema.ResourceData) *cloudresourcemanager.Binding {
|
||||||
return &cloudresourcemanager.Binding{
|
return &cloudresourcemanager.Binding{
|
||||||
Members: []string{d.Get("member").(string)},
|
Members: []string{d.Get("member").(string)},
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"google.golang.org/api/cloudresourcemanager/v1"
|
"google.golang.org/api/cloudresourcemanager/v1"
|
||||||
)
|
)
|
||||||
@ -21,6 +22,20 @@ var IamPolicyBaseSchema = map[string]*schema.Schema{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func iamPolicyImport(resourceIdParser resourceIdParserFunc) schema.StateFunc {
|
||||||
|
return func(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
|
||||||
|
if resourceIdParser == nil {
|
||||||
|
return nil, errors.New("Import not supported for this IAM resource.")
|
||||||
|
}
|
||||||
|
config := m.(*Config)
|
||||||
|
err := resourceIdParser(d, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []*schema.ResourceData{d}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ResourceIamPolicy(parentSpecificSchema map[string]*schema.Schema, newUpdaterFunc newResourceIamUpdaterFunc) *schema.Resource {
|
func ResourceIamPolicy(parentSpecificSchema map[string]*schema.Schema, newUpdaterFunc newResourceIamUpdaterFunc) *schema.Resource {
|
||||||
return &schema.Resource{
|
return &schema.Resource{
|
||||||
Create: ResourceIamPolicyCreate(newUpdaterFunc),
|
Create: ResourceIamPolicyCreate(newUpdaterFunc),
|
||||||
@ -32,6 +47,14 @@ func ResourceIamPolicy(parentSpecificSchema map[string]*schema.Schema, newUpdate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ResourceIamPolicyWithImport(parentSpecificSchema map[string]*schema.Schema, newUpdaterFunc newResourceIamUpdaterFunc, resourceIdParser resourceIdParserFunc) *schema.Resource {
|
||||||
|
r := ResourceIamPolicy(parentSpecificSchema, newUpdaterFunc)
|
||||||
|
r.Importer = &schema.ResourceImporter{
|
||||||
|
State: iamPolicyImport(resourceIdParser),
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
func ResourceIamPolicyCreate(newUpdaterFunc newResourceIamUpdaterFunc) schema.CreateFunc {
|
func ResourceIamPolicyCreate(newUpdaterFunc newResourceIamUpdaterFunc) schema.CreateFunc {
|
||||||
return func(d *schema.ResourceData, meta interface{}) error {
|
return func(d *schema.ResourceData, meta interface{}) error {
|
||||||
config := meta.(*Config)
|
config := meta.(*Config)
|
||||||
|
@ -45,3 +45,10 @@ exported:
|
|||||||
|
|
||||||
* `etag` - (Computed) The etag of the crypto key's IAM policy.
|
* `etag` - (Computed) The etag of the crypto key's IAM policy.
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
IAM binding imports use space-delimited identifiers; first the resource in question and then the role. These bindings can be imported using the `crypto_key_id` and role, e.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ terraform import google_kms_crypto_key_binding.my_binding "your-project-id/location-name/key-name roles/viewer"
|
||||||
|
```
|
||||||
|
@ -45,3 +45,11 @@ In addition to the arguments listed above, the following computed attributes are
|
|||||||
exported:
|
exported:
|
||||||
|
|
||||||
* `etag` - (Computed) The etag of the project's IAM policy.
|
* `etag` - (Computed) The etag of the project's IAM policy.
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
IAM member imports use space-delimited identifiers; the resource in question, the role, and the account. This member resource can be imported using the `crypto_key_id`, role, and account e.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ terraform import google_kms_crypto_key_iam_member.member "your-project-id/location-name/key-name roles/viewer foo@example.com"
|
||||||
|
```
|
||||||
|
@ -90,3 +90,23 @@ In addition to the arguments listed above, the following computed attributes are
|
|||||||
exported:
|
exported:
|
||||||
|
|
||||||
* `etag` - (Computed) The etag of the key ring's IAM policy.
|
* `etag` - (Computed) The etag of the key ring's IAM policy.
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
IAM member imports use space-delimited identifiers; the resource in question, the role, and the account. This member resource can be imported using the `key_ring_id`, role, and account e.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ terraform import google_kms_key_ring_iam_member.key_ring_iam "your-project-id/location-name/key-ring-name roles/viewer foo@example.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
IAM binging imports use space-delimited identifiers; the resource in question and the role. This binding resource can be imported using the `key_ring_id`, role, and account e.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ terraform import google_kms_key_ring_iam_binding.key_ring_iam "your-project-id/location-name/key-ring-name roles/viewer"
|
||||||
|
```
|
||||||
|
|
||||||
|
IAM policy imports use the identifier of the resource in question. This policy resource can be imported using the `key_ring_id`, role, and account e.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ terraform import google_kms_key_ring_iam_policy.key_ring_iam your-project-id/location-name/key-ring-name
|
||||||
|
```
|
||||||
|
@ -46,3 +46,10 @@ exported:
|
|||||||
|
|
||||||
* `etag` - (Computed) The etag of the organization's IAM policy.
|
* `etag` - (Computed) The etag of the organization's IAM policy.
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
IAM binding imports use space-delimited identifiers; first the resource in question and then the role. These bindings can be imported using the `org_id` and role, e.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ terraform import google_organization_iam_binding.my_org "your-org-id roles/viewer"
|
||||||
|
```
|
||||||
|
@ -41,3 +41,11 @@ In addition to the arguments listed above, the following computed attributes are
|
|||||||
exported:
|
exported:
|
||||||
|
|
||||||
* `etag` - (Computed) The etag of the organization's IAM policy.
|
* `etag` - (Computed) The etag of the organization's IAM policy.
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
IAM member imports use space-delimited identifiers; the resource in question, the role, and the account. This member resource can be imported using the `org_id`, role, and account e.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ terraform import google_organization_iam_member.my_org "your-org-id roles/viewer foo@example.com"
|
||||||
|
```
|
||||||
|
@ -54,3 +54,10 @@ exported:
|
|||||||
|
|
||||||
* `etag` - (Computed) The etag of the project's IAM policy.
|
* `etag` - (Computed) The etag of the project's IAM policy.
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
IAM binding imports use space-delimited identifiers; first the resource in question and then the role. These bindings can be imported using the `project_id` and role, e.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ terraform import google_project_iam_binding.my_project "your-project-id roles/viewer"
|
||||||
|
```
|
||||||
|
@ -50,3 +50,11 @@ In addition to the arguments listed above, the following computed attributes are
|
|||||||
exported:
|
exported:
|
||||||
|
|
||||||
* `etag` - (Computed) The etag of the project's IAM policy.
|
* `etag` - (Computed) The etag of the project's IAM policy.
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
IAM member imports use space-delimited identifiers; the resource in question, the role, and the account. This member resource can be imported using the `project_id`, role, and account e.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ terraform import google_project_iam_member.my_project "your-project-id roles/viewer foo@example.com"
|
||||||
|
```
|
||||||
|
@ -38,7 +38,7 @@ data "google_iam_policy" "admin" {
|
|||||||
The following arguments are supported:
|
The following arguments are supported:
|
||||||
|
|
||||||
* `project` - (Required) The project ID.
|
* `project` - (Required) The project ID.
|
||||||
Changing this forces a new project to be created.
|
Changing this forces a new resource to be created.
|
||||||
|
|
||||||
* `policy_data` - (Required) The `google_iam_policy` data source that represents
|
* `policy_data` - (Required) The `google_iam_policy` data source that represents
|
||||||
the IAM policy that will be applied to the project. The policy will be
|
the IAM policy that will be applied to the project. The policy will be
|
||||||
@ -73,3 +73,11 @@ exported:
|
|||||||
|
|
||||||
* `restore_policy` - (DEPRECATED) (Computed) The IAM policy that will be restored when a
|
* `restore_policy` - (DEPRECATED) (Computed) The IAM policy that will be restored when a
|
||||||
non-authoritative policy resource is deleted.
|
non-authoritative policy resource is deleted.
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
IAM policy imports use the identifier of the resource in question. This policy resource can be imported using the `project_id` e.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ terraform import google_project_iam_policy.my_project your-project-id
|
||||||
|
```
|
||||||
|
Loading…
Reference in New Issue
Block a user