-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
google_iam_policy with multiple bindings show changes on every plan #8701
google_iam_policy with multiple bindings show changes on every plan #8701
Comments
I believe the issue here exists within google/resource_iam_policy.go, and that the problem is that the policy data which comes back from the Google API may come back in any order, but when the local policy gets converted to json here its always sorted and an exact match is expected. Possible solutions could be ignoring the order, or sorting list which come back within bindings so that the difference will actually show properly in plans. |
Also this is related to issue #7074, but it seems like the root is a bit different. In that case, the original policy was created outside of Terraform. In this case, everything has been done through Terraform. The issue is simply that the provider here is strict about the ordering of bindings when it should ignore their ordering. |
#9535 may be a dupe of this? 🤔 |
Setting as Solution seems to require adding diff suppress logic to ignore the json order, or sorting the list. |
From what I've seen, it seems to mostly happen when there are conditions present, specifically when there are multiple bindings of the same role with different or identical conditions.
The order of the bindings in the |
Is there a known workaround for this type of bug? For me, it helps if I deploy all bindings without conditions and then add all the ones with conditions but this is not a very sustainable way of deploying stuff. |
I've been working on a PR to address this, and just adding some notes about how I've explored and reproduced the issue 1. Problem due to different JSONs in state vs returned from Google APIs
👉 Configuration I used is here (expand to see)provider "google" {
project = var.gcp_project_id
region = var.default_region
zone = var.default_zone
}
variable "gcp_project_id" {
type = string
}
variable "default_region" {
type = string
}
variable "default_zone" {
type = string
}
locals {
group_1 = "[name]@[domain].com"
group_2 = "[name]@[domain].com"
}
data "google_iam_policy" "example" {
# Bindings without condition blocks
binding {
role = "roles/iap.httpsResourceAccessor"
members = [
"group:${local.group_1}"
]
}
binding {
role = "roles/iap.admin"
members = [
"group:${local.group_1}"
]
}
# Bindings with condition blocks
binding {
role = "roles/iap.httpsResourceAccessor"
members = [
"group:${local.group_1}"
]
condition {
title = "foobar-a"
description = "This one has a description"
expression = "request.host == 'foobar-a.example.com'"
}
}
binding {
role = "roles/iap.httpsResourceAccessor"
members = [
"group:${local.group_1}"
]
condition {
title = "foobar-b"
expression = "request.host == 'foobar-b.example.com'"
}
}
binding {
role = "roles/iap.httpsResourceAccessor"
members = [
"group:${local.group_2}"
]
condition {
title = "foobar-c"
expression = "request.host == 'foobar-c.example.com'"
}
}
}
resource "google_iap_web_type_compute_iam_policy" "example" {
project = var.gcp_project_id
policy_data = data.google_iam_policy.example.policy_data
} After a successful apply the resource is created but debug logs warn that there's an unexpected change in the resource's data after creation. This is due to the resource's state being set using data that is read from the API, versus the input data coming from the config. From what I've seen, policy data that originates from the For me, subsequent 👉 Example of unexpected changes in a plan (expand to see)For example, changing the description in one binding in the config above results in a plan with lots of unexpected changes, which are due to the mismatching I mentioned # Bindings with condition blocks
binding {
role = "roles/iap.httpsResourceAccessor"
members = [
"group:${local.group_1}"
]
condition {
title = "foobar-a"
- description = "This one has a description"
+ description = "This one has a description and I edited it"
expression = "request.host == 'foobar-a.example.com'"
}
} 2. Plans adding empty descriptions to conditions inside bindings There's also the issue where plans contain diffs like this: ~ {
~ condition = {
+ description = ""
# (2 unchanged elements hidden)
}
# (2 unchanged elements hidden)
},
~ {
~ condition = {
+ description = ""
# (2 unchanged elements hidden)
}
# (2 unchanged elements hidden)
}, This seems to be a separate issue to the above, and is due to the Google API not returning empty fields in responses, which affects state, and Terraform sending empty fields in requests. I'll probably change this in a separate PR! |
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. |
Community Note
modular-magician
user, it is either in the process of being autogenerated, or is planned to be autogenerated soon. If an issue is assigned to a user, that user is claiming responsibility for the issue. If an issue is assigned tohashibot
, a community member has claimed the issue already.Terraform Version
Terraform 0.13
Google provider 3.60.0
Affected Resource(s)
Primarily this affects:
It also affects anything which can use a
policy_data
input, including all of these:Terraform Configuration Files
This is an example which would trigger the issue, note that our actual config may have many more bindings and longer expressions.
Debug Output
N/A
Panic Output
N/A
Expected Behavior
Subsequent plans should show no changes after a successful apply.
Actual Behavior
The config is able to apply, but subsequent plans will always show changes to apply even when nothing has changed.
The policy data gets encoded a list in json without sorting the input, so once you have more than a couple of bindings in a policy terraform thinks that there are changes because the state doesn't match what the generated json looks like.
If you just have a single binding you won't run into this problem, but it becomes very difficult to see what the actual changes are when it will show significant changes on every plan.
It may be possible to work around this by placing the bindings in a policy in the same order which the json encoder would put them in, but this should not be needed.
Steps to Reproduce
terraform apply
Important Factoids
References
The text was updated successfully, but these errors were encountered: