Search code examples
azureterraformterraform-provider-azure

Error: Incorrect attribute value type for multiple resources


I'm having issues deploying 2 x data collection rules (regions = ause & auea) that link to their corresponding data collection endpoints.

I successfully deploy the RG, the 2 LAWS (ause & auea), 2 x dces (ause & auea) but having issues deploying 2 x dcrs (ause & auea).

Structure would look like:

lp-rg-management-infra

 >ause-lp-log-management-infra
 >ause-lp-dce-infra
 >ause-lp-dcr-win-eventlogs-infra

 >auea-lp-log-management-infra
 >auea-lp-dce-infra
 >auea-lp-dcr-win-eventlogs-infra

Errors:

 Error: Incorrect attribute value type
│
│   on monitor.tf line 27, in resource "azurerm_monitor_data_collection_rule" "dcr-windows-eventlogs":
│   27:   data_collection_endpoint_id = module.dce.id
│     ├────────────────
│     │ module.dce.id is a object
│
│ Inappropriate value for attribute "data_collection_endpoint_id": string required.
╵
╷
│ Error: Incorrect attribute value type
│
│   on monitor.tf line 32, in resource "azurerm_monitor_data_collection_rule" "dcr-windows-eventlogs":
│   32:       workspace_resource_id = module.law.workspace_id
│     ├────────────────
│     │ module.law.workspace_id is a object
│
│ Inappropriate value for attribute "workspace_resource_id": string required.
╵
╷
│ Error: Incorrect attribute value type
│
│   on monitor.tf line 33, in resource "azurerm_monitor_data_collection_rule" "dcr-windows-eventlogs":
│   33:       name                  = module.law.workspace_name
│     ├────────────────
│     │ module.law.workspace_name is a object
│
│ Inappropriate value for attribute "name": string required.

My code is as follows:

modules\rg\main.tf

resource "azurerm_resource_group" "rg" {
  name     = var.resource_group_name
  location = var.location
  tags     = var.tags
}

modules\rg\outputs.tf

output "resource_group_name_id" {
  value = azurerm_resource_group.rg.id
}
    
output "resource_group_name" {
  value       = azurerm_resource_group.rg.name
  description = "name of resource group"
}
    
output "location" {
  value       = azurerm_resource_group.rg.location
  description = "location of resource group"
}
    
output "tags" {
  value = azurerm_resource_group.rg.tags
}

modules\rg\variables.tf

variable "resource_group_name" {
  type        = string
  description = "name of resource group"
}
    
variable "location" {
  type        = string
  description = "location of resource group"
}
    
variable "tags" {
  type    = map(any)
  default = {}
}

modules\law\main.tf

resource "azurerm_log_analytics_workspace" "workspaces" {
  name                            = var.name
  location                        = var.location
  resource_group_name             = var.resource_group_name
  sku                             = var.sku
  retention_in_days               = var.retention_in_days
  allow_resource_only_permissions = var.allow_resource_only_permissions
  tags                            = var.tags
}

modules\law\outputs.tf

output "workspace_id" {
  value = azurerm_log_analytics_workspace.workspaces.id
}
    
output "workspace_name" {
  value = azurerm_log_analytics_workspace.workspaces.name
}
    
output "resource_group_name" {
  value = var.resource_group_name
}

modules\law\variables.tf

variable "name" {
  description = "The name of the Log Analytics workspace."
}
    
variable "location" {
  description = "The location of the Log Analytics workspace."
}
    
variable "resource_group_name" {
  description = "The name of the resource group for the Log analytics workspace."
}
    
variable "retention_in_days" {
  description = "The retention period in days for Log Analytics data."
}
    
variable "sku" {
  description = "The sku for the Log Analytics data."
}
    
variable "allow_resource_only_permissions" {
  description = "Specifies if the log Analytics Workspace allow users accessing to data associated with resources they have permission to view, without permission to workspace."
}
    
variable "tags" {
  type    = map(any)
  default = {}
}

modules\monitor\dce\main.tf

resource "azurerm_monitor_data_collection_endpoint" "dce" {
  name                            = var.name
  location                        = var.location
  resource_group_name             = var.resource_group_name
  tags                            = var.tags
  
  lifecycle {
    create_before_destroy = true
  }
}

modules\monitor\dce\outputs.tf

output "dce_id" {
  value = azurerm_monitor_data_collection_endpoint.dce.id
}
    
output "dce_name" {
  value = azurerm_monitor_data_collection_endpoint.dce.name
}
    
output "resource_group_name" {
  value = var.resource_group_name
}

modules\monitor\dce\variables.tf

variable "name" {
  description = " (Required) The name which should be used for this Data Collection Endpoint."
}
    
variable "location" {
  description = " (Required) The Azure Region where the Data Collection Endpoint should exist."
}
    
variable "resource_group_name" {
  description = " (Required) The name of the Resource Group where the Data Collection Endpoint should exist."
}
    
variable "tags" {
  type    = map(any)
  default = {}
}

project\law.tf

module "law" {
  for_each = var.locations
  source   = "../../../../modules/common/law"
    
