Terraform v0.12.13
azurerm_role_assignment
terraform {
required_version = ">= 0.12"
}
provider "azurerm" {
version = "~> 1.36.0"
}
provider "azuread" {
version = "~> 0.6.0"
}
data "azurerm_client_config" "current" {
}
# Get the tenant root Management Group
data "azurerm_management_group" "mgTenantRoot" {
group_id = data.azurerm_client_config.current.tenant_id
}
# Create a Management Group as a child to the tenant root
resource "azurerm_management_group" "test239857" {
display_name = "test239857"
parent_management_group_id = data.azurerm_management_group.mgTenantRoot.id
group_id = "test239857"
subscription_ids = [
data.azurerm_client_config.current.subscription_id //move the subscription under the role definition scope
]
}
# Create a custom role scoped to a management group
resource "azurerm_role_definition" "test239857" {
name = "test239857"
scope = azurerm_management_group.test239857.id
description = "Role scoped to a management group"
permissions {
actions = [
"Microsoft.DeploymentManager/*/read"
]
not_actions = []
}
assignable_scopes = [
azurerm_management_group.test239857.id
]
}
# create a target for the role assignment
resource "azuread_group" "test239857" {
name = "test239857"
}
# Get the current subscription
data "azurerm_subscription" "currentSubscription" {
}
# Assignment of a Management Group scoped role to a subscription
resource "azurerm_role_assignment" "test239857" {
scope = data.azurerm_subscription.currentSubscription.id
role_definition_id = azurerm_role_definition.test239857.id
principal_id = azuread_group.test239857.id
}
https://gist.github.com/rjfmachado/b8dd89e4e89fd88391e26e27ab0ff3f2
Terraform plan should have no changes after apply
Terraform wants to recreate the Role Assignment
User should have global tenant admin role on Azure AD and Owner on the subscription
Hi, I get the same behavior for built in roles, using azurerm_builtin_role_definition or azurerm_role_definition.
data azurerm_builtin_role_definition contributor {
name = "Contributor"
}
OR
data azurerm_role_definition contributor {
name = "Contributor"
}
Here is the output from plan/apply
# module.service.azurerm_role_assignment.app-role must be replaced
-/+ resource "azurerm_role_assignment" "app-role" {
~ id = "/subscriptions/1234/resourceGroups/service-nexus-test1-westus2-dev/providers/Microsoft.Authorization/roleAssignments/6fea8cf5-5113-299f-aa9e-5e4be190fc2f" -> (known after apply)
~ name = "6fea8cf5-5113-299f-aa9e-5e4be190fc2f" -> (known after apply)
principal_id = "7f16a9bb-a75d-4953-8c50-61b7ae694bb4"
~ principal_type = "ServicePrincipal" -> (known after apply)
~ role_definition_id = "/subscriptions/1234/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c" -> "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c" # forces replacement
~ role_definition_name = "Contributor" -> (known after apply)
scope = "/subscriptions/1234/resourceGroups/service-test1-westus2-dev"
+ skip_service_principal_aad_check = (known after apply)
}
Still having the same issue today 23/01/2020. It looks like it keeps wanting to switch between:
/subscriptions/GUID/providers/Microsoft.Authorization/roleDefinitions/GUID" -> "/providers/Microsoft.Authorization/roleDefinitions/GUID"
Every time it is also creating a new role_definition_id GUID.
Hi I can confirm this issue still happens with terraform 0.12.21 and AzureRM 2.0
Same issue with Terraform v0.12.23
I am having a similar issue that has to deal with multiple subscriptions in the same tenant. Here is my scenario:
resource "azurerm_role_definition" "resource-provider-registration" {
name = "Register Azure Resource Providers"
scope = "/subscriptions/${local.subscriptions.prod}"
description = "Can register Azure resource providers"
permissions {
actions = ["*/register/action"]
}
assignable_scopes = [
"/subscriptions/${local.subscriptions.prod}",
"/subscriptions/${local.subscriptions.uat}",
"/subscriptions/${local.subscriptions.dev}"
]
provider = azurerm.prod
}
resource "azurerm_role_assignment" "ado-service-principal-provider-registration-prod" {
scope = "/subscriptions/${local.subscriptions.prod}"
role_definition_id = azurerm_role_definition.resource-provider-registration.id
principal_id = local.azure_dev_ops_service_principals.prod.object_id
provider = azurerm.prod
}
resource "azurerm_role_assignment" "ado-service-principal-provider-registration-uat" {
scope = "/subscriptions/${local.subscriptions.uat}"
role_definition_id = azurerm_role_definition.resource-provider-registration.id
principal_id = local.azure_dev_ops_service_principals.uat.object_id
provider = azurerm.uat
}
resource "azurerm_role_assignment" "ado-service-principal-provider-registration-dev" {
scope = "/subscriptions/${local.subscriptions.dev}"
role_definition_id = azurerm_role_definition.resource-provider-registration.id
principal_id = local.azure_dev_ops_service_principals.dev.object_id
provider = azurerm.dev
}
Subsequent runs of this produces the following terraform plans (wants to replace them due to the ID changing, when it hasn't changed.
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
~ update in-place
-/+ destroy and then create replacement
Terraform will perform the following actions:
# azurerm_role_assignment.ado-service-principal-provider-registration-dev must be replaced
-/+ resource "azurerm_role_assignment" "ado-service-principal-provider-registration-dev" {
~ id = "/subscriptions/{Dev Subscription ID}/providers/Microsoft.Authorization/roleAssignments/2c2691ea-877f-cfe2-326e-6133d1ec73b9" -> (known after apply)
~ name = "2c2691ea-877f-cfe2-326e-6133d1ec73b9" -> (known after apply)
principal_id = "2da99d69-b8a3-419f-a885-f6e1e5314524"
~ principal_type = "ServicePrincipal" -> (known after apply)
~ role_definition_id = "/subscriptions/{Dev Subscription ID}/providers/Microsoft.Authorization/roleDefinitions/75262d2f-6665-aada-da4e-2bcafd5b2bc5" -> "/subscriptions/{Production Subscription ID}/providers/Microsoft.Authorization/roleDefinitions/75262d2f-6665-aada-da4e-2bcafd5b2bc5" # forces replacement
~ role_definition_name = "Register Azure Resource Providers" -> (known after apply)
scope = "/subscriptions/{Dev Subscription ID}"
+ skip_service_principal_aad_check = (known after apply)
}
# azurerm_role_assignment.ado-service-principal-provider-registration-uat must be replaced
-/+ resource "azurerm_role_assignment" "ado-service-principal-provider-registration-uat" {
~ id = "/subscriptions/{UAT Subscription ID}/providers/Microsoft.Authorization/roleAssignments/faf86950-c49d-061d-fd5e-142132c44441" -> (known after apply)
~ name = "faf86950-c49d-061d-fd5e-142132c44441" -> (known after apply)
principal_id = "3defe365-2eb3-41c7-a025-55649d591ede"
~ principal_type = "ServicePrincipal" -> (known after apply)
~ role_definition_id = "/subscriptions/{UAT Subscription ID}/providers/Microsoft.Authorization/roleDefinitions/75262d2f-6665-aada-da4e-2bcafd5b2bc5" -> "/subscriptions/{Production Subscription ID}/providers/Microsoft.Authorization/roleDefinitions/75262d2f-6665-aada-da4e-2bcafd5b2bc5" # forces replacement
~ role_definition_name = "Register Azure Resource Providers" -> (known after apply)
scope = "/subscriptions/{UAT Subscription ID}"
+ skip_service_principal_aad_check = (known after apply)
}
Plan: 2 to add, 0 to change, 2 to destroy.
Facing exactly the issue. Was anybody able to resolve?
Yes I did literally yesterday! If you add a lifecycle ignore-changes block it stops happening.
I hope this helps.
lifecycle {
ignore_changes = [
role_definition_id,
]
}
@darren-johnson : Thank you that helped.
Same situation here, "ignore_changes" is a patch that works but this should be investigated and solved. In my case this happens only with custom roles, once we assign them it works but It wants to modify the resource each time we re-apply:
~ role_definition_id = "/subscriptions/SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/d7e9b9d6-a3d1-9518-0e6b-ff17d47c9078" -> "/providers/Microsoft.Authorization/roleDefinitions/d7e9b9d6-a3d1-9518-0e6b-ff17d47c9078" # forces replacement
I have same problem for a custom role, it always try to replace the role definition even when I add the ignore changes, can anyone assist ?
Terraform v0.12.28
locals {
role_definition_id = uuid()
}
resource "azurerm_role_definition" "custom" {
role_definition_id = local.role_definition_id
name = var.role_definition_name
scope = data.azurerm_management_group.gbs_cloud.id
description = var.role_definition_description
permissions {
actions = var.role_actions
not_actions = var.role_not_actions
}
assignable_scopes = [
data.azurerm_management_group.gbs_cloud.id,
]
lifecycle {
ignore_changes = [
role_definition_id,
]
}
}
Terraform will perform the following actions:
-/+ resource "azurerm_role_definition" "custom" {
assignable_scopes = [
"/providers/Microsoft.Management/managementGroups/GBSCloud",
]
description = "This is a custom role created via Terraform"
~ id = "/providers/Microsoft.Authorization/roleDefinitions/709c011c-46c1-c5bd-5431-f5b12058399b" -> (known after apply)
name = "Custom Log Analytics"
~ role_definition_id = "709c011c-46c1-c5bd-5431-f5b12058399b" -> (known after apply)
+ scope = "/providers/Microsoft.Management/managementGroups/GBSCloud" # forces replacement
~ permissions {
actions = [
"*/read",
"Microsoft.OperationalInsights/workspaces/analytics/query/action",
"Microsoft.OperationalInsights/workspaces/search/action",
"Microsoft.Insights/AlertRules/Throttled/Action",
"Microsoft.Insights/AlertRules/Resolved/Action",
"Microsoft.Insights/AlertRules/Activated/Action",
"Microsoft.Insights/AlertRules/Read",
"Microsoft.Insights/AlertRules/Delete",
"Microsoft.Insights/AlertRules/Write",
]
- data_actions = [] -> null
not_actions = [
"Microsoft.OperationalInsights/workspaces/sharedKeys/read",
]
- not_data_actions = [] -> null
}
}
Plan: 1 to add, 0 to change, 1 to destroy.
I have same problem for a custom role, it always try to replace the role definition even when I add the ignore changes, can anyone assist ?
Terraform v0.12.28
- provider.azurerm v2.17.0
locals { role_definition_id = uuid() }resource "azurerm_role_definition" "custom" { role_definition_id = local.role_definition_id name = var.role_definition_name scope = data.azurerm_management_group.gbs_cloud.id description = var.role_definition_description permissions { actions = var.role_actions not_actions = var.role_not_actions } assignable_scopes = [ data.azurerm_management_group.gbs_cloud.id, ] lifecycle { ignore_changes = [ role_definition_id, ] } }Terraform will perform the following actions: -/+ resource "azurerm_role_definition" "custom" { assignable_scopes = [ "/providers/Microsoft.Management/managementGroups/GBSCloud", ] description = "This is a custom role created via Terraform" ~ id = "/providers/Microsoft.Authorization/roleDefinitions/709c011c-46c1-c5bd-5431-f5b12058399b" -> (known after apply) name = "Custom Log Analytics" ~ role_definition_id = "709c011c-46c1-c5bd-5431-f5b12058399b" -> (known after apply) + scope = "/providers/Microsoft.Management/managementGroups/GBSCloud" # forces replacement ~ permissions { actions = [ "*/read", "Microsoft.OperationalInsights/workspaces/analytics/query/action", "Microsoft.OperationalInsights/workspaces/search/action", "Microsoft.Insights/AlertRules/Throttled/Action", "Microsoft.Insights/AlertRules/Resolved/Action", "Microsoft.Insights/AlertRules/Activated/Action", "Microsoft.Insights/AlertRules/Read", "Microsoft.Insights/AlertRules/Delete", "Microsoft.Insights/AlertRules/Write", ] - data_actions = [] -> null not_actions = [ "Microsoft.OperationalInsights/workspaces/sharedKeys/read", ] - not_data_actions = [] -> null } } Plan: 1 to add, 0 to change, 1 to destroy.
Your problem is related to an issue in azurerm_role_definition that was introduced in version 2.16, downgrade to version 2.15 and it will work as expected. Please don't forget to post in issue #7549 to let the developers know that there is more people affected.
@juanjojulian Thanks downgrade to 2.15 works for me
@juanjojulian 2.15 still gives the error in my case ;-(
Hi,
I found a workaround for role_definition_id that should be applied in some situations only:
role_definition_name is usedrole_definition_id = azurerm_role_definition.example.id as in terraform examplerole_definition_id = "${data.azurerm_subscription.primary.id}${ azurerm_role_definition.example.id}"Manuel
Thanks for the tip @boillodmanuel , in my case it doesn't work, there must be some kind of mess in azurerm_role_assignment resource in my version combination:
Terraform v0.13.5
+ provider registry.terraform.io/hashicorp/azuread v1.1.1
+ provider registry.terraform.io/hashicorp/azurerm v2.38.0
For instance, if I write:
role_definition_id = azurerm_role_definition.customRole.id
Terraform wants to set role_definition_id to:
"/providers/Microsoft.Authorization/roleDefinitions/1b7485d0-f713-e168-5a5b-0816ba0b0646|/providers/Microsoft.Management/managementGroups/myManagementGroupName"
Which according to Documentation should be the output for "role_definition_id" not for "id"
But then if I make use of role_definition_resource_id
role_definition_id = azurerm_role_definition.customRole.role_definition_resource_id
Terraform wants to set role_definition_id to:
"/providers/Microsoft.Authorization/roleDefinitions/1b7485d0-f713-e168-5a5b-0816ba0b0646"
Which initially works but in subsequent applies Terraform will want to change it again and again:
"/subscriptions/6hsbdka-d4cf-98e6-ff0c-3114fjkds8dbhnb43/providers/Microsoft.Authorization/roleDefinitions/1b7485d0-f713-e168-5a5b-0816ba0b0646" -> "/providers/Microsoft.Authorization/roleDefinitions/1b7485d0-f713-e168-5a5b-0816ba0b0646"
So the (ugly) workaround that works for me its:
role_definition_id = "${data.azurerm_subscription.mySubscription.id}/providers/Microsoft.Authorization/roleDefinitions/${ azurerm_role_definition.customRole.role_definition_id}"
I really cannot understand what's going on with this resource in azurerm, this issue has been open for one year now.
Facing the same issue, when using Terraform v0.14.2 and azurerm provider v2.36.0
Most helpful comment
Still having the same issue today 23/01/2020. It looks like it keeps wanting to switch between:
/subscriptions/GUID/providers/Microsoft.Authorization/roleDefinitions/GUID" -> "/providers/Microsoft.Authorization/roleDefinitions/GUID"
Every time it is also creating a new role_definition_id GUID.