From 3721fe5b6c0978426cea1cbfdd9375ca4cff7366 Mon Sep 17 00:00:00 2001 From: Wodans Son <20408400+WodansSon@users.noreply.github.com> Date: Wed, 21 Feb 2024 21:49:52 -0700 Subject: [PATCH] Including #24892 * Initial Check-in... * Fix typo in update function... * Add note to documentation for the new storage_tier field... * Check-in progress... * Fix lint error... * Adding test cases... * Update mapping table... * Remove comments... * Fix test validation... * Reduce size of upscale... * Added 4193280 back in as a valid value for storage_mb... * Update document table... * Add host caching note to table... * Move default value assignment from diff to expand... * Move logic back to custom diff... * Add code to make defaults work in create... * Move default values from expand into create only... * Update code comment... * Fix for gradually deprecated functions... --- .../postgresql_flexible_server_resource.go | 112 ++++++++++++- ...ostgresql_flexible_server_resource_test.go | 153 +++++++++++++++++- .../validate/flexible_server_storage_tier.go | 90 +++++++++++ .../postgresql_flexible_server.html.markdown | 40 ++++- 4 files changed, 384 insertions(+), 11 deletions(-) create mode 100644 internal/services/postgres/validate/flexible_server_storage_tier.go diff --git a/internal/services/postgres/postgresql_flexible_server_resource.go b/internal/services/postgres/postgresql_flexible_server_resource.go index b59da096e91d..cc74656fa397 100644 --- a/internal/services/postgres/postgresql_flexible_server_resource.go +++ b/internal/services/postgres/postgresql_flexible_server_resource.go @@ -21,6 +21,7 @@ import ( "github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2021-06-01/serverrestart" "github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/servers" "github.com/hashicorp/go-azure-sdk/resource-manager/privatedns/2020-06-01/privatezones" + "github.com/hashicorp/terraform-provider-azurerm/helpers/azure" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" keyVaultValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/keyvault/validate" @@ -133,6 +134,25 @@ func resourcePostgresqlFlexibleServer() *pluginsdk.Resource { ValidateFunc: validation.IntInSlice([]int{32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4193280, 4194304, 8388608, 16777216, 33553408}), }, + "storage_tier": { + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + string(servers.AzureManagedDiskPerformanceTiersPFour), + string(servers.AzureManagedDiskPerformanceTiersPSix), + string(servers.AzureManagedDiskPerformanceTiersPOneZero), + string(servers.AzureManagedDiskPerformanceTiersPOneFive), + string(servers.AzureManagedDiskPerformanceTiersPTwoZero), + string(servers.AzureManagedDiskPerformanceTiersPThreeZero), + string(servers.AzureManagedDiskPerformanceTiersPFourZero), + string(servers.AzureManagedDiskPerformanceTiersPFiveZero), + string(servers.AzureManagedDiskPerformanceTiersPSixZero), + string(servers.AzureManagedDiskPerformanceTiersPSevenZero), + string(servers.AzureManagedDiskPerformanceTiersPEightZero), + }, false), + }, + "version": { Type: pluginsdk.TypeString, Optional: true, @@ -344,6 +364,58 @@ func resourcePostgresqlFlexibleServer() *pluginsdk.Resource { if oldLoginName != "" { diff.ForceNew("administrator_login") } + return nil + }, func(ctx context.Context, diff *pluginsdk.ResourceDiff, v interface{}) error { + storageTierMappings := validate.InitializeFlexibleServerStorageTierDefaults() + var newTier string + var newMb int + var isValid bool + + oldStorageMbRaw, newStorageMbRaw := diff.GetChange("storage_mb") + oldTierRaw, newTierRaw := diff.GetChange("storage_tier") + + if oldStorageMbRaw.(int) == 0 && oldTierRaw.(string) == "" && newStorageMbRaw.(int) == 0 && newTierRaw.(string) == "" { + // This is a new resource without any values in the state + // or config, default values will be set in create... + return nil + } + + newMb = newStorageMbRaw.(int) + newTier = newTierRaw.(string) + + // storage_mb can only be scaled up... + if newMb < oldStorageMbRaw.(int) { + return fmt.Errorf("'storage_mb' can only be scaled up, expected the new 'storage_mb' value (%d) to be larger than the previous 'storage_mb' value (%d)", newMb, oldStorageMbRaw.(int)) + } + + // if newMb or newTier values are empty, + // assign the default values that will + // be assigned in the create func... + if newMb == 0 { + newMb = 32768 + } + + // get the valid mappings for the passed + // storage_mb size... + storageTiers := storageTierMappings[newMb] + + if newTier == "" { + newTier = string(storageTiers.DefaultTier) + } + + // verify that the storage_tier is valid + // for the given storage_mb... + for _, tier := range *storageTiers.ValidTiers { + if newTier == tier { + isValid = true + break + } + } + + if !isValid { + return fmt.Errorf("invalid 'storage_tier' %q for defined 'storage_mb' size '%d', expected one of [%s]", newTier, newMb, azure.QuotedStringSlice(*storageTiers.ValidTiers)) + } + return nil }, ), @@ -408,6 +480,7 @@ func resourcePostgresqlFlexibleServerCreate(d *pluginsdk.ResourceData, meta inte if !adminLoginSet { return fmt.Errorf("`administrator_login` is required when `create_mode` is `Default` and `authentication.password_auth_enabled` is set to `true`") } + if !adminPwdSet { return fmt.Errorf("`administrator_password` is required when `create_mode` is `Default` and `authentication.password_auth_enabled` is set to `true`") } @@ -418,12 +491,10 @@ func resourcePostgresqlFlexibleServerCreate(d *pluginsdk.ResourceData, meta inte if _, ok := d.GetOk("sku_name"); !ok { return fmt.Errorf("`sku_name` is required when `create_mode` is `Default`") } + if _, ok := d.GetOk("version"); !ok { return fmt.Errorf("`version` is required when `create_mode` is `Default`") } - if _, ok := d.GetOk("storage_mb"); !ok { - return fmt.Errorf("`storage_mb` is required when `create_mode` is `Default`") - } } sku, err := expandFlexibleServerSku(d.Get("sku_name").(string)) @@ -431,11 +502,32 @@ func resourcePostgresqlFlexibleServerCreate(d *pluginsdk.ResourceData, meta inte return fmt.Errorf("expanding `sku_name` for %s: %v", id, err) } + storage := expandArmServerStorage(d) + var storageMb int + + if storage.StorageSizeGB == nil || *storage.StorageSizeGB == 0 { + // set the default value for storage_mb... + storageMb = 32768 + storage.StorageSizeGB = pointer.FromInt64(int64(32)) + log.Printf("[DEBUG]: Default 'storage_mb' Set -> %d\n", storageMb) + } else { + storageMb = int(*storage.StorageSizeGB) * 1024 + } + + if storage.Tier == nil || *storage.Tier == "" { + // determine the correct default storage_tier based + // on the defined storage_mb... + storageTierMappings := validate.InitializeFlexibleServerStorageTierDefaults() + storageTiers := storageTierMappings[storageMb] + storage.Tier = pointer.To(storageTiers.DefaultTier) + log.Printf("[DEBUG]: Default 'storage_tier' Set -> %q\n", storageTiers.DefaultTier) + } + parameters := servers.Server{ Location: location.Normalize(d.Get("location").(string)), Properties: &servers.ServerProperties{ Network: expandArmServerNetwork(d), - Storage: expandArmServerStorage(d), + Storage: storage, HighAvailability: expandFlexibleServerHighAvailability(d.Get("high_availability").([]interface{}), true), Backup: expandArmServerBackup(d), DataEncryption: expandFlexibleServerDataEncryption(d.Get("customer_managed_key").([]interface{})), @@ -573,6 +665,10 @@ func resourcePostgresqlFlexibleServerRead(d *pluginsdk.ResourceData, meta interf if storage.StorageSizeGB != nil { d.Set("storage_mb", (*storage.StorageSizeGB * 1024)) } + + if storage.Tier != nil { + d.Set("storage_tier", string(*storage.Tier)) + } } if backup := props.Backup; backup != nil { @@ -741,7 +837,7 @@ func resourcePostgresqlFlexibleServerUpdate(d *pluginsdk.ResourceData, meta inte parameters.Properties.AuthConfig = expandFlexibleServerAuthConfig(d.Get("authentication").([]interface{})) } - if d.HasChange("auto_grow_enabled") || d.HasChange("storage_mb") { + if d.HasChange("auto_grow_enabled") || d.HasChange("storage_mb") || d.HasChange("storage_tier") { // TODO remove the additional update after https://github.com/Azure/azure-rest-api-specs/issues/22867 is fixed storageUpdateParameters := servers.ServerForUpdate{ Properties: &servers.ServerPropertiesForUpdate{ @@ -898,7 +994,11 @@ func expandArmServerStorage(d *pluginsdk.ResourceData) *servers.Storage { storage.AutoGrow = &autoGrow if v, ok := d.GetOk("storage_mb"); ok { - storage.StorageSizeGB = utils.Int64(int64(v.(int) / 1024)) + storage.StorageSizeGB = pointer.FromInt64(int64(v.(int) / 1024)) + } + + if v, ok := d.GetOk("storage_tier"); ok { + storage.Tier = pointer.To(servers.AzureManagedDiskPerformanceTiers(v.(string))) } return &storage diff --git a/internal/services/postgres/postgresql_flexible_server_resource_test.go b/internal/services/postgres/postgresql_flexible_server_resource_test.go index 730b74e7aa6b..fdaf3fde2192 100644 --- a/internal/services/postgres/postgresql_flexible_server_resource_test.go +++ b/internal/services/postgres/postgresql_flexible_server_resource_test.go @@ -6,6 +6,7 @@ package postgres_test import ( "context" "fmt" + "regexp" "testing" "time" @@ -29,6 +30,8 @@ func TestAccPostgresqlFlexibleServer_basic(t *testing.T) { check.That(data.ResourceName).ExistsInAzure(r), check.That(data.ResourceName).Key("fqdn").Exists(), check.That(data.ResourceName).Key("public_network_access_enabled").Exists(), + check.That(data.ResourceName).Key("storage_mb").HasValue("32768"), + check.That(data.ResourceName).Key("storage_tier").HasValue("P4"), ), }, data.ImportStep("administrator_password", "create_mode"), @@ -75,6 +78,8 @@ func TestAccPostgresqlFlexibleServer_completeUpdate(t *testing.T) { check.That(data.ResourceName).ExistsInAzure(r), check.That(data.ResourceName).Key("fqdn").Exists(), check.That(data.ResourceName).Key("public_network_access_enabled").Exists(), + check.That(data.ResourceName).Key("storage_tier").HasValue("P4"), + check.That(data.ResourceName).Key("storage_mb").HasValue("32768"), ), }, data.ImportStep("administrator_password", "create_mode"), @@ -84,6 +89,8 @@ func TestAccPostgresqlFlexibleServer_completeUpdate(t *testing.T) { check.That(data.ResourceName).ExistsInAzure(r), check.That(data.ResourceName).Key("fqdn").Exists(), check.That(data.ResourceName).Key("public_network_access_enabled").Exists(), + check.That(data.ResourceName).Key("storage_tier").HasValue("P6"), + check.That(data.ResourceName).Key("storage_mb").HasValue("65536"), ), }, data.ImportStep("administrator_password", "create_mode"), @@ -410,6 +417,93 @@ func TestAccPostgresqlFlexibleServer_autoGrowEnabled(t *testing.T) { }) } +func TestAccPostgresqlFlexibleServer_invalidStorageTier(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_postgresql_flexible_server", "test") + r := PostgresqlFlexibleServerResource{} + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.invalidStorageTier(data), + ExpectError: regexp.MustCompile("invalid 'storage_tier'"), + }, + }) +} + +func TestAccPostgresqlFlexibleServer_invalidStorageMbScaling(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_postgresql_flexible_server", "test") + r := PostgresqlFlexibleServerResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.invalidStorageMbScaling(data, "524288"), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("administrator_password", "create_mode"), + { + Config: r.invalidStorageMbScaling(data, "262144"), + ExpectError: regexp.MustCompile("'storage_mb' can only be scaled up"), + }, + }) +} + +func TestAccPostgresqlFlexibleServer_invalidStorageTierScalingStorageMb(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_postgresql_flexible_server", "test") + r := PostgresqlFlexibleServerResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.invalidStorageTierScaling(data, "P4", "32768"), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("administrator_password", "create_mode"), + { + Config: r.invalidStorageTierScaling(data, "P4", "262144"), + ExpectError: regexp.MustCompile("invalid 'storage_tier'"), + }, + }) +} + +func TestAccPostgresqlFlexibleServer_invalidStorageTierScalingStorageTier(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_postgresql_flexible_server", "test") + r := PostgresqlFlexibleServerResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.invalidStorageTierScaling(data, "P4", "32768"), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("administrator_password", "create_mode"), + { + Config: r.invalidStorageTierScaling(data, "P80", "32768"), + ExpectError: regexp.MustCompile("invalid 'storage_tier'"), + }, + }) +} + +func TestAccPostgresqlFlexibleServer_invalidStorageTierScalingStorageMbStorageTier(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_postgresql_flexible_server", "test") + r := PostgresqlFlexibleServerResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.invalidStorageTierScaling(data, "P4", "32768"), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("administrator_password", "create_mode"), + { + Config: r.invalidStorageTierScaling(data, "P6", "131072"), + ExpectError: regexp.MustCompile("invalid 'storage_tier'"), + }, + }) +} + func (PostgresqlFlexibleServerResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { id, err := servers.ParseFlexibleServerID(state.ID) if err != nil { @@ -447,7 +541,6 @@ resource "azurerm_postgresql_flexible_server" "test" { location = azurerm_resource_group.test.location administrator_login = "adminTerraform" administrator_password = "QAZwsx123" - storage_mb = 32768 version = "12" sku_name = "GP_Standard_D2s_v3" zone = "2" @@ -600,6 +693,7 @@ resource "azurerm_postgresql_flexible_server" "test" { version = "13" backup_retention_days = 10 storage_mb = 65536 + storage_tier = "P6" delegated_subnet_id = azurerm_subnet.test.id private_dns_zone_id = azurerm_private_dns_zone.test.id sku_name = "GP_Standard_D2s_v3" @@ -1055,3 +1149,60 @@ resource "azurerm_postgresql_flexible_server" "test" { } `, r.template(data), data.RandomInteger, autoGrowEnabled) } + +func (r PostgresqlFlexibleServerResource) invalidStorageTier(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +resource "azurerm_postgresql_flexible_server" "test" { + name = "acctest-fs-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + administrator_login = "adminTerraform" + administrator_password = "QAZwsx123" + storage_mb = 65536 + storage_tier = "P4" + version = "12" + sku_name = "GP_Standard_D2s_v3" + zone = "2" +} +`, r.template(data), data.RandomInteger) +} + +func (r PostgresqlFlexibleServerResource) invalidStorageMbScaling(data acceptance.TestData, storageMb string) string { + return fmt.Sprintf(` +%s + +resource "azurerm_postgresql_flexible_server" "test" { + name = "acctest-fs-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + administrator_login = "adminTerraform" + administrator_password = "QAZwsx123" + storage_mb = %s + storage_tier = "P20" + version = "12" + sku_name = "GP_Standard_D2s_v3" + zone = "2" +} +`, r.template(data), data.RandomInteger, storageMb) +} + +func (r PostgresqlFlexibleServerResource) invalidStorageTierScaling(data acceptance.TestData, storageTier string, storageMb string) string { + return fmt.Sprintf(` +%s + +resource "azurerm_postgresql_flexible_server" "test" { + name = "acctest-fs-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + administrator_login = "adminTerraform" + administrator_password = "QAZwsx123" + storage_mb = %s + storage_tier = "%s" + version = "12" + sku_name = "GP_Standard_D2s_v3" + zone = "2" +} +`, r.template(data), data.RandomInteger, storageMb, storageTier) +} diff --git a/internal/services/postgres/validate/flexible_server_storage_tier.go b/internal/services/postgres/validate/flexible_server_storage_tier.go new file mode 100644 index 000000000000..689d47de8e1d --- /dev/null +++ b/internal/services/postgres/validate/flexible_server_storage_tier.go @@ -0,0 +1,90 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validate + +import ( + "github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/servers" +) + +type StorageTiers struct { + DefaultTier servers.AzureManagedDiskPerformanceTiers + ValidTiers *[]string + PossibleTiersInt *[]int +} + +// Creates a map of valid StorageTiers based on the storage_mb for the PostgreSQL Flexible Server +func InitializeFlexibleServerStorageTierDefaults() map[int]StorageTiers { + + storageTiersMappings := map[int]StorageTiers{ + 32768: {servers.AzureManagedDiskPerformanceTiersPFour, &[]string{ + string(servers.AzureManagedDiskPerformanceTiersPFour), + string(servers.AzureManagedDiskPerformanceTiersPSix), + string(servers.AzureManagedDiskPerformanceTiersPOneZero), + string(servers.AzureManagedDiskPerformanceTiersPOneFive), + string(servers.AzureManagedDiskPerformanceTiersPTwoZero), + string(servers.AzureManagedDiskPerformanceTiersPThreeZero), + string(servers.AzureManagedDiskPerformanceTiersPFourZero), + string(servers.AzureManagedDiskPerformanceTiersPFiveZero), + }, &[]int{4, 6, 10, 15, 20, 30, 40, 50}}, + 65536: {servers.AzureManagedDiskPerformanceTiersPSix, &[]string{ + string(servers.AzureManagedDiskPerformanceTiersPSix), + string(servers.AzureManagedDiskPerformanceTiersPOneZero), + string(servers.AzureManagedDiskPerformanceTiersPOneFive), + string(servers.AzureManagedDiskPerformanceTiersPTwoZero), + string(servers.AzureManagedDiskPerformanceTiersPThreeZero), + string(servers.AzureManagedDiskPerformanceTiersPFourZero), + string(servers.AzureManagedDiskPerformanceTiersPFiveZero), + }, &[]int{6, 10, 15, 20, 30, 40, 50}}, + 131072: {servers.AzureManagedDiskPerformanceTiersPOneZero, &[]string{ + string(servers.AzureManagedDiskPerformanceTiersPOneZero), + string(servers.AzureManagedDiskPerformanceTiersPOneFive), + string(servers.AzureManagedDiskPerformanceTiersPTwoZero), + string(servers.AzureManagedDiskPerformanceTiersPThreeZero), + string(servers.AzureManagedDiskPerformanceTiersPFourZero), + string(servers.AzureManagedDiskPerformanceTiersPFiveZero), + }, &[]int{10, 15, 20, 30, 40, 50}}, + 262144: {servers.AzureManagedDiskPerformanceTiersPOneFive, &[]string{ + string(servers.AzureManagedDiskPerformanceTiersPOneFive), + string(servers.AzureManagedDiskPerformanceTiersPTwoZero), + string(servers.AzureManagedDiskPerformanceTiersPThreeZero), + string(servers.AzureManagedDiskPerformanceTiersPFourZero), + string(servers.AzureManagedDiskPerformanceTiersPFiveZero), + }, &[]int{15, 20, 30, 40, 50}}, + 524288: {servers.AzureManagedDiskPerformanceTiersPTwoZero, &[]string{ + string(servers.AzureManagedDiskPerformanceTiersPTwoZero), + string(servers.AzureManagedDiskPerformanceTiersPThreeZero), + string(servers.AzureManagedDiskPerformanceTiersPFourZero), + string(servers.AzureManagedDiskPerformanceTiersPFiveZero), + }, &[]int{20, 30, 40, 50}}, + 1048576: {servers.AzureManagedDiskPerformanceTiersPThreeZero, &[]string{ + string(servers.AzureManagedDiskPerformanceTiersPThreeZero), + string(servers.AzureManagedDiskPerformanceTiersPFourZero), + string(servers.AzureManagedDiskPerformanceTiersPFiveZero), + }, &[]int{30, 40, 50}}, + 2097152: {servers.AzureManagedDiskPerformanceTiersPFourZero, &[]string{ + string(servers.AzureManagedDiskPerformanceTiersPFourZero), + string(servers.AzureManagedDiskPerformanceTiersPFiveZero), + }, &[]int{40, 50}}, + 4193280: {servers.AzureManagedDiskPerformanceTiersPFiveZero, &[]string{ + string(servers.AzureManagedDiskPerformanceTiersPFiveZero), + }, &[]int{50}}, + 4194304: {servers.AzureManagedDiskPerformanceTiersPFiveZero, &[]string{ + string(servers.AzureManagedDiskPerformanceTiersPFiveZero), + }, &[]int{50}}, + 8388608: {servers.AzureManagedDiskPerformanceTiersPSixZero, &[]string{ + string(servers.AzureManagedDiskPerformanceTiersPSixZero), + string(servers.AzureManagedDiskPerformanceTiersPSevenZero), + string(servers.AzureManagedDiskPerformanceTiersPEightZero), + }, &[]int{60, 70, 80}}, + 16777216: {servers.AzureManagedDiskPerformanceTiersPSevenZero, &[]string{ + string(servers.AzureManagedDiskPerformanceTiersPSevenZero), + string(servers.AzureManagedDiskPerformanceTiersPEightZero), + }, &[]int{70, 80}}, + 33553408: {servers.AzureManagedDiskPerformanceTiersPEightZero, &[]string{ + string(servers.AzureManagedDiskPerformanceTiersPEightZero), + }, &[]int{80}}, + } + + return storageTiersMappings +} diff --git a/website/docs/r/postgresql_flexible_server.html.markdown b/website/docs/r/postgresql_flexible_server.html.markdown index 89b5ed79ec39..47b3da489389 100644 --- a/website/docs/r/postgresql_flexible_server.html.markdown +++ b/website/docs/r/postgresql_flexible_server.html.markdown @@ -69,7 +69,8 @@ resource "azurerm_postgresql_flexible_server" "example" { administrator_password = "H@Sh1CoR3!" zone = "1" - storage_mb = 32768 + storage_mb = 32768 + storage_tier = "P30" sku_name = "GP_Standard_D4s_v3" depends_on = [azurerm_private_dns_zone_virtual_network_link.example] @@ -113,7 +114,7 @@ The following arguments are supported: * `private_dns_zone_id` - (Optional) The ID of the private DNS zone to create the PostgreSQL Flexible Server. -~> **NOTE:** There will be a breaking change from upstream service at 15th July 2021, the `private_dns_zone_id` will be required when setting a `delegated_subnet_id`. For existing flexible servers who don't want to be recreated, you need to provide the `private_dns_zone_id` to the service team to manually migrate to the specified private DNS zone. The `azurerm_private_dns_zone` should end with suffix `.postgres.database.azure.com`. +~> **Note:** There will be a breaking change from upstream service at 15th July 2021, the `private_dns_zone_id` will be required when setting a `delegated_subnet_id`. For existing flexible servers who don't want to be recreated, you need to provide the `private_dns_zone_id` to the service team to manually migrate to the specified private DNS zone. The `azurerm_private_dns_zone` should end with suffix `.postgres.database.azure.com`. * `high_availability` - (Optional) A `high_availability` block as defined below. @@ -125,7 +126,7 @@ The following arguments are supported: * `replication_role` - (Optional) The replication role for the PostgreSQL Flexible Server. Possible value is `None`. -~> **NOTE:** The `replication_role` cannot be set while creating and only can be updated to `None` for replica server. +~> **Note:** The `replication_role` cannot be set while creating and only can be updated to `None` for replica server. * `sku_name` - (Optional) The SKU Name for the PostgreSQL Flexible Server. The name of the SKU, follows the `tier` + `name` pattern (e.g. `B_Standard_B1ms`, `GP_Standard_D2s_v3`, `MO_Standard_E4s_v3`). @@ -135,6 +136,14 @@ The following arguments are supported: * `storage_mb` - (Optional) The max storage allowed for the PostgreSQL Flexible Server. Possible values are `32768`, `65536`, `131072`, `262144`, `524288`, `1048576`, `2097152`, `4193280`, `4194304`, `8388608`, `16777216` and `33553408`. +~> **Note:** If the `storage_mb` field is undefined on the initial deployment of the PostgreSQL Flexible Server resource it will default to `32768`. If the `storage_mb` field has been defined and then removed, the `storage_mb` field will retain the previously defined value. + +~> **Note:** The `storage_mb` can only be scaled up, for example, you can scale the `storage_mb` from `32768` to `65536`, but not from `65536` to `32768`. + +* `storage_tier` - (Optional) The name of storage performance tier for IOPS of the PostgreSQL Flexible Server. Possible values are `P4`, `P6`, `P10`, `P15`,`P20`, `P30`,`P40`, `P50`,`P60`, `P70` or `P80`. Default value is dependant on the `storage_mb` value. Please see the `storage_tier` defaults based on `storage_mb` table below. + +~> **Note:** The `storage_tier` can be scaled once every 12 hours, this restriction is in place to ensure stability and performance after any changes to your PostgreSQL Flexible Server's configuration. + * `tags` - (Optional) A mapping of tags which should be assigned to the PostgreSQL Flexible Server. * `version` - (Optional) The version of PostgreSQL Flexible Server to use. Possible values are `11`,`12`, `13`, `14`, `15` and `16`. Required when `create_mode` is `Default`. @@ -173,7 +182,7 @@ A `customer_managed_key` block supports the following: * `geo_backup_user_assigned_identity_id` - (Optional) The geo backup user managed identity id for a Customer Managed Key. Should be added with `identity_ids`. It can't cross region and need identity in same region as geo backup. -~> **NOTE:** `primary_user_assigned_identity_id` or `geo_backup_user_assigned_identity_id` is required when `type` is set to `UserAssigned`. +~> **Note:** `primary_user_assigned_identity_id` or `geo_backup_user_assigned_identity_id` is required when `type` is set to `UserAssigned`. --- @@ -205,6 +214,29 @@ A `high_availability` block supports the following: -> **Note:** The Availability Zones available depend on the Azure Region that the PostgreSQL Flexible Server is being deployed into - see [the Azure Availability Zones documentation](https://azure.microsoft.com/global-infrastructure/geographies/#geographies) for more information on which Availability Zones are available in each Azure Region. +--- + +## `storage_tier` defaults based on `storage_mb` + +| `storage_mb` | GiB | TiB | Default | Supported `storage_tier`'s | Provisioned `IOPS` | +|:------------:|:-----:|:---:|:-------:|:------------------------------------:|:-------------------:| +| 32768 | 32 | - | P4 | P4, P6, P10, P15, P20, P30, P40, P50 | 120 | +| 65536 | 64 | - | P6 | P6, P10, P15, P20, P30, P40, P50 | 240 | +| 131072 | 128 | - | P10 | P10, P15, P20, P30, P40, P50 | 500 | +| 262144 | 256 | - | P15 | P15, P20, P30, P40, P50 | 1,100 | +| 524288 | 512 | - | P20 | P20, P30, P40, P50 | 2,300 | +| 1048576 | 1024 | 1 | P30 | P30, P40, P50 | 5,000 | +| 2097152 | 2048 | 2 | P40 | P40, P50 | 7,500 | +| 4193280 | 4095 | 4 | P50 | P50 | 7,500 | +| 4194304 | 4096 | 4 | P50 | P50 | 7,500 | +| 8388608 | 8192 | 8 | P60 | P60, P70 | 16,000 | +| 16777216 | 16384 | 16 | P70 | P70, P80 | 18,000 | +| 33553408 | 32767 | 32 | P80 | P80 | 20,000 | + +-> **Note:** Host Caching (ReadOnly and Read/Write) is supported on disk sizes less than 4194304 MiB. This means any disk that is provisioned up to 4193280 MiB can take advantage of Host Caching. Host caching is not supported for disk sizes larger than 4193280 MiB. For example, a P50 premium disk provisioned at 4193280 GiB can take advantage of Host caching while a P50 disk provisioned at 4194304 MiB cannot. Moving from a smaller disk size to a larger disk size, greater than 4193280 MiB, will cause the disk to lose the disk caching ability. + +--- + ## Attributes Reference In addition to the Arguments listed above - the following Attributes are exported: