Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IAM Conditions support; enable it in service account IAM #2372

Merged

Conversation

danawillow
Copy link
Contributor

@danawillow danawillow commented Sep 25, 2019

Part of hashicorp/terraform-provider-google#2909.

This adds the conditions properties to all IAM resources (except, I think, google_project_iam_policy because that one does its own thing). To keep this PR from getting too unwieldy (and because certain resources seem to be broken), I've only enabled and documented it in the service account IAM resources. Technically this means that if this change is released on its own, people will be able to set the conditions field in other IAM resources, but it would fail at apply-time because we didn't set the version to 3. I think this is fine, but if we don't want that to happen we can time this PR with any follow-ups so they appear in a release together.

This change also adds a bunch of the scaffolding to the GA provider without adding full support for the feature, mainly to limit the number of erb tags in the code. Let me know if that's confusing and I can adjust.

The other confusing behavior is around users who have changed IAM conditions out-of-band. We
have no way to know whether a given binding with no condition (and no equivalent binding upstream but one with a condition upstream) had a condition added out-of-band (and thus TF should clobber the condition) or if it is intentionally being created as one with no conditions (and thus TF should add a new binding with no conditions). That, combined with the fact that we allow bindings with no members, leads to some weird diffs:
Config:

resource "google_service_account_iam_binding" "foo" {
  provider = "google-beta"

  service_account_id = "${google_service_account.test_account.name}"
  role        = "roles/iam.serviceAccountUser"
  members     = ["user:[email protected]"]
}

If I add a condition out of band, I get this diff:

  # google_service_account_iam_binding.foo will be updated in-place
  ~ resource "google_service_account_iam_binding" "foo" {
        etag               = "BwWTVHk6K4g="
        id                 = "projects/graphite-test-danahoffman-tf/serviceAccounts/[email protected] roles/iam.serviceAccountUser"
      ~ members            = [
          + "user:[email protected]",
        ]
        role               = "roles/iam.serviceAccountUser"
        service_account_id = "projects/graphite-test-danahoffman-tf/serviceAccounts/[email protected]"
    }

If applied, this would add a new binding with this member list and no condition, and leave the one with the condition no longer managed by TF.

If I add a condition out of band, then add it to my config as such:

resource "google_service_account_iam_binding" "foo" {
  provider = "google-beta"

  service_account_id = "${google_service_account.test_account.name}"
  role        = "roles/iam.serviceAccountUser"
  members     = ["user:[email protected]"]
  condition {
    title       = "expires_after_2019_12_31"
    description = "Expiring at midnight of 2019-12-31"
    expression  = "request.time < timestamp(\"2020-01-01T00:00:00Z\")"
  }
}

Then the diff looks like this:

  # google_service_account_iam_binding.foo will be updated in-place
  ~ resource "google_service_account_iam_binding" "foo" {
        etag               = "BwWTVHk6K4g="
        id                 = "projects/graphite-test-danahoffman-tf/serviceAccounts/[email protected] roles/iam.serviceAccountUser"
      ~ members            = [
          + "user:[email protected]",
        ]
        role               = "roles/iam.serviceAccountUser"
        service_account_id = "projects/graphite-test-danahoffman-tf/serviceAccounts/[email protected]"

      + condition {
          + description = "Expiring at midnight of 2019-12-31"
          + expression  = "request.time < timestamp(\"2020-01-01T00:00:00Z\")"
          + title       = "expires_after_2019_12_31"
        }
    }

And applying it is effectively a no-op.

I've been staring at this for too long and could use some fresh eyes to see if there's a way to improve this UX. @emilymye, any chance you'll have time before your break to do a thorough review?

Release Note Template for Downstream PRs (will be copied)

iam: added support for IAM Conditions to the `google_service_account_iam_*` resources (beta provider only)
`google_service_account_iam_*` resources now support IAM Conditions. If any conditions had been created out of band before this release, take extra care to ensure they are present in your Terraform config so the provider doesn't try to create new bindings with no conditions. Terraform will show a diff that it is adding the condition to the resource, which is safe to apply.

@modular-magician
Copy link
Collaborator

Hi! I'm the modular magician, I work on Magic Modules.
I see that this PR has already had some downstream PRs generated. Any open downstreams are already updated to your most recent commit, 97c97a6.

Pull request statuses

No diff detected in terraform-google-conversion.
No diff detected in Ansible.
No diff detected in Inspec.

New Pull Requests

I built this PR into one or more new PRs on other repositories, and when those are closed, this PR will also be merged and closed.
depends: hashicorp/terraform-provider-google-beta#1188
depends: hashicorp/terraform-provider-google#4541

@dancmeyers
Copy link

dancmeyers commented Sep 25, 2019

