Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azurerm_cosmosdb_account - support new property backup.tier #24595

Merged
merged 11 commits into from
Feb 20, 2024
26 changes: 25 additions & 1 deletion internal/services/cosmos/cosmosdb_account_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,12 @@ func resourceCosmosDbAccount() *pluginsdk.Resource {
}, false),
},

"tier": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice(cosmosdb.PossibleValuesForContinuousTier(), false),
},

"interval_in_minutes": {
Type: pluginsdk.TypeInt,
Optional: true,
Expand Down Expand Up @@ -1869,13 +1875,26 @@ func expandCosmosdbAccountBackup(input []interface{}, backupHasChange bool, crea
if v := attr["storage_redundancy"].(string); v != "" && !backupHasChange {
return nil, fmt.Errorf("`storage_redundancy` can not be set when `type` in `backup` is `Continuous`")
}
return cosmosdb.ContinuousModeBackupPolicy{}, nil

result := cosmosdb.ContinuousModeBackupPolicy{}

if v := attr["tier"].(string); v != "" {
result.ContinuousModeProperties = &cosmosdb.ContinuousModeProperties{
Tier: pointer.To(cosmosdb.ContinuousTier(v)),
}
}

return result, nil

case string(cosmosdb.BackupPolicyTypePeriodic):
if createMode != "" {
return nil, fmt.Errorf("`create_mode` only works when `backup.type` is `Continuous`")
}

if v := attr["tier"].(string); v != "" && !backupHasChange {
return nil, fmt.Errorf("`tier` can not be set when `type` in `backup` is `Periodic`")
}

return cosmosdb.PeriodicModeBackupPolicy{
PeriodicModeProperties: &cosmosdb.PeriodicModeProperties{
BackupIntervalInMinutes: utils.Int64(int64(attr["interval_in_minutes"].(int))),
Expand All @@ -1896,9 +1915,14 @@ func flattenCosmosdbAccountBackup(input cosmosdb.BackupPolicy) ([]interface{}, e

switch backupPolicy := input.(type) {
case cosmosdb.ContinuousModeBackupPolicy:
var tier cosmosdb.ContinuousTier
if v := backupPolicy.ContinuousModeProperties; v != nil {
tier = pointer.From(v.Tier)
}
return []interface{}{
map[string]interface{}{
"type": string(cosmosdb.BackupPolicyTypeContinuous),
"tier": string(tier),
},
}, nil

Expand Down
31 changes: 26 additions & 5 deletions internal/services/cosmos/cosmosdb_account_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,7 @@ func TestAccCosmosDBAccount_backupPeriodicToContinuous(t *testing.T) {
},
data.ImportStep(),
{
Config: r.basicWithBackupContinuous(data, cosmosdb.DatabaseAccountKindGlobalDocumentDB, cosmosdb.DefaultConsistencyLevelEventual),
Config: r.basicWithBackupContinuous(data, cosmosdb.DatabaseAccountKindGlobalDocumentDB, cosmosdb.DefaultConsistencyLevelEventual, cosmosdb.ContinuousTierContinuousSevenDays),
Check: acceptance.ComposeAggregateTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
Expand All @@ -1054,7 +1054,14 @@ func TestAccCosmosDBAccount_backupContinuous(t *testing.T) {

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.basicWithBackupContinuous(data, cosmosdb.DatabaseAccountKindGlobalDocumentDB, cosmosdb.DefaultConsistencyLevelEventual),
Config: r.basicWithBackupContinuous(data, cosmosdb.DatabaseAccountKindGlobalDocumentDB, cosmosdb.DefaultConsistencyLevelEventual, cosmosdb.ContinuousTierContinuousSevenDays),
Check: acceptance.ComposeAggregateTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
{
Config: r.basicWithBackupContinuous(data, cosmosdb.DatabaseAccountKindGlobalDocumentDB, cosmosdb.DefaultConsistencyLevelEventual, cosmosdb.ContinuousTierContinuousThreeZeroDays),
Check: acceptance.ComposeAggregateTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
Expand Down Expand Up @@ -3386,7 +3393,7 @@ resource "azurerm_cosmosdb_account" "test" {
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, string(kind), string(consistency))
}

func (CosmosDBAccountResource) basicWithBackupContinuous(data acceptance.TestData, kind cosmosdb.DatabaseAccountKind, consistency cosmosdb.DefaultConsistencyLevel) string {
func (CosmosDBAccountResource) basicWithBackupContinuous(data acceptance.TestData, kind cosmosdb.DatabaseAccountKind, consistency cosmosdb.DefaultConsistencyLevel, tier cosmosdb.ContinuousTier) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
Expand Down Expand Up @@ -3415,9 +3422,10 @@ resource "azurerm_cosmosdb_account" "test" {

backup {
type = "Continuous"
tier = "%s"
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, string(kind), string(consistency))
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, string(kind), string(consistency), string(tier))
}

func (CosmosDBAccountResource) basicWithBackupContinuousUpdate(data acceptance.TestData, kind cosmosdb.DatabaseAccountKind, consistency cosmosdb.DefaultConsistencyLevel) string {
Expand Down Expand Up @@ -3452,6 +3460,10 @@ resource "azurerm_cosmosdb_account" "test" {
backup {
type = "Continuous"
}

lifecycle {
ignore_changes = [backup.0.tier]
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

how come this is required?

Copy link
Contributor Author

@neil-yechenwei neil-yechenwei Feb 1, 2024

Choose a reason for hiding this comment

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

There are two reasons.
Reason 1: Though tier has the default value Continuous30Days but tier is only for the backup type Continuous. So the default value isn't added in the property schema.
Reason 2: API would return the default value Continuous30Days when backup.type is Continuous and tier isn't set. At this time, it would cause diff. So here ignore_changes for tier is added.

Note: I updated PR to add the note for it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I feel like this is a bug, is there no way to correctly handle this so lifecycle ignore changes is not requireD? is this an API bug with the API not returning the correct values?

Copy link
Contributor Author

@neil-yechenwei neil-yechenwei Feb 2, 2024

Choose a reason for hiding this comment

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

Service team confirmed that it's by API design. Actually, This new property is called ContinuousTier in azure-rest-api-spec, which means it only supports the backup type "Continuous" and it doesn't support the backup type "Periodic". So I assume that it's not an API bug.

I listed all behaviors for this new property:

Scenario 1: API doesn't return default value for this new property "ContinuousTier" when backup type is "Periodic" and "ContinuousTier" isn't set.

Scenario 2: API doesn't return any value for this new property "ContinuousTier" when backup type is "Periodic" and "ContinuousTier" is set.

Scenario 3: API returns default value "Continuous30Days" for this new property "ContinuousTier" when backup type is "Continuous" and "ContinuousTier" isn't set.

Scenario 4: API returns value "Continuous7Days" for this new property "ContinuousTier" when backup type is "Continuous" and ContinuousTier is set to "Continuous7Days".

Scenario 5: API returns value "Continuous30Days" for this new property "ContinuousTier" when backup type is "Continuous" and ContinuousTier is set to "Continuous30Days".

}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, string(kind), string(consistency))
}
Expand Down Expand Up @@ -4007,6 +4019,10 @@ resource "azurerm_cosmosdb_account" "test" {
location = azurerm_resource_group.test.location
failover_priority = 0
}

lifecycle {
ignore_changes = [backup.0.tier]
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, string(kind), string(consistency))
}
Expand Down Expand Up @@ -4045,6 +4061,10 @@ resource "azurerm_cosmosdb_account" "test1" {
backup {
type = "Continuous"
}

lifecycle {
ignore_changes = [backup.0.tier]
}
}

resource "azurerm_cosmosdb_mongo_database" "test" {
Expand Down Expand Up @@ -4109,7 +4129,8 @@ resource "azurerm_cosmosdb_account" "test" {
// As "restore_timestamp_in_utc" is retrieved dynamically, so it would cause diff when tf plan. So we have to ignore it here.
lifecycle {
ignore_changes = [
restore.0.restore_timestamp_in_utc
restore.0.restore_timestamp_in_utc,
backup.0.tier
]
}
}
Expand Down
2 changes: 2 additions & 0 deletions website/docs/r/cosmosdb_account.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ A `backup` block supports the following:

* `type` - (Required) The type of the `backup`. Possible values are `Continuous` and `Periodic`. Migration of `Periodic` to `Continuous` is one-way, changing `Continuous` to `Periodic` forces a new resource to be created.

* `tier` - (Optional) The continuous backup tier. Possible values are `Continuous7Days` and `Continuous30Days`.

* `interval_in_minutes` - (Optional) The interval in minutes between two backups. This is configurable only when `type` is `Periodic`. Possible values are between 60 and 1440.

* `retention_in_hours` - (Optional) The time in hours that each backup is retained. This is configurable only when `type` is `Periodic`. Possible values are between 8 and 720.
Expand Down
Loading