  name                            = "${each.key}-${var.company_prefix}-log-management-infra"
  location                        = each.value.region
  resource_group_name             = module.rg.resource_group_name
  sku                             = var.sku
  retention_in_days               = var.retention_in_days
  allow_resource_only_permissions = var.allow_resource_only_permissions
}

project\monitor.tf

module "dce" {
  for_each = var.locations
  source = "../../../../modules/monitor/dce"
    
  name = "${each.key}-${var.company_prefix}-dce-infra"
  resource_group_name = module.rg.resource_group_name
  location            = each.value.region
}
    
resource "azurerm_monitor_data_collection_rule" "dcr-windows-eventlogs" {
  for_each = var.locations
    
  name                        = "${each.key}-${var.company_prefix}-dcr-win-eventlogs-infra"
  resource_group_name         = module.rg.resource_group_name
  location                    = "module.dce.location"
  data_collection_endpoint_id = module.dce.id
  kind                        = "Windows"
    
  destinations {
    log_analytics {
      workspace_resource_id = module.law.workspace_id
      name                  = module.law.workspace_name
    }
  }

  data_sources {
    windows_event_log {
      streams = ["Microsoft-Event"]
      x_path_queries = ["Application!*[System[(Level=1 or Level=2 or Level=3)]]", "Security!*[System[(band(Keywords,13510798882111488))]]", "System!*[System[(Level=1 or Level=2 or Level=3)]]"]
      name = "eventLogsDataSource"
    }
  }
  
  data_flow {
    streams      = ["Microsoft-Event"]
    destinations = ["module.law.workspace_name"]
  }
}

project\outputs.tf

output "rg_resource_group_names" {
  value = {
    for key, location in var.locations :
    key => "${key}-${var.company_prefix}-management-rg"
  }
}
    
output "log_analytics_workspace_names" {
  value = {
    for key, location in var.locations :
      key => "${key}-${var.company_prefix}-management-log"
  }
}
    
output "log_analytics_workspace_ids" {
  value = {
    for key, location in var.locations :
    key => module.law[key].workspace_id
  }
}
    
output "dce_ids" {
  value = {
    for key, location in var.locations :
    key => module.dce[key].id
  }
}

project\rg.tf

module "rg" {
  source   = "../../../../modules/common/rg"
    
  resource_group_name = "${var.company_prefix}-rg-management-infra"
  location            = var.locations["ause"].region
  tags                = var.tags
}

project\terraform.tfvars

# Resource Group Variables
    
tags = {
  Description = "Management Landing Zone "
  Owner       = "Cloud Engineers"
  Environment = "Management Subscription"
}
    
locations = {
  ause = { region = "australiasoutheast" }
  auea = { region = "australiaeast" }
}
    
# Log Analytics Variables
    
deployment_environment          = "p"
company_prefix                  = "lp"
retention_in_days               = "365"
sku                             = "PerGB2018"
allow_resource_only_permissions = true

project\variables.tf

# Resource Group Variables
    
variable "tags" {
  type    = map(any)
  default = {}
}
    
variable "locations" {
  description = "Map of location identifiers to Azure region names"
  type = map(object({
    region = string
  }))
  default = {}
}
    
variable "company_prefix" {
  description = "Company prefix for naming resources"
  type        = string
}
    
# Log Analytics Variables
variable "deployment_environment" {
  description = "Deployment environment"
  type        = string
}
    
variable "retention_in_days" {
  description = "Number of days to retain logs"
  type        = number
}
    
variable "sku" {
  description = "The sku for the Log Analytics data."
  type        = string
}
    
variable "allow_resource_only_permissions" {
  description = "Specifies if the log Analytics Workspace allow users accessing to data associated with resources they have permission to view, without permission to workspace."
}

Solution

  • Terraform is telling you that you are trying to assign a value of wrong type to an argument which expects something different. In this case, since both law and dce modules were created using for_each, that means when you are trying to reference the module outputs without specifying a key will yield an error which tells you you are trying to reference an entire object (which it is since the module was created with for_each) instead of accessing the correct attribute value for a given key in the object. This should fix the errors:

    resource "azurerm_monitor_data_collection_rule" "dcr-windows-eventlogs" {
      for_each = var.locations
        
      name                        = "${each.key}-${var.company_prefix}-dcr-win-eventlogs-infra"
      resource_group_name         = module.rg.resource_group_name
      location                    = module.dce[each.key].location
      data_collection_endpoint_id = module.dce[each.key].id
      kind                        = "Windows"
        
      destinations {
        log_analytics {
          workspace_resource_id = module.law[each.key].workspace_id
          name                  = module.law[each.key].workspace_name
        }
      }
    
      data_sources {
        windows_event_log {
          streams = ["Microsoft-Event"]
          x_path_queries = ["Application!*[System[(Level=1 or Level=2 or Level=3)]]", "Security!*[System[(band(Keywords,13510798882111488))]]", "System!*[System[(Level=1 or Level=2 or Level=3)]]"]
          name = "eventLogsDataSource"
        }
      }
      
      data_flow {
        streams      = ["Microsoft-Event"]
        destinations = [module.law[each.key].workspace_name]
      }
    }