使用for_each为Azure存储文件共享分配RBAC角色报错求助
Terraform RBAC角色分配报错:Unsupported attribute 解决方法
问题描述
已通过for_each循环在存储账户上成功创建3个文件共享,尝试使用for_each循环为每个文件共享分配RBAC角色时,持续触发Unsupported attribute错误。
原代码
main.tf
########################### # RESOURCE GROUP CREATION # ########################### resource "azurerm_resource_group" "rg" { name = var.rg.name location = var.rg.location # tag is a test to see if I can get them to use a variable map tags = "${var.tags}" } ############################ # STORAGE ACCOUNT CREATION # ############################ resource "azurerm_storage_account" "storage_account" { name = var.storage_account.name resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location account_tier = var.storage_account.account_tier account_replication_type = var.storage_account.account_replication_type allow_nested_items_to_be_public = false azure_files_authentication { directory_type = var.storage_account.directory_type active_directory { storage_sid = var.storage_account.storage_sid domain_name = var.storage_account.domain_name domain_sid = var.storage_account.domain_sid domain_guid = var.storage_account.domain_guid forest_name = var.storage_account.forest_name netbios_domain_name = var.storage_account.netbios_domain_name } } } ######################################## # STORAGE ACCOUNT FILE SHARES CREATION # ######################################## resource "azurerm_storage_share" "file_shares" { for_each = var.file_shares name = each.value.name storage_account_name = azurerm_storage_account.storage_account.name quota = each.value.quota } ######################## # RBAC ROLE ASSIGNMENT # ######################## resource "azurerm_role_assignment" "rbac" { for_each = var.rbac scope = azurerm_storage_share.file_shares.*.id role_definition_name = each.value.role_definition_name principal_id = each.value.principal_id }
variables.tf
####################################### # STORAGE ACCOUNT FILE SHARE SETTINGS # ####################################### variable "file_shares" { description = "storage account file share settings" default = { profiles = { name = "profiles" quota = "5120" } o365 = { name = "o365" quota = "5120" } msix = { name = "msix" quota = "5120" } } } ################################# # RBAC ROLE ASSIGNMENT SETTINGS # ################################# variable "rbac" { description = "rbac assignment to storage account, principal id is the object id of the security group listed in Azure AD" default = { back_office = { role_definition_name = "Storage File Data SMB Share Contributor" principal_id = "e93a67c7-4bfc-4bbd-a720-b26d9291fa28" } front_office = { role_definition_name = "Storage File Data SMB Share Contributor" principal_id = "0280b0c9-295a-4d75-b8d0-a092cf52dabc" } dev_dev = { role_definition_name = "Storage File Data SMB Share Contributor" principal_id = "512be349-5444-45b0-80f5-8e59046a0175" } dev_prod = { role_definition_name = "Storage File Data SMB Share Contributor" principal_id = "0a676556-cf96-4318-b229-503808da7e1c" } admins = { role_definition_name = "Storage File Data SMB Share Elevated Contributor" principal_id = "b0bde374-eb5d-4967-9a4f-cdd41fd7bb23" } } }
错误信息
╵ ╷ │ Error: Unsupported attribute │ │ on storage_account/main.tf line 51, in resource "azurerm_role_assignment" "rbac": │ 51: scope = azurerm_storage_share.file_shares.*.id │ │ This object does not have an attribute named "id". ╵ ╷ │ Error: Unsupported attribute │ │ on storage_account/main.tf line 51, in resource "azurerm_role_assignment" "rbac": │ 51: scope = azurerm_storage_share.file_shares.*.id │ │ This object does not have an attribute named "id". ╵ ╷ │ Error: Unsupported attribute │ │ on storage_account/main.tf line 51, in resource "azurerm_role_assignment" "rbac": │ 51: scope = azurerm_storage_share.file_shares.*.id │ │ This object does not have an attribute named "id". ╵ ╷ │ Error: Unsupported attribute │ │ on storage_account/main.tf line 51, in resource "azurerm_role_assignment" "rbac": │ 51: scope = azurerm_storage_share.file_shares.*.id │ │ This object does not have an attribute named "id". ╵ ╷ │ Error: Unsupported attribute │ │ on storage_account/main.tf line 51, in resource "azurerm_role_assignment" "rbac": │ 51: scope = azurerm_storage_share.file_shares.*.id │ │ This object does not have an attribute named "id". ╵ ##[warning]Can't find loc string for key: TerraformPlanFailed ##[error]Error: TerraformPlanFailed 1
错误原因
- 语法错误:
azurerm_storage_share.file_shares是通过for_each创建的映射(map)类型资源集合,*.id是针对count创建的列表类型资源的语法,不适用于map集合,因此无法识别id属性。 - 逻辑错误:每个
azurerm_role_assignment的scope只能指定单个资源的ID,不能将所有文件共享的ID集合赋值给它,这会导致参数类型不匹配。
解决方案
需要创建文件共享与RBAC角色的笛卡尔积,让每个文件共享都绑定所有指定的RBAC角色。通过setproduct函数生成组合键,再用for_each遍历这个组合集合。
修正后的RBAC角色分配代码
######################## # RBAC ROLE ASSIGNMENT # ######################## # 生成文件共享和RBAC角色的组合集合 locals { share_role_combinations = setproduct(keys(var.file_shares), keys(var.rbac)) } resource "azurerm_role_assignment" "rbac" { # 遍历组合集合,用组合键作为for_each的键 for_each = { for combo in local.share_role_combinations : "${combo[0]}-${combo[1]}" => combo } # 获取对应文件共享的ID scope = azurerm_storage_share.file_shares[each.value[0]].id role_definition_name = var.rbac[each.value[1]].role_definition_name principal_id = var.rbac[each.value[1]].principal_id # 添加可选的ignore_changes,避免principal_id变更导致不必要的重建 lifecycle { ignore_changes = [principal_id] } }
说明
setproduct(keys(var.file_shares), keys(var.rbac))会生成所有文件共享键与RBAC角色键的组合,比如["profiles", "back_office"]、["profiles", "front_office"]等,总共3×5=15个组合。for combo in local.share_role_combinations : "${combo[0]}-${combo[1]}" => combo将组合转换为唯一键的map,符合for_each的要求。azurerm_storage_share.file_shares[each.value[0]].id通过文件共享的键获取对应的资源ID,解决了原语法错误问题。
内容的提问来源于stack exchange,提问作者Jon
相关产品推荐
相关产品推荐

