hashicorp / terraform-provider-google

Terraform Provider for Google Cloud Platform
https://registry.terraform.io/providers/hashicorp/google/latest/docs
Mozilla Public License 2.0
2.36k stars 1.75k forks source link

Replication specs re-creation #20351

Closed jagada1010 closed 6 days ago

jagada1010 commented 1 week ago

Community Note

Terraform Version & Provider Version(s)

Terraform vX.X.X on

Affected Resource(s)

mongodbatlas_cluster

Module: main.tf:

resource "mongodbatlas_cluster" "cluster" {
  for_each                       = var.mongodb_config == null ? {} : { for cluster in var.mongodb_config : cluster.cluster_name => cluster if cluster.cluster_name != null }
  project_id                     = each.value.project_id
  name                           = each.value.cluster_name
  mongo_db_major_version         = each.value.mongo_version
  cluster_type                   = each.value.cluster_type
  retain_backups_enabled         = each.value.retain_backups_enabled
  pit_enabled                    = each.value.pit_enabled
  cloud_backup                   = each.value.cloud_backup
  termination_protection_enabled = each.value.termination_protection_enabled
  advanced_configuration {
    oplog_min_retention_hours = each.value.oplog_min_retention_hours
    oplog_size_mb             = each.value.oplog_size_mb
  }

  dynamic "replication_specs" {
    for_each = each.value.replication_specs == null ? {} : { for shards in each.value.replication_specs : shards.num_shards => shards if shards.num_shards != null }
    content {
      num_shards = replication_specs.value.num_shards
      dynamic "regions_config" {
        for_each = replication_specs.value.regions_config == null ? {} : { for region_config in replication_specs.value.regions_config : region_config.region => region_config if region_config.region != null }
        content {
          region_name     = regions_config.value.region
          electable_nodes = regions_config.value.electable_nodes
          priority        = regions_config.value.priority
          read_only_nodes = regions_config.value.read_only_nodes
          analytics_nodes = regions_config.value.analytics_nodes
        }
      }
    }
  }

  dynamic "tags" {
    for_each = { for tags in each.value.tags : tags.key => tags if tags.key != null }
    content {
      key   = tags.value.key
      value = tags.value.value
    }
  }
  # Provider Settings "block"
  auto_scaling_compute_enabled                    = each.value.auto_scaling_compute_enabled
  auto_scaling_compute_scale_down_enabled         = each.value.auto_scaling_compute_scale_down_enabled
  provider_auto_scaling_compute_min_instance_size = each.value.provider_auto_scaling_compute_min_instance_size
  provider_auto_scaling_compute_max_instance_size = each.value.provider_auto_scaling_compute_max_instance_size
  auto_scaling_disk_gb_enabled                    = each.value.auto_scaling_disk_gb_enabled
  provider_name                                   = each.value.provider_name
  disk_size_gb                                    = each.value.disk_size_gb
  provider_instance_size_name                     = each.value.provider_instance_size_name
  lifecycle {
    ignore_changes = [ disk_size_gb]
  }
}

variables.tf:

variable "mongodb_config" {
  type = list(object({
    project_id                                      = string // Atlas project name
    cluster_name                                    = string // Atlas cluster name
    cluster_type                                    = string // Atlas cluster type
    auto_scaling_compute_enabled                    = optional(bool)
    auto_scaling_compute_scale_down_enabled         = optional(bool)
    provider_auto_scaling_compute_min_instance_size = optional(string)
    provider_auto_scaling_compute_max_instance_size = optional(string)
    auto_scaling_disk_gb_enabled                    = bool   // Atlas cluster auto scaling disk enabled
    disk_size_gb                                    = number // Atlas cluster disk size in GB
    provider_name                                   = string // Atlas cluster provider name
    backing_provider_name                           = string // Atlas cluster backing provider name
    provider_instance_size_name                     = string // Atlas cluster provider instance name
    GCP_region                                      = string // GCP region
    mongo_version                                   = string // Atlas cluster version
    retain_backups_enabled                          = bool   // Set to true to retain backup snapshots for the deleted cluster. M10 and above only.
    pit_enabled                                     = bool   // Flag that indicates if the cluster uses Continuous Cloud Backup. If set to true, cloud_backup must also be set to true
    cloud_backup                                    = bool
    termination_protection_enabled                  = bool
    oplog_min_retention_hours                       = number
    oplog_size_mb                                   = number
    tags = optional(list(object({
      key   = string
      value = string
    })))
    replication_specs = list(object({
      num_shards = number // Atlas cluster number of shards
      regions_config = list(object({
        region          = string // Atlas cluster region
        priority        = number // Atlas cluster priority
        read_only_nodes = number // Atlas cluster number of read only node
        electable_nodes = number // Atlas cluster number of electable nodes
        analytics_nodes = optional(number)
      }))
    }))
    database_config = list(object({
      database_user     = string
      database_password = string
      project_id        = string
      roles = list(object({
        role_name     = string // Atlas database user role name
        database_name = string
      }))
      cluster_name       = string
      auth_database_name = string // Auth database name
      labels = optional(list(object({
        key   = string
        value = string
      })))
    }))
  }))
  default = [{
    project_id                     = null // Atlas project name
    cluster_name                   = null // Atlas cluster name
    cluster_type                   = null // Atlas cluster type
    auto_scaling_disk_gb_enabled   = true // Atlas cluster auto scaling disk enabled
    disk_size_gb                   = null // Atlas cluster disk size in GB
    provider_name                  = null // Atlas cluster provider name
    backing_provider_name          = null // Atlas cluster backing provider name
    provider_instance_size_name    = null // Atlas cluster provider instance name
    GCP_region                     = null // GCP region
    retain_backups_enabled         = true // Set to true to retain backup snapshots for the deleted cluster. M10 and above only.
    pit_enabled                    = true // Flag that indicates if the cluster uses Continuous Cloud Backup. If set to true, cloud_backup must also be set to true
    cloud_backup                   = true
    termination_protection_enabled = true
    oplog_min_retention_hours      = 0
    oplog_size_mb                  = 0
    tags = [{
      key   = null
      value = null
    }]
    mongo_version = null // Atlas cluster version
    replication_specs = [{
      num_shards = null
      regions_config = [{
        electable_nodes = null
        priority        = null
        read_only_nodes = null
        region          = null
        analytics_nodes = null
      }]
    }]
    database_config = [{
      database_user      = null
      database_password  = null
      project_id         = null
      cluster_name       = null
      auth_database_name = null
      roles = [{
        database_name = null
        role_name     = null
      }]
      labels = [{
        key   = null
        value = null
      }]
    }]

  }]
}

