Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changelog/3549.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:bug
resource/mongodbatlas_advanced_cluster: Allow upgrade from tenant and flex cluster to dedicated NVMe with backup enabled
```

```release-note:bug
resource/mongodbatlas_advanced_cluster (preview provider 2.0.0): Allow upgrade from tenant and flex cluster to dedicated NVMe with backup enabled
```
6 changes: 5 additions & 1 deletion internal/service/advancedcluster/model_flex.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,13 @@ func GetUpgradeToDedicatedClusterRequest(d *schema.ResourceData) *admin.AtlasTen
if v, ok := d.GetOk("disk_size_gb"); ok {
rootDiskSizeGB = conversion.Pointer(v.(float64))
}
return &admin.AtlasTenantClusterUpgradeRequest20240805{
req := admin.AtlasTenantClusterUpgradeRequest20240805{
Name: clusterName,
ClusterType: conversion.Pointer(d.Get("cluster_type").(string)),
ReplicationSpecs: expandAdvancedReplicationSpecs(d.Get("replication_specs").([]any), rootDiskSizeGB),
}
if d.Get("backup_enabled").(bool) {
req.BackupEnabled = conversion.Pointer(true)
}
return &req
}
Original file line number Diff line number Diff line change
Expand Up @@ -1511,13 +1511,18 @@ func getUpgradeRequest(d *schema.ResourceData) *admin.LegacyAtlasTenantClusterUp
return nil
}

return &admin.LegacyAtlasTenantClusterUpgradeRequest{
req := admin.LegacyAtlasTenantClusterUpgradeRequest{
ProviderSettings: &admin.ClusterProviderSettings{
ProviderName: updatedRegion.GetProviderName(),
InstanceSizeName: updatedRegion.ElectableSpecs.InstanceSize,
RegionName: updatedRegion.RegionName,
},
}
if d.Get("backup_enabled").(bool) {
// ProviderBackupEnabled must be used instead of BackupEnabled for tenant upgrade request, details in CLOUDP-327109
req.ProviderBackupEnabled = conversion.Pointer(true)
}
return &req
}

func waitForUpdateToFinish(ctx context.Context, connV2 *admin.APIClient, projectID, name string, timeout time.Duration) error {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ func TestAccMockableAdvancedCluster_tenantUpgrade(t *testing.T) {
Check: checkTenant(true, projectID, clusterName, true),
},
{
Config: acc.ConvertAdvancedClusterToPreviewProviderV2(t, true, acc.ConfigBasicDedicated(projectID, clusterName, defaultZoneName)),
Check: checksBasicDedicated(projectID, clusterName, true),
Config: acc.ConvertAdvancedClusterToPreviewProviderV2(t, true, acc.ConfigDedicatedNVMeBackupEnabled(projectID, clusterName, defaultZoneName)),
Check: checksDedicatedNVMeBackupEnabled(projectID, clusterName),
},
acc.TestStepImportCluster(resourceName),
},
Expand Down Expand Up @@ -1795,6 +1795,18 @@ func checksBasicDedicated(projectID, name string, checkPlural bool) resource.Tes
return checkAggr(true, nil, checkMap, originalChecks)
}

func checksDedicatedNVMeBackupEnabled(projectID, name string) resource.TestCheckFunc {
originalChecks := checkTenant(true, projectID, name, false)
checkMap := map[string]string{
"backup_enabled": "true",
"replication_specs.0.region_configs.0.electable_specs.0.node_count": "3",
"replication_specs.0.region_configs.0.electable_specs.0.instance_size": "M40_NVME",
"replication_specs.0.region_configs.0.electable_specs.0.ebs_volume_type": "PROVISIONED",
"replication_specs.0.region_configs.0.provider_name": "AWS",
}
return checkAggr(true, nil, checkMap, originalChecks)
}

func configWithKeyValueBlocks(t *testing.T, usePreviewProvider bool, orgID, projectName, clusterName, blockName string, blocks ...map[string]string) string {
t.Helper()
var extraConfig string
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"name": "{clusterName}",
"providerBackupEnabled": true,
"providerSettings": {
"instanceSizeName": "M10",
"instanceSizeName": "M40_NVME",
"providerName": "AWS",
"regionName": "US_EAST_1"
}
Expand Down
20 changes: 18 additions & 2 deletions internal/service/advancedclustertpf/resource_upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package advancedclustertpf

import (
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/constant"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/service/flexcluster"
"go.mongodb.org/atlas-sdk/v20250312006/admin"
)
Expand All @@ -17,14 +18,20 @@ func getUpgradeTenantRequest(state, patch *admin.ClusterDescription20240805) *ad
if oldProviderName != constant.TENANT || newProviderName == constant.TENANT {
return nil
}
return &admin.LegacyAtlasTenantClusterUpgradeRequest{

req := admin.LegacyAtlasTenantClusterUpgradeRequest{
Name: state.GetName(),
ProviderSettings: &admin.ClusterProviderSettings{
ProviderName: newProviderName,
RegionName: newRegion.RegionName,
InstanceSizeName: newRegion.GetElectableSpecs().InstanceSize,
},
}
if patch.GetBackupEnabled() {
// ProviderBackupEnabled must be used instead of BackupEnabled for tenant upgrade request, details in CLOUDP-327109
req.ProviderBackupEnabled = conversion.Pointer(true)
}
return &req
}

func getUpgradeFlexToDedicatedRequest(state, patch *admin.ClusterDescription20240805) *admin.AtlasTenantClusterUpgradeRequest20240805 {
Expand All @@ -40,9 +47,18 @@ func getUpgradeFlexToDedicatedRequest(state, patch *admin.ClusterDescription2024
if oldProviderName != flexcluster.FlexClusterType || newProviderName == flexcluster.FlexClusterType {
return nil
}
return &admin.AtlasTenantClusterUpgradeRequest20240805{
req := admin.AtlasTenantClusterUpgradeRequest20240805{
Name: state.GetName(),
ClusterType: state.ClusterType,
ReplicationSpecs: patch.ReplicationSpecs,
}

backupEnabled := state.BackupEnabled // a flex cluster can already have backup enabled
if patch.BackupEnabled != nil {
backupEnabled = patch.BackupEnabled
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not
req.BackupEnabled = backupEnabled?
Or do we want to avoid setting it if it is false?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would not make a difference, just thought of keeping the upgrade request compact for the regular cases

if backupEnabled != nil && *backupEnabled {
Comment on lines +56 to +60
Copy link
Preview

Copilot AI Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The backup enabled logic could be simplified. Consider using a more direct approach: if (state.GetBackupEnabled() || patch.GetBackupEnabled()) { req.BackupEnabled = conversion.Pointer(true) }

Suggested change
backupEnabled := state.BackupEnabled // a flex cluster can already have backup enabled
if patch.BackupEnabled != nil {
backupEnabled = patch.BackupEnabled
}
if backupEnabled != nil && *backupEnabled {
if state.GetBackupEnabled() || patch.GetBackupEnabled() {

Copilot uses AI. Check for mistakes.

req.BackupEnabled = conversion.Pointer(true)
}
return &req
}
61 changes: 48 additions & 13 deletions internal/testutil/acc/advanced_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,21 +207,56 @@ func ConfigBasicDedicated(projectID, name, zoneName string) string {
%[3]s
}
}
data "mongodbatlas_advanced_cluster" "test" {
project_id = mongodbatlas_advanced_cluster.test.project_id
name = mongodbatlas_advanced_cluster.test.name
use_replication_spec_per_shard = true
depends_on = [mongodbatlas_advanced_cluster.test]
}

data "mongodbatlas_advanced_clusters" "test" {
use_replication_spec_per_shard = true
project_id = mongodbatlas_advanced_cluster.test.project_id
depends_on = [mongodbatlas_advanced_cluster.test]
}
`, projectID, name, zoneNameLine)
%[4]s
`, projectID, name, zoneNameLine, advancedClusterDataSources)
}

func ConfigDedicatedNVMeBackupEnabled(projectID, name, zoneName string) string {
zoneNameLine := ""
if zoneName != "" {
zoneNameLine = fmt.Sprintf("zone_name = %q", zoneName)
}
return fmt.Sprintf(`
resource "mongodbatlas_advanced_cluster" "test" {
project_id = %[1]q
name = %[2]q
cluster_type = "REPLICASET"

backup_enabled = true

replication_specs {
region_configs {
priority = 7
provider_name = "AWS"
region_name = "US_EAST_1"
electable_specs {
instance_size = "M40_NVME"
ebs_volume_type = "PROVISIONED"
node_count = 3
Comment on lines +234 to +235
Copy link
Preview

Copilot AI Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation is inconsistent. All three fields should use the same indentation level as the surrounding code.

Suggested change
ebs_volume_type = "PROVISIONED"
node_count = 3
ebs_volume_type = "PROVISIONED"
node_count = 3

Copilot uses AI. Check for mistakes.

}
}
%[3]s
}
}
%[4]s
`, projectID, name, zoneNameLine, advancedClusterDataSources)
}

const advancedClusterDataSources = `
data "mongodbatlas_advanced_cluster" "test" {
project_id = mongodbatlas_advanced_cluster.test.project_id
name = mongodbatlas_advanced_cluster.test.name
use_replication_spec_per_shard = true
depends_on = [mongodbatlas_advanced_cluster.test]
}

data "mongodbatlas_advanced_clusters" "test" {
use_replication_spec_per_shard = true
project_id = mongodbatlas_advanced_cluster.test.project_id
depends_on = [mongodbatlas_advanced_cluster.test]
}
`

func JoinQuotedStrings(list []string) string {
quoted := make([]string, len(list))
for i, item := range list {
Expand Down