You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

错误原因

  1. 语法错误:azurerm_storage_share.file_shares是通过for_each创建的映射(map)类型资源集合,*.id是针对count创建的列表类型资源的语法,不适用于map集合,因此无法识别id属性。
  2. 逻辑错误:每个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 11:01:10