Open ndrone-kr opened 4 years ago
I have the same issue with version 2.33.0 of the azurerm provider.
Hello,
I seem to have a similar issue with Terraform v0.13.5 and provider registry.terraform.io/hashicorp/azurerm v2.33.0 ; however, it is the principal_id that forces replacement, even if it has not changed :
# module.xxx.azurerm_role_assignment.rg-contributor must be replaced
-/+ resource "azurerm_role_assignment" "rg-contributor" {
~ id = "/subscriptions/xxxxxxx-xxxx-xxx-xxx-xxxxxxxx/providers/Microsoft.Authorization/roleAssignments/xxxxxxxx-xxx-xxxx-xxxx-xxxxxxxxxxxx" -> (known after apply)
~ name = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx" -> (known after apply)
~ principal_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx" -> (known after apply) # forces replacement
~ principal_type = "ServicePrincipal" -> (known after apply)
~ role_definition_id = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/providers/Microsoft.Authorization/roleDefinitions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx" -> (known after apply)
role_definition_name = "Contributor"
scope = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
+ skip_service_principal_aad_check = (known after apply)
}
This is also present in v2.38
Hi, we are seeing the same issue in provider v2.36 - any timeframes on a fix for this? We have 100's of role assignments being recreated on every build but with nothing changing.
Ours are not custom role assignments either, they are built in roles.
Thanks
I've had a similar issue with custom role definitions, and I have a very kludgy workaround in case it helps anyone.
The Problem In my case, the problem was creating a role definition with multiple assignable scopes - e.g.
resource "azurerm_role_definition" "my_role_definition" {
name = "My CustomRole"
scope = "/subscriptions/xxxxxxxx"
permissions {
... etc ...
}
assignable_scopes = [
"/subscriptions/xxxxxxxx"
"/subscriptions/yyyyyyyy"
"/subscriptions/zzzzzzzz"
]
}
resource "azurerm_role_assignment" "my_role_assignment" {
scope = "/subscriptions/zzzzzzzz"
role_definition_id = data.azurerm_role_definition.my_role_definition.id
principal_id = "<my_principal_id>"
}
The core of the issue is that data.azurerm_role_definition.my_role_definition.id
refers to the id of the role definition in scope /subscriptions/xxxxxxxx
where it was created, but it also has two other ids for the other assignable scopes. When you refer to the role definition in the azurerm_role_assignment
resource you have to use the role definition id for the appropriate scope.
It seems that even though this creates an assignment perfectly fine:
resource "azurerm_role_assignment" "my_role_assignment" {
scope = "/subscriptions/zzzzzzzz"
role_definition_id = "/subscriptions/xxxxxxxx/providers/Microsoft.Authorization/roleDefinitions/aaaaaaaa"
principal_id = "<my_principal_id>"
}
the Azure API munges the role definition id internally so that what actually gets created is:
resource "azurerm_role_assignment" "my_role_assignment" {
scope = "/subscriptions/zzzzzzzz"
role_definition_id = "/subscriptions/zzzzzzzz/providers/Microsoft.Authorization/roleDefinitions/aaaaaaaa"
principal_id = "<my_principal_id>"
}
and when you run the plan again there's a mismatch between the found (zzzzzzzz
) and specified (xxxxxxxx
) role definition ids which triggers the destroy / create sequence:
~ role_definition_id = "/subscriptions/zzzzzzzz/providers/Microsoft.Authorization/roleDefinitions/aaaaaaaa" -> "/subscriptions/xxxxxxxx/providers/Microsoft.Authorization/roleDefinitions/aaaaaaaa" # forces replacement
The (Hacky) Solution The somewhat hacky fix for me was to do the same munging in my terraform resource to make the resource definition id match the assignment's scope:
resource "azurerm_role_assignment" "my_role_assignment" {
scope = "/subscriptions/zzzzzzzz"
role_definition_id = join("", [
"/subscriptions/zzzzzzzz",
"/providers/Microsoft.Authorization",
"/roleDefinitions/${reverse(split("/", azurerm_role_definition.my_role_definition))[0]}"
])
principal_id = "<my_principal_id>"
}
Bascially, hand-craft the first part of the role definition id, then extract the guid from the end of the role definition resource and append that.
This still references the azurerm_role_definition.my_role_definition
resource so the dependencies are intact, and it avoids the -/+ resource "azurerm_role_assignment" "my_role_assignment"
on each tf apply
.
It's not pretty, but it works...
I noticed this not only relates to custom role definitions as a data source
When you set the "scope" as a resource group, and this resource group is declared as a datasource to get its ID, Then you will see the exact same recreate behavior. Role assignment is always recreated.
It seems like as soon as any input comes from a datasource it loses the ability to check for equality with what it already has.
This might be a new issue, but tagging it onto this one as it seems related.
I just had the same problem few days ago. If you see the plan message the problem is the scope of the role definition, this forces a destroy/create Fix by adding the scope to the azurerm_role_definition datasource
I just had the same problem few days ago. If you see the plan message the problem is the scope of the role definition, this forces a destroy/create Fix by adding the scope to the azurerm_role_definition datasource
I'd admit I haven't had much time to dig into what you stated. Can you provide an example?
I had same issue but this will work generate random uid and add it as name, it is optional but it will be created and not tracked in the state if we are not providing the value.
resource "random_uuid" "this" { for_each = toset(var.principal_ids) }
resource "azurerm_role_assignment" "role_assign" { for_each = toset(var.principal_ids) name = (random_uuid.this)[each.value].result description = var.description scope = var.scope role_definition_name = var.role_definition_name role_definition_id = var.role_definition_id principal_id = each.value condition = var.condition condition_version = var.condition_version }
see if this works for you.
Community Note
Terraform (and AzureRM Provider) Version
Affected Resource(s)
azurerm_role_assignment
azurerm_role_definition
Terraform Configuration Files
Debug Output
Panic Output
Expected Behavior
After applying, no change should be needed when doing a second apply or plan.
Actual Behavior
Terraform wants to recreate the role assignments on every apply.
Steps to Reproduce
terraform apply
terraform plan
Important Factoids
References
0000