terraform-linters / tflint-ruleset-azurerm

TFLint ruleset for terraform-provider-azurerm
Mozilla Public License 2.0
116 stars 24 forks source link

Question: `azurerm_kubernetes_cluster_invalid_name` rule raised false alarm on function call #273

Closed lonegunmanb closed 1 year ago

lonegunmanb commented 1 year ago

I'm trying to update my module's code to:

resource "azurerm_log_analytics_workspace" "main" {
  count = local.create_analytics_workspace ? 1 : 0

  location            = coalesce(var.location, data.azurerm_resource_group.main.location)
  name                = coalesce(var.cluster_log_analytics_workspace_name, "${var.prefix}-workspace")

Today I found it failed TFLint rule azurerm_kubernetes_cluster_invalid_name. It's generated from Azure API, but it doesn't work with a function call.

Is this behavior by design or bug? I think this kind of value validation checks are not compatible with function call right? @wata727


A quick thought, maybe we should provide a toggle to indicate whether we're using TFLint with a root module or a reusable module, if we're using TFLint with a reusable module then using function call as resource's name is a common practice, so we should disable all naming check rules.

Or should we group rules so we can turn off a group of rules?

wata727 commented 1 year ago

What do you mean by "function call"? Do you mean the coalesce function call? Or do you mean a module call? If you mean the latter, module inspection can help. https://github.com/terraform-linters/tflint/blob/v0.46.1/docs/user-guide/module-inspection.md

lonegunmanb commented 1 year ago

Apology for the confusion @wata727, it's my mistake, not a bug.

The error was caused by a potential incorrect string interpolation, and TFLint just caught it. I've figured a minimum example that can reproduce an error:

provider "azurerm" {
  features {}
}

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

variable "aks_name" {
  type = string
  default = null
}

variable "prefix" {
  type = string
  default = null
}

resource "azurerm_kubernetes_cluster" "example" {
  name                = coalesce(var.aks_name, "${var.prefix}-aks")
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  dns_prefix          = "exampleaks1"

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

  identity {
    type = "SystemAssigned"
  }

  tags = {
    Environment = "Production"
  }
  lifecycle {
    precondition {
      condition = can(coalesce(var.aks_name, var.prefix))
      error_message = "you must set one of `var.aks_name` and `var.prefix`."
    }
  }
}

We'll meet the following error:

Failed to check ruleset; Failed to check `azurerm_kubernetes_cluster_invalid_name` rule: main.tf:21,51-61: Invalid template interpolation value; The expression result is null. Cannot include a null value in a string template.

We can fix the error if we set prefix's default value to "". Thanks for TFLint, saved my day!