hashicorp / terraform-provider-azurerm

Terraform provider for Azure Resource Manager
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
Mozilla Public License 2.0
4.58k stars 4.62k forks source link

azurerm_postgresql_flexible_server Fails when Updating VM SKU and HA at the same time between burstable and general purpose #27612

Open AndrewCi opened 5 days ago

AndrewCi commented 5 days ago

Is there an existing issue for this?

Community Note

Terraform Version

1.9.6

AzureRM Provider Version

4.4.0

Affected Resource(s)/Data Source(s)

azurerm_postgresql_flexible_server

Terraform Configuration Files

Terraform Config File First Apply

resource "azurerm_postgresql_flexible_server" "psql_flexible" {
  name                          = "psql-backup-test-123-flexible-server"
  resource_group_name           = azurerm_resource_group.psql_test_resource_group.name
  location                      = azurerm_resource_group.psql_test_resource_group.location
  delegated_subnet_id           = azurerm_subnet.psql_subnet.id
  private_dns_zone_id           = azurerm_private_dns_zone.psql_private_dns.id
  public_network_access_enabled = false   # Disable public access
  version                       = "16"   # Latest stable version
  zone                          = "2"

  administrator_login           = var.psql_admin_username
  administrator_password        = var.psql_admin_password

  sku_name                      = "B_Standard_B1ms" # Smallest SKU
  storage_mb                    = 32768             # 32 GB for lowest cost
  auto_grow_enabled             = true              # Enable auto-grow for storage

  backup_retention_days         = 7                 # Min backup retention for testing
  geo_redundant_backup_enabled  = false             # Disable for cost

    depends_on = [
    azurerm_virtual_network.vnet,  # Ensure VNet is created
    azurerm_subnet.psql_subnet     # Ensure Subnet is created
  ]

  tags = {
    environment = "development"
  }
}

Terraform Config File Second Apply that causes the error

resource "azurerm_postgresql_flexible_server" "psql_flexible" {
  name                          = "psql-backup-test-123-flexible-server"
  resource_group_name           = azurerm_resource_group.psql_test_resource_group.name
  location                      = azurerm_resource_group.psql_test_resource_group.location
  delegated_subnet_id           = azurerm_subnet.psql_subnet.id
  private_dns_zone_id           = azurerm_private_dns_zone.psql_private_dns.id
  public_network_access_enabled = false   # Disable public access
  version                       = "16"   # Latest stable version
  zone                          = "2"

  administrator_login           = var.psql_admin_username
  administrator_password        = var.psql_admin_password

  sku_name                      = "GP_Standard_D2ds_v4" # Smallest SKU
  storage_mb                    = 32768             # 32 GB for lowest cost
  storage_tier = "P4"
  auto_grow_enabled             = true              # Enable auto-grow for storage

  backup_retention_days         = 7                 # Min backup retention for testing
  geo_redundant_backup_enabled  = false             # Disable for cost

  high_availability {
    mode            = "ZoneRedundant"    # Enable zone-redundant high availability
    standby_availability_zone = 1
  }

  depends_on = [
    azurerm_virtual_network.vnet,  # Ensure VNet is created
    azurerm_subnet.psql_subnet     # Ensure Subnet is created
  ]

  tags = {
    environment = "development"
  }
}

Debug Output/Panic Output

