-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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 guide on deleted principals #3950
Merged
slevenick
merged 2 commits into
GoogleCloudPlatform:master
from
slevenick:iam-deleted-guide
Sep 11, 2020
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
65 changes: 65 additions & 0 deletions
65
third_party/terraform/website/docs/guides/iam_deleted_members.html.markdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
--- | ||
layout: "google" | ||
page_title: "Handling diffs with deleted IAM principals" | ||
sidebar_current: "docs-google-provider-guides-iam-deleted" | ||
description: |- | ||
Handling diffs with deleted IAM principals | ||
--- | ||
|
||
# Handling diffs within IAM resources due to `deleted:` IAM principals | ||
|
||
## What is a `deleted:` IAM principal? | ||
|
||
Deleted IAM principals reference IAM principals (service accounts, users, groups) that were granted permission on an IAM policy when they were deleted. Deleting the IAM principal does not immediately purge associated permissions, but prefixes them with `deleted:` for \~30 days before deleting them. | ||
|
||
This results in IAM bindings existing for accounts that no longer exist. These bindings can be removed by removing the permission for the deleted account. Terraform will detect permissions that exist for deleted accounts, and in some cases try to remove them. This can potentially cause permanent diffs depending on which types of IAM resources are used within Terraform. This guide documents the different cases and how to handle the diffs in each case. | ||
|
||
Validation will occur in the API preventing granting permissions on an IAM policy to a principal that matches a `deleted:` principal on the same policy. This is intended to prevent granting permission to a user that has the same name as a recently deleted user who had escalated permissions. | ||
|
||
Prior to version 3.3.0 and 2.20.1 of the provider there was a bug with `deleted:` service accounts. It is strongly recommended to upgrade to 3.3.0+ to avoid issues. | ||
|
||
For more information on deleted accounts, see the [official documentation](https://cloud.google.com/iam/docs/creating-managing-service-accounts) on service accounts. | ||
|
||
## Intermediate phase | ||
|
||
Deleted IAM principals are being introduced to GCP starting on September 14, 2020. Support for them will be fully rolled out over the few weeks following. This rollout period may present a period of time when the API will behave differently, requiring some extra action to be taken to resolve Terraform diffs. During this phase users will need to delete all references to `deleted:` members before adding bindings for a new principal with the same email. Attempting to add bindings for a new principal that shares an email with a `deleted:` principal on the same policy will result in the permissions being added to the `deleted:` principal, causing Terraform to attempt to recreate the binding. References to a `deleted:` principal must be fully removed from an IAM policy before permissions can be granted to the new principal. | ||
|
||
After this intermediate phase, attempting to grant permissions to a principal that shares an email with a `deleted:` principal on the same policy will result in an error. | ||
|
||
## Using `*_iam_policy` resources | ||
|
||
`_iam_policy` allows you to declare the entire IAM policy from within Terraform. Users may see diffs on `deleted:` members in some cirtumstances, but applying the policy should succeed and resolve any issues. Specifying `deleted:` members is not allowed in Terraform, so any policy entirely managed by Terraform should automatically remove any deleted members when Terraform is run. | ||
|
||
During the intermediate period it may be required to `taint` the `_iam_policy` resource to ensure any deleted principals are removed *before* the new principal is granted permission. This should only be necessary if you are continuing to see diffs after successful applies. For more information on using `taint` see the [official documentation](https://www.terraform.io/docs/commands/taint.html). | ||
|
||
**Note:** Tainting an `iam_policy` resource will delete and recreate it. If the account that Terraform uses to provision GCP resources requires permissions granted by the `iam_policy` resource it may result in Terraform being unable to complete the apply. This is possible for `google_project_iam_policy` and `google_organization_iam_policy`. Special care should be taken when tainting these resources. | ||
|
||
## `*_iam_binding` resources | ||
|
||
`_iam_binding` resources handle all the members who are granted a specific role for an IAM policy. These resources may see diffs if a member they grant a role to is deleted and recreated. Due to these resources not controlling the entire IAM policy you may see issues around diffs not being resolved as requests can include both the deleted and non-deleted form of a principal. | ||
|
||
Example diff caused by `deleted:` member on an IAM binding resource: | ||
```hcl | ||
# google_secret_manager_secret_iam_binding.binding will be updated in-place | ||
~ resource "google_secret_manager_secret_iam_binding" "binding" { | ||
id = "projects/my-project/secrets/secret/roles/secretmanager.secretAccessor" | ||
~ members = [ | ||
- "deleted:serviceAccount:[email protected]?uid=10231234122325702", | ||
+ "serviceAccount:[email protected]", | ||
] | ||
project = "my-project" | ||
role = "roles/secretmanager.secretAccessor" | ||
secret_id = "projects/my-project/secrets/secret" | ||
} | ||
``` | ||
|
||
Tainting the `_iam_binding` resource using the [taint command](https://www.terraform.io/docs/commands/taint.html) may resolve this diff. If it does not, or results in an API error, you may need to manually remove any references to the deleted version of the principal causing the diff. This can be done through the Cloud Console UI for the resource. This could also be done via Terraform by specifying the entire IAM policy authoritatively using the `_iam_policy` resource. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same comment wrt making an arbitrary change |
||
|
||
## `*_iam_member` resources and inconsistent results | ||
|
||
`_iam_member` resources manage a certain permission for a certain principal. This resource may see diffs if the principal that it grants permissions for is deleted and recreated. Similarly to the binding resources above these may see unresolved diffs on apply. Due to this resource only ensuring that a single role is present for a single principal, member resources will not remove permissions for `deleted:` members. | ||
|
||
If applying the creation of an `_iam_member` resource results in an API error or the Terraform error: `Provider produced inconsistent result after apply` it may mean that the deleted version of the principal already exists on the IAM policy. Inspecting the policy either by [capturing the Terraform debug logs](https://www.terraform.io/docs/internals/debugging.html) or via the Cloud Console can verify that this is the cause. If the deleted version of the principal exists on the IAM policy, remove it using the Cloud Console or by using an authoritative IAM resource like `_iam_policy`. | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another way to do it would be to make an arbitrary change to the policy, like adding a random member and then just removing them right away after. This would avoid the need for a destroy/create, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the issue is that a diff shows up to remove the deleted form of a member and add the non-deleted form of that member. When Terraform attempts to apply that diff during the intermediate period, the API assumes that the non-deleted forms are references to the deleted forms and does not change them.
To successfully apply there must be the intermediate step of deleting all references to the deleted member, then the references to the non-deleted member can be added
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wow, that's tricky! Thanks for the explanation.