@danawillow Can I ask which resources are broken? Our primary use case for wanting IAM conditions is to be able to set access permissions on GCS buckets that apply to entire prefixes rather than either entire buckets or only specific objects (e.g. everything under bucket-name/prefixA accessible by groupA, bucket-name/prefixB by groupB, and groupC can control everything (regular bucket level IAM). It'd be useful to know if that is going to take signifiant time/work to achieve even after this PR.

Apologies if this would be better on hashicorp/terraform-provider-google#2909, let me know if so and I'll move it there.

@danawillow
Copy link
Contributor Author

@dancmeyers, the only resources I've played around with so far are service accounts (which work) and pubsub subscriptions (which don't seem to).

@emilymye emilymye self-requested a review September 25, 2019 20:57
@modular-magician
Copy link
Collaborator

Hi! I'm the modular magician, I work on Magic Modules.
I see that this PR has already had some downstream PRs generated. Any open downstreams are already updated to your most recent commit, e943dc2.

Pull request statuses

terraform-provider-google-beta already has an open PR.
No diff detected in terraform-google-conversion.
terraform-provider-google already has an open PR.
No diff detected in Ansible.
No diff detected in Inspec.

New Pull Requests

I didn't open any new pull requests because of this PR.

@danawillow danawillow requested review from rileykarson and removed request for emilymye October 15, 2019 23:12
@danawillow danawillow requested a review from slevenick October 16, 2019 21:20
@modular-magician
Copy link
Collaborator

Hi! I'm the modular magician, I work on Magic Modules.
I see that this PR has already had some downstream PRs generated. Any open downstreams are already updated to your most recent commit, 96e7ce3.

Pull request statuses

terraform-provider-google-beta already has an open PR.
No diff detected in terraform-google-conversion.
terraform-provider-google already has an open PR.
No diff detected in Ansible.
No diff detected in Inspec.

New Pull Requests

I didn't open any new pull requests because of this PR.

@modular-magician
Copy link
Collaborator

Hi! I'm the modular magician, I work on Magic Modules.
I see that this PR has already had some downstream PRs generated. Any open downstreams are already updated to your most recent commit, 1a028ac.

Pull request statuses

terraform-provider-google-beta already has an open PR.
No diff detected in terraform-google-conversion.
terraform-provider-google already has an open PR.
No diff detected in Ansible.
No diff detected in Inspec.

New Pull Requests

I didn't open any new pull requests because of this PR.

@modular-magician
Copy link
Collaborator

Hi! I'm the modular magician, I work on Magic Modules.
I see that this PR has already had some downstream PRs generated. Any open downstreams are already updated to your most recent commit, 894a9b9.

Pull request statuses

terraform-provider-google-beta already has an open PR.
No diff detected in terraform-google-conversion.
terraform-provider-google already has an open PR.
No diff detected in Ansible.
No diff detected in Inspec.

New Pull Requests

I didn't open any new pull requests because of this PR.


* `description` - (Optional) An optional description of the expression. This is a longer text which describes the expression, e.g. when hovered over it in a UI.

~> **Warning:** Terraform considers the `role` and condition contents (`title`+`description`+`expression`) as the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want description as part of the identifier for the binding?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes and no. It feels silly to do so, but it also makes the code much easier to deal with, and it aligns with what the IAM team has told us (since there can be two distinct conditions with the exact same title and expression but different descriptions). Since a ForceNew on an IAM resource isn't super destructive, I'm pretty ok with leaving it this way and seeing if it causes any issues.

@modular-magician
Copy link
Collaborator

Hi! I'm the modular magician, I work on Magic Modules.
I see that this PR has already had some downstream PRs generated. Any open downstreams are already updated to your most recent commit, 0c0a13b.

Pull request statuses

terraform-provider-google-beta already has an open PR.
No diff detected in terraform-google-conversion.
terraform-provider-google already has an open PR.
No diff detected in Ansible.
No diff detected in Inspec.

New Pull Requests

I didn't open any new pull requests because of this PR.

@modular-magician
Copy link
Collaborator

Hi! I'm the modular magician, I work on Magic Modules.
I see that this PR has already had some downstream PRs generated. Any open downstreams are already updated to your most recent commit, d5e5d40.

Pull request statuses

terraform-provider-google-beta already has an open PR.
No diff detected in terraform-google-conversion.
terraform-provider-google already has an open PR.
No diff detected in Ansible.
No diff detected in Inspec.

New Pull Requests

I didn't open any new pull requests because of this PR.

@modular-magician
Copy link
Collaborator

Hi! I'm the modular magician, I work on Magic Modules.
I see that this PR has already had some downstream PRs generated. Any open downstreams are already updated to your most recent commit, e95eb91.

Pull request statuses

terraform-provider-google-beta already has an open PR.
No diff detected in terraform-google-conversion.
terraform-provider-google already has an open PR.
No diff detected in Ansible.
No diff detected in Inspec.

New Pull Requests

I didn't open any new pull requests because of this PR.

Tracked submodules are build/terraform-beta build/terraform-mapper build/terraform build/ansible build/inspec.
@modular-magician modular-magician merged commit 8ba5798 into GoogleCloudPlatform:master Oct 28, 2019
@danawillow danawillow deleted the iam-conditions-3 branch October 28, 2019 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants