hashicorp / terraform-provider-google

Terraform Provider for Google Cloud Platform
https://registry.terraform.io/providers/hashicorp/google/latest/docs
Mozilla Public License 2.0
2.31k stars 1.73k forks source link

Cloud Identity Resources require Delegated Credential #6806

Closed seanearley closed 4 years ago

seanearley commented 4 years ago

Community Note

Terraform Version

Terraform v0.12.28

Affected Resource(s)

google_cloud_identity_group cloud_identity_group_membership

Terraform Configuration Files

provider "google-beta" {
  credentials = file("~/projects/credentials/group-dev.json")
  project     = "sde-group-dev"

  scopes = ["https://www.googleapis.com/auth/cloud-identity.groups"]

}

resource "google_cloud_identity_group" "cloud_identity_group_basic" {
  provider     = google-beta
  display_name = "sean-group"

  parent = "customers/XXXXXXXXX"

  group_key {
    id = "sean-group@qarikdevelopers.com"
  }

  labels = {
    "cloudidentity.googleapis.com/groups.discussion_forum" = ""
  }
}

Debug Output

https://gist.github.com/seanearley/0d6d99450eac0b13506f15c7cd407380

Expected Behavior

Terraform should have created the group.

Actual Behavior

Error: Error creating Group: googleapi: Error 403: Error(2015): Actor does not have permission to create group 'sean-group2@qarikdevelopers.com'.
Details:
[
  {
    "@type": "type.googleapis.com/google.rpc.ResourceInfo",
    "description": "Error(2015): Actor does not have permission to create group 'sean-group@qarikdevelopers.com'.",
    "owner": "domain:cloudidentity.googleapis.com",
    "resourceType": "cloudidentity.googleapis.com/Group"
  }
]

  on main.tf line 9, in resource "google_cloud_identity_group" "cloud_identity_group_basic":
   9: resource "google_cloud_identity_group" "cloud_identity_group_basic" {

Steps to Reproduce

  1. Create service account
  2. Perform domain wide delegation of the appropriate scope "https://www.googleapis.com/auth/cloud-identity.groups" to the service account in admin.google.com console
  3. terraform apply

Important Factoids

This is a G Suite domain, not a cloud identity domain.

Typically when accessing G Suite APIs with a a service account you need to create delegated credentials by specifying an email address for a real user. I can't see anyway to configure the Terraform provider to create a delegated credential.

Using the python SDK, I performed two group creation call that were identical, except for the passed credential:

credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
delegated_credentials = credentials.with_subject('sean@qarikdevelopers.com') 

The call with credentials generated the same 403 as terraform, while the call with delegated_credentials succeeded.

edwardmedia commented 4 years ago

@seanearley do you want to take a look into below data source to see if it helps? google_service_account_access_token

seanearley commented 4 years ago

Hi, thanks for the reply!

This looks like the right direction, but it appears the target_service_account field can only take another service account, not an end user.

data "google_service_account_access_token" "default" {
  provider               = google
  target_service_account = "sean@qarikdevelopers.com"
  scopes                 = ["https://www.googleapis.com/auth/cloud-identity.groups"]
  lifetime               = "3600s"
}
(group-dev) [~/projects/sauce/group-dev]$ terraform plan                                                                                                                                                                                     

Error: "target_service_account" ("sean@qarikdevelopers.com") doesn't match regexp "((?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))@[a-z]+.gserviceaccount.com$|[0-9]{1,20}-compute@developer.gserviceaccount.com|[a-z](?:[-a-z0-9]{4,28}[a-z0-9])@[-a-z0-9\\.]{1,63}\\.iam\\.gserviceaccount\\.com$)"

  on groups.tf line 9, in data "google_service_account_access_token" "default":
   9: data "google_service_account_access_token" "default" {

I think the issue is that the google_service_account_access_token resource is using the https://iamcredentials.googleapis.com/v1/ endpoint, while to create the G Suite compatible credential the https://oauth2.googleapis.com/token endpoint is required.

For reference, Google has the Python SDK example using the Cloud Identity Groups API here. Note I think there is a typo googleapiclient.discovery.build call should be using credentials=delegated_credentials. The example uses the google.oauth2 client, which calls the oaut2.googleapis.com, not iamcredentials.googleapis.com. The documentation for using service accounts with that endpoint is here.

I will confess we are at the boundaries of my ability to navigate Google Oauth, so happy to take any pointers on correct direction. What I would like to do is be able to use the google_cloud_identity_group and cloud_identity_group_membership terraform resources with a G Suite domain and Service Account authentication. I'm not sure what the best way to set up authentication to support that is (or if it is possible).

The G Suite Terraform Provider supports the needed functionality using the https://www.googleapis.com/admin/directory/v1/groups/ API, but it is A) unofficial and B) requires installing the provider binary, which adds a bit of toil to maintaining CI/CD pipelines.

edwardmedia commented 4 years ago

@seanearley Can you take a look into this? https://github.com/terraform-providers/terraform-provider-google/issues/6704#issuecomment-651285723

seanearley commented 4 years ago

Yes, just tried this and it does resolve the issue, we are unblocked for now. Thanks for that find!

I do have concerns that this is not an officially supported method. Is there any way to confirm that using the API to directly assign the role will work moving forward? It seems passing an impersonated credential is the preferred approach by Google.

edwardmedia commented 4 years ago

@seanearley I am glad this helps resolve your issue. What you described is possible but there is no any plan yet. You may file an enhancement for what you prefer and the team could add it into the backlog. I am closing this issue then. Thank you!

ghost commented 4 years ago

I'm going to lock this issue because it has been closed for 30 days ā³. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error šŸ¤– šŸ™‰ , please reach out to my human friends šŸ‘‰ hashibot-feedback@hashicorp.com. Thanks!