hashicorp / terraform-provider-azurerm

Terraform provider for Azure Resource Manager
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
Mozilla Public License 2.0
4.6k stars 4.64k forks source link

Unable to mock list of object #25691

Open emilkor1 opened 6 months ago

emilkor1 commented 6 months ago

Is there an existing issue for this?

Community Note

Hello.

I am trying to mock/test my Terraform module.

I have this stripped down version of the module which creates a resource group, kubernetes cluster and role assignment.

terraform {
  required_version = ">= 1.3"
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.99.0"
    }
    azuread = {
      source  = "hashicorp/azuread"
      version = "~> 2.48.0"
    }
  }
}

resource "azurerm_resource_group" "main" {
  name     = "example-resources"
  location = "West Europe"
}

resource "azurerm_kubernetes_cluster" "main" {
  name                = "example-aks1"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  dns_prefix          = "exampleaks1"

  default_node_pool {
    name       = "default"
    node_count = 1
    vm_size    = "Standard_D2_v2"
  }

  identity {
    type = "SystemAssigned"
  }
}

resource "azurerm_role_assignment" "oms" {
  principal_id         = azurerm_kubernetes_cluster.main.kubelet_identity[0].object_id
  role_definition_name = "Log Analytics Contributor"
  scope                = "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/my-rg/providers/Microsoft.OperationalInsights/workspaces/myci"
}

I am trying to mock both providers used in the module

mock_provider "azurerm" {}

mock_provider "azuread" {}

run "simple" {
    command = plan
}

Which crashes with the following when running terraform test

Error: Invalid index

  on main.tf line 283, in resource "azurerm_role_assignment" "oms":
 283:   principal_id         = azurerm_kubernetes_cluster.main.kubelet_identity[0].object_id
    ├────────────────
    │ azurerm_kubernetes_cluster.main.kubelet_identity is empty list of object

I have tried to mock the resources as

mock_provider "azurerm" {
  mock_resource "azurerm_role_assignment" {
    defaults = {
      principal_id = "12345678-8888-2222-3333-123456789012"
    }
  }
}

and

mock_provider "azurerm" {
  mock_resource "azurerm_kubernetes_cluster" {
    defaults = {
      kubelet_identity = [
        { object_id = "12345678-8888-2222-3333-123456789012" }
      ]
    }
  }
}

But it seems to exit with the same error no matter how the mock resources are structured.

Terraform Version

1.8.1

AzureRM Provider Version

3.99.0

Affected Resource(s)/Data Source(s)

azurerm_kubernetes_cluster, azurerm_role_assignment

Terraform Configuration Files

terraform {
  required_version = ">= 1.3"
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.99.0"
    }
    azuread = {
      source  = "hashicorp/azuread"
      version = "~> 2.48.0"
    }
  }
}

resource "azurerm_resource_group" "main" {
  name     = "example-resources"
  location = "West Europe"
}

resource "azurerm_kubernetes_cluster" "main" {
  name                = "example-aks1"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  dns_prefix          = "exampleaks1"

  default_node_pool {
    name       = "default"
    node_count = 1
    vm_size    = "Standard_D2_v2"
  }

  identity {
    type = "SystemAssigned"
  }
}

resource "azurerm_role_assignment" "oms" {
  principal_id         = azurerm_kubernetes_cluster.main.kubelet_identity[0].object_id
  role_definition_name = "Log Analytics Contributor"
  scope                = "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/my-rg/providers/Microsoft.OperationalInsights/workspaces/myci"
}

Debug Output/Panic Output

Testing tests/container-insight.tftest.hcl

Error: Invalid index

  on main.tf line 283, in resource "azurerm_role_assignment" "oms":
 283:   principal_id         = azurerm_kubernetes_cluster.main.kubelet_identity[0].object_id
    ├────────────────
    │ azurerm_kubernetes_cluster.main.kubelet_identity is empty list of object

The given key does not identify an element in this collection value: the collection has no elements.

Expected Behaviour

No response

Actual Behaviour

No response

Steps to Reproduce

  1. terraform test

Important Factoids

No response

References

No response

provglencolby commented 2 months ago

@emilkor1 were you ever able to find a work-around? We are getting hit by this exact issue

emilkor1 commented 2 months ago

This is probably an issue of terraform and not azurerm... nevertheless, no, I placed it on hold :/

provglencolby commented 2 months ago

This is probably an issue of terraform and not azurerm... nevertheless, no, I placed it on hold :/

Well, crud, Thanks for the update

jschwanz commented 2 weeks ago

I hit this exact same issue. I took your example config, removed the azurerm_role_assignment resource, and just ran a terraform plan against it to see the output.

  # azurerm_kubernetes_cluster.main will be created
  + resource "azurerm_kubernetes_cluster" "main" {
      + api_server_authorized_ip_ranges     = (known after apply)
      + current_kubernetes_version          = (known after apply)
      + dns_prefix                          = "exampleaks1"
  ...
      + identity {
          + principal_id = (known after apply)
          + tenant_id    = (known after apply)
          + type         = "SystemAssigned"
        }

      + kubelet_identity (known after apply)

      + network_profile (known after apply)

      + windows_profile (known after apply)
    }

Using your example tftest.hcl file, again with the role assignment removed, I ran terraform test -verbose to see what plan it was generating. Notice how the kubelet_identity, network_profile, etc are all missing?

  # azurerm_kubernetes_cluster.main will be created
  + resource "azurerm_kubernetes_cluster" "main" {
      + api_server_authorized_ip_ranges    = (known after apply)
      + current_kubernetes_version         = (known after apply)
      + dns_prefix                         = "exampleaks1"
  ...
      + identity {
          + principal_id = (known after apply)
          + tenant_id    = (known after apply)
          + type         = "SystemAssigned"
        }
    }

I'm not sure if this is an issue with terraform test or the azurerm_kubernetes_cluster resource, but something is definitely broken here.