mongodb / terraform-provider-mongodbatlas

Terraform MongoDB Atlas Provider: Deploy, update, and manage MongoDB Atlas infrastructure as code through HashiCorp Terraform
https://registry.terraform.io/providers/mongodb/mongodbatlas
Mozilla Public License 2.0
239 stars 168 forks source link

matcher not allowing null #1489

Closed Kikivsantos closed 11 months ago

Kikivsantos commented 11 months ago

Hi, there.

I'm trying to create some alerts on mongoDB using terraform + terragrunt. It was working just fine, at least, until tuesday.

The error is on the plan. Saying that the matcher cannot be null. But this configuretion does not use matcher.

Terraform CLI and Terraform MongoDB Atlas Provider Version

terraform version
Terraform v1.5.3
on linux_amd64

Terraform Configuration File

My terraform code:

main.tf:


resource "mongodbatlas_alert_configuration" "default" {
  project_id = var.project_id #var.project_id[var.environment]
  event_type = var.event_type #"OUTSIDE_METRIC_THRESHOLD"
  enabled    = var.enabled

  matcher {
    field_name = try(var.matcher.field_name, null)
    operator   = try(var.matcher.operator, null)
    value = try(var.matcher.value, null)
  }

  metric_threshold_config {
    metric_name = try(var.metric_threshold_config.metric_name, null) #"ASSERT_REGULAR"
    operator    = try(var.metric_threshold_config.operator, null) #"LESS_THAN"
    threshold   = try(var.metric_threshold_config.threshold, null)#99.0
    units       = try(var.metric_threshold_config.units, null)#"RAW"
    mode        = try(var.metric_threshold_config.mode, null)#"AVERAGE"
  }

  threshold_config {
    operator    = try(var.threshold_config.operator, null) #"LESS_THAN"
    threshold   = try(var.threshold_config.threshold, null)#99.0
    units       = try(var.threshold_config.units, null)#"RAW"
  }

  notification {
    type_name     = var.notification.type_name #"GROUP" SLACK etc
    interval_min  = var.notification.interval_min # 5
    delay_min     = var.notification.delay_min #0
    sms_enabled   = try(var.notification.sms_enabled, null) #false
    email_enabled = try(var.notification.email_enabled, null) #true
    roles         = try(var.notification.roles, null) #["GROUP_OWNER", "GROUP_CLUSTER_MANAGER"]
    api_token     = try(var.slack_bot_token_dbre, null) 
    channel_name  = try(var.notification.channel_name, null)
    datadog_api_key = try(var.datadog_api_key,null)  ### aki_key para uso do datadog. Precisou ser fora por ser secret
    datadog_region  = try(var.notification.datadog_region, null)
    email_address = try(var.notification.email_address, null)
    #flowdock_api_token = try(var.notification.flowdock_api_token, null)
    #flow_name       = try(var.notification.flow_name, null)
    mobile_number   = try(var.notification.mobile_number, null)
    ops_genie_api_key = try(var.ops_genie_api_key, null)
    ops_genie_region  = try(var.notification.ops_genie_region, null)
    #org_name          = try(var.notification.org_name, null)
    service_key       = try(var.service_key, null)
    username          = try(var.notification.username, null)
    victor_ops_api_key  = try(var.victor_ops_api_key, null)
    victor_ops_routing_key  = try(var.victor_ops_routing_key, null)
    webhook_secret          = try(var.webhook_secret, null)
    webhook_url             = try(var.notification.webhook_url, null)
    microsoft_teams_webhook_url = try(var.notification.microsoft_teams_webhook_url, null)
  }

}

variable.tf


  variable "project_id" {
      description = <<HEREDOC
      (Required) The ID of the project where the alert configuration will create.
      HEREDOC
  }

  variable "enabled" {
      description = <<HEREDOC
      It is not required, but If the attribute is omitted, by default will be false, and the configuration would be disabled. You must set true to enable the configuration.
      HEREDOC
      default = true
  }

  variable "event_type" {
      description = <<HEREDOC
      (Required) The type of event that will trigger an alert.
      OPtions in https://www.mongodb.com/docs/cloud-manager/reference/alert-types/#alert-event-types
      HEREDOC
  }

  variable "notification" {
    description = "List of notifications to send when an alert condition is detected"
    type = any
    default = {
      type_name               = "GROUP",
      channel_name            = null,
      datadog_api_key         = null,
      delay_min               = 0,
      interval_min            = 60,
      email_enabled           = null,
      sms_enabled             = null,
      mobile_number           = null,
      roles                   = null,
      datadog_region          = null,
      email_address           = null,
      ops_genie_region        = null,
      username                = null,
      webhook_url             = null,
      microsoft_teams_webhook_url = null
    }
  }

  variable "slack_bot_token_dbre" {
      type = string
      sensitive = true
  }

  variable "ops_genie_api_key" {
      type = string
      sensitive = true
      default = null
  }

  variable "victor_ops_api_key" {
    type = string
    sensitive = true
    default = null
  }

  variable "service_key" {
    type = string
    sensitive = true
    default = null
  }

  variable "victor_ops_routing_key" {
    type = string
    sensitive = true
    default = null
  }

  variable "datadog_api_key" {
      type = string
      sensitive = true  
      default = null
  }

  variable "webhook_secret" {
      type = string
      sensitive = true
      default = null
  }

  variable "metric_threshold_config" {
      description = <<HEREDOC
      The threshold that causes an alert to be triggered. 
      Required if event_type_name : OUTSIDE_METRIC_THRESHOLD or OUTSIDE_SERVERLESS_METRIC_THRESHOLD
      HEREDOC
      type = any
      default = null
  }

  variable "threshold_config" {
      type = any
      default = null
  }

  variable "matcher" {
      type = any
      default = null
  }