data.http.my_public_ip: Reading...
data.http.my_public_ip: Read complete after 1s [id=https://api.ipify.org]
azurerm_resource_group.psql_test_resource_group: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123]
azurerm_public_ip.vm_public_ip: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.Network/publicIPAddresses/vm-public-ip]
azurerm_virtual_network.vnet: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.Network/virtualNetworks/psql-test-vnet-123]
azurerm_subnet.vm_subnet: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.Network/virtualNetworks/psql-test-vnet-123/subnets/vm-subnet-123]
azurerm_private_dns_zone.psql_private_dns: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.Network/privateDnsZones/acitera-test.postgres.database.azure.com]       
azurerm_network_security_group.vm_nsg: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.Network/networkSecurityGroups/vm-nsg]
azurerm_subnet.psql_subnet: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.Network/virtualNetworks/psql-test-vnet-123/subnets/psql-server-subnet-123]
azurerm_network_interface.vm_nic: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.Network/networkInterfaces/vm-nic]
azurerm_subnet_network_security_group_association.vm_subnet_nsg: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.Network/virtualNetworks/psql-test-vnet-123/subnets/vm-subnet-123]
azurerm_windows_virtual_machine.vm: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.Compute/virtualMachines/win-test-vm]
azurerm_private_dns_zone_virtual_network_link.psql_dns_vnet_link: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.Network/privateDnsZones/acitera-test.postgres.database.azure.com/virtualNetworkLinks/psql-vnet-link]
azurerm_postgresql_flexible_server.psql_flexible: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.DBforPostgreSQL/flexibleServers/psql-backup-test-123-flexible-server]
azurerm_postgresql_flexible_server_firewall_rule.allow_current_ip: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.DBforPostgreSQL/flexibleServers/psql-backup-test-123-flexible-server/firewallRules/allow_current_ip_test_backup]
azurerm_postgresql_flexible_server_database.additional_db: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.DBforPostgreSQL/flexibleServers/psql-backup-test-123-flexible-server/databases/test_db_backup]
azurerm_postgresql_flexible_server_configuration.custom_param: Refreshing state... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.DBforPostgreSQL/flexibleServers/psql-backup-test-123-flexible-server/configurations/logfiles.retention_days]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # azurerm_postgresql_flexible_server.psql_flexible will be updated in-place
  ~ resource "azurerm_postgresql_flexible_server" "psql_flexible" {
        id                            = "/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.DBforPostgreSQL/flexibleServers/psql-backup-test-123-flexible-server"
        name                          = "psql-backup-test-123-flexible-server"
      ~ sku_name                      = "B_Standard_B1ms" -> "GP_Standard_D2ds_v4"
        tags                          = {
            "environment" = "development"
        }
        # (16 unchanged attributes hidden)

      + high_availability {
          + mode                      = "ZoneRedundant"
          + standby_availability_zone = "1"
        }

        # (1 unchanged block hidden)
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

azurerm_postgresql_flexible_server.psql_flexible: Modifying... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-2c6e10db09e9/resourceGroups/psql-test-tf-123/providers/Microsoft.DBforPostgreSQL/flexibleServers/psql-backup-test-123-flexible-server]
azurerm_postgresql_flexible_server.psql_flexible: Still modifying... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-...s/psql-backup-test-123-flexible-server, 10s elapsed]
azurerm_postgresql_flexible_server.psql_flexible: Still modifying... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-...s/psql-backup-test-123-flexible-server, 20s elapsed]
azurerm_postgresql_flexible_server.psql_flexible: Still modifying... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-...s/psql-backup-test-123-flexible-server, 30s elapsed]
azurerm_postgresql_flexible_server.psql_flexible: Still modifying... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-...s/psql-backup-test-123-flexible-server, 40s elapsed]
azurerm_postgresql_flexible_server.psql_flexible: Still modifying... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-...s/psql-backup-test-123-flexible-server, 50s elapsed]
azurerm_postgresql_flexible_server.psql_flexible: Still modifying... [id=/subscriptions/28215b30-7ba5-4ca8-bc7b-...s/psql-backup-test-123-flexible-server, 1m0s elapsed]
╷
│ Error: updating Flexible Server (Subscription: "28215b30-7ba5-4ca8-bc7b-2c6e10db09e9"
│ Resource Group Name: "psql-test-tf-123"
│ Flexible Server Name: "psql-backup-test-123-flexible-server"): polling after Update: polling failed: the Azure API returned the following error:
│
│ Status: "Failed"
│ Code: "Failed"
│ Message: "HA is not supported for Burstable SKUs."
│ Activity Id: ""
│
│ ---
│
│ API Response:
│
│ ----[start]----
│ {"name":"990e7189-db51-4f44-ba91-3695bd258dbe","status":"Failed","startTime":"2024-10-10T16:01:08.257Z","error":{"code":"","message":"HA is not supported for Burstable SKUs."}}
│ -----[end]-----
│
│
│   with azurerm_postgresql_flexible_server.psql_flexible,
│   on psqlflexiserver.tf line 1, in resource "azurerm_postgresql_flexible_server" "psql_flexible":
│    1: resource "azurerm_postgresql_flexible_server" "psql_flexible" {

Expected Behaviour

Expected behavior would be that Terraform would know to update the VM SKU of PSQL Flexi Server first and then update the HA configuration

Actual Behaviour

Terraform attempted to update the HA first which failed because the prior SKU was burstable

Steps to Reproduce

TF apply when going from B_Standard_B1ms without HA to GP_Standard_D2ds_v4 with HA

Important Factoids

No response

References

No response

neil-yechenwei commented 4 days ago

Thanks for raising this issue. Seems I updated it successfully. Below is my reproduce steps. Maybe there is no enough permission on the region/the service principal you are using. Please try below tf config to see if the issue still exists.

First apply:

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "test" {
  name     = "acctestRG-postgresql-test03"
  location = "eastus"
}

resource "azurerm_virtual_network" "test" {
  name                = "acctest-vn-test03"
  location            = azurerm_resource_group.test.location
  resource_group_name = azurerm_resource_group.test.name
  address_space       = ["10.0.0.0/16"]
}

resource "azurerm_subnet" "test" {
  name                 = "acctest-sn-test03"
  resource_group_name  = azurerm_resource_group.test.name
  virtual_network_name = azurerm_virtual_network.test.name
  address_prefixes     = ["10.0.2.0/24"]
  service_endpoints    = ["Microsoft.Storage"]
  delegation {
    name = "fs"
    service_delegation {
      name = "Microsoft.DBforPostgreSQL/flexibleServers"
      actions = [
        "Microsoft.Network/virtualNetworks/subnets/join/action",
      ]
    }
  }
}

resource "azurerm_private_dns_zone" "test" {
  name                = "acctest03.postgres.database.azure.com"
  resource_group_name = azurerm_resource_group.test.name
}

resource "azurerm_private_dns_zone_virtual_network_link" "test" {
  name                  = "acctestVnetZonetest03.com"
  private_dns_zone_name = azurerm_private_dns_zone.test.name
  virtual_network_id    = azurerm_virtual_network.test.id
  resource_group_name   = azurerm_resource_group.test.name

  depends_on = [azurerm_subnet.test]
}

resource "azurerm_postgresql_flexible_server" "test" {
  name                          = "psql-backup-test03-flexible-server"
  resource_group_name           = azurerm_resource_group.test.name
  location                      = azurerm_resource_group.test.location
  delegated_subnet_id           = azurerm_subnet.test.id
  private_dns_zone_id           = azurerm_private_dns_zone.test.id
  public_network_access_enabled = false
  version                       = "16"
  zone                          = "2"

  administrator_login    = "adminTerraform"
  administrator_password = "QAZwsx123"

  sku_name          = "B_Standard_B1ms"
  storage_mb        = 32768
  auto_grow_enabled = true

  backup_retention_days        = 7
  geo_redundant_backup_enabled = false

  depends_on = [azurerm_private_dns_zone_virtual_network_link.test]
}

Second apply:

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "test" {
  name     = "acctestRG-postgresql-test03"
  location = "eastus"
}

resource "azurerm_virtual_network" "test" {
  name                = "acctest-vn-test03"
  location            = azurerm_resource_group.test.location
  resource_group_name = azurerm_resource_group.test.name
  address_space       = ["10.0.0.0/16"]
}

resource "azurerm_subnet" "test" {
  name                 = "acctest-sn-test03"
  resource_group_name  = azurerm_resource_group.test.name
  virtual_network_name = azurerm_virtual_network.test.name
  address_prefixes     = ["10.0.2.0/24"]
  service_endpoints    = ["Microsoft.Storage"]
  delegation {
    name = "fs"
    service_delegation {
      name = "Microsoft.DBforPostgreSQL/flexibleServers"
      actions = [
        "Microsoft.Network/virtualNetworks/subnets/join/action",
      ]
    }
  }
}

resource "azurerm_private_dns_zone" "test" {
  name                = "acctest03.postgres.database.azure.com"
  resource_group_name = azurerm_resource_group.test.name
}

resource "azurerm_private_dns_zone_virtual_network_link" "test" {
  name                  = "acctestVnetZonetest03.com"
  private_dns_zone_name = azurerm_private_dns_zone.test.name
  virtual_network_id    = azurerm_virtual_network.test.id
  resource_group_name   = azurerm_resource_group.test.name

  depends_on = [azurerm_subnet.test]
}

resource "azurerm_postgresql_flexible_server" "test" {
  name                          = "psql-backup-test03-flexible-server"
  resource_group_name           = azurerm_resource_group.test.name
  location                      = azurerm_resource_group.test.location
  delegated_subnet_id           = azurerm_subnet.test.id
  private_dns_zone_id           = azurerm_private_dns_zone.test.id
  public_network_access_enabled = false
  version                       = "16"
  zone                          = "2"

  administrator_login    = "adminTerraform"
  administrator_password = "QAZwsx123"

  sku_name          = "GP_Standard_D2ds_v4"
  storage_mb        = 32768
  auto_grow_enabled = true

  high_availability {
    mode                      = "ZoneRedundant"
    standby_availability_zone = 1
  }

  backup_retention_days        = 7
  geo_redundant_backup_enabled = false

  depends_on = [azurerm_private_dns_zone_virtual_network_link.test]
}

image

AndrewCi commented 4 days ago

Thank you for attempting to reproduce. Can it be related to storage tier? That's the only difference I could see with your provided TF files. Would you be able to retry with storage tier defined?