Runner file: main.tf:

module "mongodb_cluster" {
  source                     = "/local//terraform-mongodb-cluster-database"
  version                    = "1.0.46"
  mongodb_config             = var.mongodb_config
  public_key                 = var.public_key
  private_key                = var.private_key
  atlas_org_id               = var.atlas_org_id
  project_access_list_config = var.project_access_list_config
}

terraform.tfvars:

mongodb_config = [
  // This block will create one project, one cluster, two datbases and two cidr block
  {
    project_id                                      = "ad" // Atlas project id
    cluster_name                                    = "db-1000"         // Atlas cluster name
    cluster_type                                    = "REPLICASET"               // Atlas cluster type
    auto_scaling_disk_gb_enabled                    = true                       // Atlas cluster auto scaling disk enabled
    disk_size_gb                                    = 10                         // Atlas cluster disk size in GB
    provider_name                                   = "GCP"                      // Atlas cluster provider name
    backing_provider_name                           = "GCP"                      // Atlas cluster backing provider name
    provider_instance_size_name                     = "M60"                      // Atlas cluster provider instance name
    GCP_region                                      = "us-central1"              // GCP region
    mongo_version                                   = "6.0"                      // Atlas cluster version
    retain_backups_enabled                          = true                       // Set to true to retain backup snapshots for the deleted cluster. M10 and above only.
    pit_enabled                                     = true                       // Flag that indicates if the cluster uses Continuous Cloud Backup. If set to true, cloud_backup must also be set to true
    cloud_backup                                    = true
    termination_protection_enabled                  = true
    auto_scaling_compute_enabled                    = true
    auto_scaling_compute_scale_down_enabled         = true
    provider_auto_scaling_compute_min_instance_size = "M40"
    provider_auto_scaling_compute_max_instance_size = "M80"
    oplog_min_retention_hours                       = 24
    oplog_size_mb                                   = 1024
    tags = [{
      key   = "Environment"
      value = "Dev"
    }]
    replication_specs = [{
      num_shards = 1
      regions_config = [{
        electable_nodes = 3
        priority        = 7
        read_only_nodes = 0
        region          = "CENTRAL_US"
        },
        /*
        {
          electable_nodes = 0
          priority        = 6
          read_only_nodes = 0
          region          = "EASTERN_US"
        }
        */
      ]
    }]

Terraform Configuration

provider_auto_scaling_compute_max_instance_size = "M80" -> "M20"

Debug Output

No response

Expected Behavior

~ provider_auto_scaling_compute_max_instance_size = "M80" -> "M20"

Plan: 0 to add, 1 to change, 0 to destroy. 

Actual Behavior

~ provider_auto_scaling_compute_max_instance_size = "M80" -> "M20"

- replication_specs {
          - id         = "xxxxxxxxxxxxxxx" -> null
          - num_shards = 1 -> null
          - zone_name  = "Zone 1" -> null
          - regions_config {
              - analytics_nodes = 0 -> null
              - electable_nodes = 3 -> null
              - priority        = 7 -> null
              - read_only_nodes = 0 -> null
              - region_name     = "CENTRAL_US" -> null
            }
        }
+ replication_specs {
          + id         = (known after apply)
          + num_shards = 1
          + zone_name  = "ZoneName managed by Terraform"
          + regions_config {
              + analytics_nodes = 0
              + electable_nodes = 3
              + priority        = 7
              + read_only_nodes = 0
              + region_name     = "CENTRAL_US"
            }
        }

Plan: 0 to add, 1 to change, 0 to destroy.

Steps to reproduce

  1. terraform apply

Important Factoids

I have encountered an issue with Terraform while managing our MongoDB cluster. Recently, I manually changed the cluster tier from M60 to M10, where the auto-scaling instance size range is from M10 to M80 (min, max).

Subsequently, I attempted to update the maximum auto-scaling instance size from M80 to M20 using Terraform. However, when I ran the Terraform plan, it indicated that the replication_specs block would be re-created. This is unexpected, as I have not made any changes to the replication specs either in the Terraform code or through the console. I am concerned about the potential impact of this re-creation on our MongoDB cluster.

I would like to understand why the replication_specs block is being marked for re-creation and what the potential impact of this change might be on our MongoDB cluster.

References

No response

ggtisc commented 6 days ago

Hi @jagada1010!

The mongodbatlas_cluster Terraform resource is not part of Google Cloud Platform (GCP). It's a custom resource created by HashiCorp specifically for managing MongoDB Atlas clusters within Terraform configurations. For this reason, being a foreign resource, it is out of our reach.