mongodb/terraform-provider-mongodbatlas

[Bug]: Provider produced inconsistent result after apply

Closed this issue · 6 comments

Is there an existing issue for this?

  • I have searched the existing issues

Provider Version

v1.21.1

Terraform Version

v1.8.2

Terraform Edition

Terraform Cloud

Current Behavior

Within a project scope, when removing the following roles from a team:

[GROUP_DATA_ACCESS_ADMIN", "GROUP_DATA_ACCESS_READ_ONLY", "GROUP_DATA_ACCESS_READ_WRITE", "GROUP_OWNER", "GROUP_READ_ONLY", "GROUP_SEARCH_INDEX_EDITOR]

but adding the following roles

[GROUP_DATA_ACCESS_READ_ONLY", "GROUP_READ_ONLY", "GROUP_SEARCH_INDEX_EDITOR"]

Plan is successful, but during apply the following error is thrown:

Error: Provider produced inconsistent result after apply

When applying changes to
module.atlas_mongodb[].mongodbatlas_project.atlas_project,
provider "provider["registry.terraform.io/mongodb/mongodbatlas"]"
produced an unexpected new value: .ip_addresses.services.clusters: new
element 0 has appeared.

This is a bug in the provider, which should be reported in the provider's
own issue tracker.

Terraform configuration to reproduce the issue

data "mongodbatlas_team" "admin_sre" {
  for_each = toset(local.filtered_admin_team_names)
  org_id   = var.atlas_org_id
  name     = each.value
}

data "mongodbatlas_team" "read_only" {
  for_each = var.atlas_read_only_teams
  org_id   = var.atlas_org_id
  name     = each.value
}

resource "mongodbatlas_project" "atlas_project" {
  org_id           = var.atlas_org_id
  project_owner_id = var.atlas_project_owner_id
  name             = "${var.environment_name}-${var.service_name}"

  teams {
    team_id    = data.mongodbatlas_team.owning_dev.team_id
    role_names = var.atlas_project_permissions["dev"]
  }

  teams {
    team_id    = data.mongodbatlas_team.owning_sre.team_id
    role_names = var.atlas_project_permissions["sre"]
  }

  dynamic "teams" {
    for_each = data.mongodbatlas_team.admin_sre
    content {
      team_id    = teams.value.team_id
      role_names = var.atlas_project_permissions["sre"]
    }
  }

  dynamic "teams" {
    for_each = data.mongodbatlas_team.read_only
    content {
      team_id    = teams.value.team_id
      role_names = var.atlas_project_permissions["read_only"]
    }
  }

  is_collect_database_specifics_statistics_enabled = true
  is_data_explorer_enabled                         = true
  is_performance_advisor_enabled                   = true
  is_realtime_performance_panel_enabled            = true
  is_schema_advisor_enabled                        = true
  with_default_alerts_settings                     = false
}

Steps To Reproduce

Within a project scope, when remove the following roles from a team:

[GROUP_DATA_ACCESS_ADMIN", "GROUP_DATA_ACCESS_READ_ONLY", "GROUP_DATA_ACCESS_READ_WRITE", "GROUP_OWNER", "GROUP_READ_ONLY", "GROUP_SEARCH_INDEX_EDITOR]

while adding the following roles

[GROUP_DATA_ACCESS_READ_ONLY", "GROUP_READ_ONLY", "GROUP_SEARCH_INDEX_EDITOR"]

With this particular configuration, move a team from the set in "data.mongodbatlas_team.admin_sre" to "data.mongodbatlas_team.read_only"

Logs

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Thanks for opening this issue! Please make sure you've followed our guidelines when opening the issue. In short, to help us reproduce the issue we need:

  • Terraform configuration file used to reproduce the issue
  • Terraform log files from the run where the issue occurred
  • Terraform Atlas provider version used to reproduce the issue
  • Terraform version used to reproduce the issue
  • Confirmation if Terraform OSS, Terraform Cloud, or Terraform Enterprise deployment

The ticket CLOUDP-278678 was created for internal tracking.

Hi @spencer-langley, thank you for raising this issue to us. I tried to replicate the issue as you described but I couldn't manage it. In order to make sure I did the right steps, here's what I did:

versions.tf

terraform {
  required_providers {
    mongodbatlas = {
      source  = "mongodb/mongodbatlas"
      version = "= 1.21.1"
    }
  }
  required_version = "= 1.8.2"
}

variables.tf

variable "private_key" {
  type = string

}
variable "public_key" {
  type = string

}


variable "atlas_org_id" {
  type = string

}

variable "user1" {
  type = string

}

variable "user2" {
  type = string

}

variable "user3" {
  type = string

}

variable "user4" {
  type = string

}

# variable "atlas_read_only_teams" {
#   type = list(string)
#   default = [""]
# }

variable "atlas_project_owner_id" {
  type = string

}

variable "environment_name" {
  type = string
  default = "dev"
}

variable "service_name" {
  type = string
  default = "service_test"
}

variable "atlas_project_permissions" {
  type = object({
    sre       = list(string),
    # dev       = list(string),
    read_only = list(string)
  })
  default = {
    "sre"       = ["GROUP_DATA_ACCESS_ADMIN", "GROUP_DATA_ACCESS_READ_ONLY", "GROUP_DATA_ACCESS_READ_WRITE", "GROUP_OWNER", "GROUP_READ_ONLY", "GROUP_SEARCH_INDEX_EDITOR"],
    # "dev"       = [],
    "read_only" = ["GROUP_DATA_ACCESS_READ_ONLY", "GROUP_READ_ONLY", "GROUP_SEARCH_INDEX_EDITOR"]
  }
}

main.tf

resource "mongodbatlas_team" "admin_sre_1" {
  org_id     = var.atlas_org_id
  name       = "admin_sre_1"
  usernames  = [var.user1]
}

resource "mongodbatlas_team" "admin_sre_2" {
  org_id     = var.atlas_org_id
  name       = "admin_sre_2"
usernames  = [var.user2]
}

resource "mongodbatlas_team" "read_only_1" {
  org_id     = var.atlas_org_id
  name       = "read_only_1"
  usernames  = [var.user3]
}

resource "mongodbatlas_team" "read_only_2" {
  org_id     = var.atlas_org_id
  name       = "read_only_2"
  usernames  = [var.user4]
}

data "mongodbatlas_team" "admin_sre" {
  for_each = toset([mongodbatlas_team.admin_sre_1.name, mongodbatlas_team.admin_sre_2.name])
  org_id   = var.atlas_org_id
  name     = each.value
}

data "mongodbatlas_team" "read_only" {
  for_each = toset([mongodbatlas_team.read_only_1.name, mongodbatlas_team.read_only_2.name])
  org_id   = var.atlas_org_id
  name     = each.value
}

resource "mongodbatlas_project" "atlas_project" {
  org_id           = var.atlas_org_id
  project_owner_id = var.atlas_project_owner_id
  name             = "${var.environment_name}-${var.service_name}"

  # teams {
  #   team_id    = data.mongodbatlas_team.owning_dev.team_id
  #   role_names = var.atlas_project_permissions["dev"]
  # }

  # teams {
  #   team_id    = data.mongodbatlas_team.owning_sre.team_id
  #   role_names = var.atlas_project_permissions["sre"]
  # }

  dynamic "teams" {
    for_each = data.mongodbatlas_team.admin_sre
    content {
      team_id    = teams.value.team_id
      role_names = var.atlas_project_permissions["sre"]
    }
  }

  dynamic "teams" {
    for_each = data.mongodbatlas_team.read_only
    content {
      team_id    = teams.value.team_id
      role_names = var.atlas_project_permissions["read_only"]
    }
  }

  is_collect_database_specifics_statistics_enabled = true
  is_data_explorer_enabled                         = true
  is_performance_advisor_enabled                   = true
  is_realtime_performance_panel_enabled            = true
  is_schema_advisor_enabled                        = true
  with_default_alerts_settings                     = false
}

terraform apply was successful!

Then I went to the variables.tf and changed the roles as following:

variable "atlas_project_permissions" {
  type = object({
    sre       = list(string),
    # dev       = list(string),
    read_only = list(string)
  })
  default = {
    "sre"       = ["GROUP_DATA_ACCESS_READ_ONLY", "GROUP_READ_ONLY", "GROUP_SEARCH_INDEX_EDITOR"],
    # "dev"       = [],
    "read_only" = ["GROUP_DATA_ACCESS_READ_ONLY", "GROUP_READ_ONLY", "GROUP_SEARCH_INDEX_EDITOR"]
  }
}

and also went to main.tf and did the following:

data "mongodbatlas_team" "admin_sre" {
  for_each = toset([mongodbatlas_team.admin_sre_1.name, mongodbatlas_team.admin_sre_2.name, mongodbatlas_team.read_only_1.name])
  org_id   = var.atlas_org_id
  name     = each.value
}

data "mongodbatlas_team" "read_only" {
  for_each = toset([mongodbatlas_team.read_only_2.name])
  org_id   = var.atlas_org_id
  name     = each.value
}

terraform apply was successful and did the update. Any subsequent terraform plan revealed no changes.

Is what I did accurate?

No, don't moody the defaults for team type permissions on "atlas_project_permissions". Only change which teams are mapped to "admin_sre" or "read_only".

I've found this can be intermittent as well. I just used the provider to remove 2 teams from "admin_sre" (without adding them to "read_only", trying a phased change as a workaround for this bug) from 33 projects at once and encountered this error on 1. Rerun was successful on that 1/33.

Hi @spencer-langley , from the last thing you said it seems to me a race condition issue.

  1. Is your script containing a lot of teams associated to the same project?
  2. Are you able to extract the DEBUG logs for your next terraform apply so we can see what is the API returning for all those calls when you encounter the issue?

I won't be able recreate the issue without compromising my production pipeline.

This issue has gone 7 days without any activity and meets the project’s definition of "stale". This will be auto-closed if there is no new activity over the next 7 days. If the issue is still relevant and active, you can simply comment with a "bump" to keep it open, or add the label "not_stale". Thanks for keeping our repository healthy!