My terragrunt code:

1) For CPS_OPLOG_BEHIND


locals {
  component_name = "modules/alert"
  component_version = "v1.2.2"
}

include "root" {
  path = "${get_repo_root()}/terragrunt.hcl"
}

dependency "project" {
  config_path = "../.."
}

inputs = {
  project_id   = dependency.project.outputs.project_id
  event_type = "CPS_OPLOG_BEHIND" 
  enabled   = true

  notification = {
    type_name     = "SLACK"
    interval_min  = 1440
    delay_min     = 0   
    channel_name = "database-alerts"
  }

  threshold_config = {
    operator    = "GREATER_THAN"
    threshold   = 1
    units       = "HOURS"
  }

} 

2) For CPS_SNAPSHOT_BEHIND


locals {
  component_name = "modules/alert"
  component_version = "v1.2.2"
}

include "root" {
  path = "${get_repo_root()}/terragrunt.hcl"
}

dependency "project" {
  config_path = "../.."
}

inputs = {
  project_id   = dependency.project.outputs.project_id
  event_type = "CPS_SNAPSHOT_BEHIND" 
  enabled   = true

  notification = {
    type_name     = "SLACK"
    interval_min  = 1440
    delay_min     = 0   
    channel_name = "database-alerts"
  }

  threshold_config = {
    operator    = "GREATER_THAN"
    threshold   = 1
    units       = "HOURS"
  }
} 

3) For CONNECTIONS_PERCENT:

locals {
  component_name = "modules/alert"
  component_version = "v1.2.2"
}

include "root" {
  path = "${get_repo_root()}/terragrunt.hcl"
}

dependency "project" {
  config_path = "../.."
}

inputs = {
  project_id   = dependency.project.outputs.project_id
  event_type = "OUTSIDE_METRIC_THRESHOLD" 
  enabled   = true

  notification = {
    type_name     = "SLACK"
    interval_min  = 1440
    delay_min     = 0   
    #api_token = get_env("TF_VAR_slack_bot_token_dbre")
    channel_name = "database-alerts"
  }

  metric_threshold_config = {
    metric_name  = "CONNECTIONS_PERCENT"
    mode = "AVERAGE"
    operator = "GREATER_THAN"
    threshold = 85.0
    units = "RAW"
  }

} 

Steps to Reproduce

  1. terraform init
  2. terraform plan

Expected Behavior

It should show the 3 alerts that would be created

Actual Behavior

Got the error below:

Planning failed. Terraform encountered an error while generating this plan.

Error: Missing Configuration for Required Attribute

  with mongodbatlas_alert_configuration.default,
  on main.tf line 8, in resource "mongodbatlas_alert_configuration" "default":
   8:     field_name = try(var.matcher.field_name, null)

Must set a configuration value for the matcher[0].field_name attribute as the
provider has marked it as required.

Refer to the provider documentation or contact the provider developers for
additional information about configurable attributes that are required.

Error: Missing Configuration for Required Attribute

  with mongodbatlas_alert_configuration.default,
  on main.tf line 9, in resource "mongodbatlas_alert_configuration" "default":
   9:     operator   = try(var.matcher.operator, null)

Must set a configuration value for the matcher[0].operator attribute as the
provider has marked it as required.

Refer to the provider documentation or contact the provider developers for
additional information about configurable attributes that are required.

Error: Missing Configuration for Required Attribute

  with mongodbatlas_alert_configuration.default,
  on main.tf line 10, in resource "mongodbatlas_alert_configuration" "default":
  10:     value = try(var.matcher.value, null)

Must set a configuration value for the matcher[0].value attribute as the
provider has marked it as required.

Debug Output

Crash Output

Additional Context

References

github-actions[bot] commented 11 months ago

Thanks for opening this issue. The ticket INTMDB-1131 was created for internal tracking.

marcosuma commented 11 months ago

Hi @Kikivsantos, similarly to https://github.com/mongodb/terraform-provider-mongodbatlas/issues/1473 we cannot directly provide assistance on terraform+terragrunt integration.

In order for us to promptly help, we'll need you to be able to replicate the issue with by using our provider directly.

Said that, when you say But this configuretion does not use matcher. what do you mean precisely? I see in your main.tf file you are using the matcher attribute: have you made sure you are passing the expected values?

Kikivsantos commented 11 months ago

Hi @marcosuma this is similar to the problem you guys resolved in the issue:

I'm creating a module to be used for our alerts. So I need to put all the possible options. That's why I use the "try()" on all the options that are not required for any alerts.

When I call this module that I created (my main.tf) I pass the values that I'm really going to use. It has to ingore all the rest - that's why we use try(..., null)

But the issue is just as the one you guys resolved on the one I opened before

Thanks

marcosuma commented 11 months ago

Ok, then if all good I am going ahead to resolve this one. Thank you @Kikivsantos