terraform-provider-azurerm icon indicating copy to clipboard operation
terraform-provider-azurerm copied to clipboard

changing the `azurerm_postgresql_flexible_server` version from 11 to any other version forces a recreate

Open Xangliev opened this issue 1 year ago • 17 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Community Note

  • Please vote on this issue by adding a :thumbsup: reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment and review the contribution guide to help.

Terraform Version

1.5.7

AzureRM Provider Version

3.94.0 and lower versions seem to be impacted

Affected Resource(s)/Data Source(s)

azurerm_postgresql_flexible_server

Terraform Configuration Files

resource "azurerm_postgresql_flexible_server" "server2" {
  name                = var.name
  location            = var.location
  resource_group_name = var.resource_group_name

  administrator_login    = var.administrator_login
  administrator_password = var.administrator_password

  sku_name   = var.sku_name
  storage_mb = var.storage_mb
  zone       = var.zone
  version    = "11" // eg. changing to "12" or "15" forces a replacement
}

Debug Output/Panic Output

Terraform will perform the following actions:
  # azurerm_postgresql_flexible_server.server must be replaced
-/+ resource "azurerm_postgresql_flexible_server" "server" {
      ~ backup_retention_days         = 7 -> (known after apply)
      ~ fqdn                          = <redacted> -> (known after apply)
      ~ id                            = <redacted> -> (known after apply)
        name                          = "psql-test-ra3h3"
      + private_dns_zone_id           = (known after apply)
      ~ public_network_access_enabled = true -> (known after apply)
      ~ version                       = "11" -> "15" # forces replacement
        # (8 unchanged attributes hidden)
      - authentication {
          - active_directory_auth_enabled = false -> null
          - password_auth_enabled         = true -> null
        }
    }

Expected Behaviour

Terraform should perform the upgrade on the existing resource without forcing a replacement of the server resource.

Actual Behaviour

Terraform forces a replacement of the server resource and all dependant resources.

Steps to Reproduce

  1. create the postgresql flexible server resource definition
  2. run terraform apply to create the postgresql flexible server resource
  3. change the server version from 11 to 15 within the resource definition
  4. rerun terraform apply

Important Factoids

No response

References

No response

Xangliev avatar Mar 08 '24 09:03 Xangliev

UPDATE: apparently setting the create_mode variable to "Update" is required in order for Terraform not to replace the server resource.

I would honestly expect that changing the value of the server_version variable would not replace existing resources by default, as performing a server upgrade via the Azure Portal doesn't trigger a replacement of any kind either.

Xangliev avatar Mar 08 '24 13:03 Xangliev

Thanks for raising this issue. Service team confirmed the version of postgresql flexible server should be in-place updated while upgrading "version" and create_mode is "Update".

Below is example:

resource "azurerm_postgresql_flexible_server" "test" {
  name                = "acctest-fs-test183"
  resource_group_name = azurerm_resource_group.test.name
  location            = azurerm_resource_group.test.location

  administrator_login    = "_admin_Terraform_123123"
  administrator_password = "QAZabx123"

  sku_name = "GP_Standard_D2s_v3"
  zone     = "2"
  version  = "12"

  create_mode = "Update"
}

neil-yechenwei avatar Mar 11 '24 02:03 neil-yechenwei

@neil-yechenwei: Is there a reason the provider doesn't set the create_mode to "Update" automatically if version changes? Unless I'm mistaken, I don't think create_mode can always be set to "Update" especially on first creation. This seems to be very error-prone and a good way to lose data.

tanadeau avatar Apr 13 '24 00:04 tanadeau

Am i understanding correctly that there is currently no way to have a terraform config that will depending on the existence of the server automatically create / upgrade it? (because i need to have create_mode = "Default" for creating the server and create_mode = "Update" for upgrading postgres)

wslaghekke avatar May 28 '24 09:05 wslaghekke

@neil-yechenwei as @tanadeau has mentioned above - the provider should be setting create_mode = "Update" automatically as required, that the API behaves in a weird manner is Terraform's problem, not something that should be pushed onto users.

FWIW this is why we shouldn't necessarily expose CreateMode (and similar) fields in resources, but instead infer it from other fields (e.g. hypothetically if there's a field restore_from_server_id = ".." and that field is populated, we could determine that create_mode = "Restore" rather than create_mode = "Default|Update"). It's a bit late for the places we've already exposed this field, but as mentioned above, this is an API/implementation detail that Terraform should be handling - users just want to update the API version, so we should be sending whatever the API needs to achieve that?

As such, @neil-yechenwei would you be able to send a PR to automatically set the value for CreateMode when updating the server in this instance?

Thanks!

tombuildsstuff avatar May 28 '24 09:05 tombuildsstuff

Any updates here?

lieberlois avatar May 29 '24 11:05 lieberlois

Please fix this, this is ridiculous. The terraform resource documentation even says this:

* create_mode cannot be changed once it's set since it's a parameter at creation.

Followed by:

* While creating the resource, create_mode cannot be set to Update.

And the property itself says:

Changing this forces a new PostgreSQL Flexible Server to be created.

So we have to set it to Create, then we can't even change the value to Update even if we wanted to do an in place upgrade of the version... This is horrible. Users want to be able to upgrade their instance in place, just like they can do through the portal.

(I'm trying this now though and we can change the value of create_mode without it resulting in a re-create of the instance?! In that case the documentation is wrong. But having to do this is still bad. )

sleenen avatar Jul 29 '24 18:07 sleenen

@sleenen I figured it out like a month ago, sorry for not posting the answer immediately.

The (very stupid) idea of this implementation seems to be that you only set the create_mode to Update along with other changes. In our scenario, we tried to first set the create_mode, then tf apply, then update the PostgreSQL version. Only setting the create_mode to update with no other changes however recreates the database. After hours of trying stuff out I just tried to do both at once, and it worked 😆 not sure if this explanation was clear, I don't know how to describe it - very confusing ^^

lieberlois avatar Jul 30 '24 07:07 lieberlois

Thanks @lieberlois , I've tried the same. First time I got a weird internal server error with no more explanation. Second try I got a timeout on the polling and the instance wasn't updated to new version.

sleenen avatar Jul 30 '24 07:07 sleenen

@sleenen Thats odd, we managed to upgrade all of our instances from 11 to 16 this way 🤔 oh when did you try this? There was an issue on Microsoft side, this was fixed like 1-2 months ago

lieberlois avatar Jul 30 '24 07:07 lieberlois

Tried it last night and this morning again.

sleenen avatar Jul 30 '24 07:07 sleenen

@sleenen We have our next release next week on saturday, I'll notify you if everything worked 👍

lieberlois avatar Aug 15 '24 09:08 lieberlois

@tombuildsstuff @neil-yechenwei any update on this?

sleenen avatar Aug 15 '24 15:08 sleenen

Please fix this, this is ridiculous. The terraform resource documentation even says this:

* create_mode cannot be changed once it's set since it's a parameter at creation.

Followed by:

* While creating the resource, create_mode cannot be set to Update.

And the property itself says:

Changing this forces a new PostgreSQL Flexible Server to be created.

So we have to set it to Create, then we can't even change the value to Update even if we wanted to do an in place upgrade of the version... This is horrible. Users want to be able to upgrade their instance in place, just like they can do through the portal.

(I'm trying this now though and we can change the value of create_mode without it resulting in a re-create of the instance?! In that case the documentation is wrong. But having to do this is still bad. )

I was about to create an issue but I found this one. The documentation is highly misleading, confusing and contradicts itself. Relying on the knowledge of existence to change the Terraform configuration makes it dependent on external factors and no longer reproducible. Looking forward to the change that will set "Update" automatically when the version is updated. I would also have expected that create_mode could be set to Update from the beginning.

simaotwx avatar Aug 21 '24 08:08 simaotwx

This is also an issue when upgrading a server with create_mode=PointInTimeRestore which is common in a staging environment.

Even if I set create_mode=Update Terraform says it will recreate the database server.

$ terraform --version
Terraform v1.9.5
on linux_amd64
+ provider registry.terraform.io/hashicorp/azurerm v3.116.0

$ terraform apply ...
[...]
-/+ resource "azurerm_postgresql_flexible_server" "psql" {
      ~ create_mode                       = "PointInTimeRestore" -> "Update"
      ~ fqdn                              = "xxxxxx.postgres.database.azure.com" -> (known after apply)
      ~ id                                = "xxxxxx" -> (known after apply)
        name                              = "xxxxxx"
      ~ point_in_time_restore_time_in_utc = "2024-08-27T07:38:13Z" -> (known after apply)
      - source_server_id                  = "xxxxxx" -> null
      ~ storage_tier                      = "P20" -> (known after apply)
      ~ version                           = "13" -> "15" # forces replacement
        # (14 unchanged attributes hidden)

Seems that we have to rely on click-ops and update the server manually in Azure and just bump the version in tfvars.

Please fix this.

Addition: I've now tried creating a brand new server with v13 and then trying to upgrade it by only changing the version and setting create_mode="Update" and I still end up with terraform wanting to destroy my existing server.

# module.psql.azurerm_postgresql_flexible_server.psql must be replaced
-/+ resource "azurerm_postgresql_flexible_server" "psql" {
      ~ create_mode                   = "Default" -> "Update"
      ~ fqdn                          = "xxx.postgres.database.azure.com" -> (known after apply)
      ~ id                            = "xxx" -> (known after apply)
        name                          = "psql-jfp-axis-se-dev"
      ~ storage_tier                  = "P20" -> (known after apply)
      ~ version                       = "13" -> "15" # forces replacement
        # (14 unchanged attributes hidden)

gangefors avatar Aug 27 '24 12:08 gangefors

This is highly unintuitive and I simply do not understand. I am using AzureRM 4.0.1, I started spinning two postgres flexible servers. All is fine, then i wanted to upgrade PG version from 15 -> 16.

I set the create_mode = "Update" and it does this fine without replacing the entire DB and I was now able to update the Prod server on a General tier but not the dev instance on a burst tier. Now I deleted my dev tier, tore it down to set it up again on PG version 16, but now I can't set the create_mode = "Update" on the dev tier without having to destroy it, at the same time i can't change create_mode away from "Update" because that will tear down my prod environment and i can't spin my dev tier up in "Update" mode 😵‍💫

Please fix this and do it the right way, this is crucial infastructure.

DennisJensen95 avatar Aug 29 '24 11:08 DennisJensen95

image

terraform-provider-azurerm/internal/services/postgres/postgresql_flexible_server_resource.go seems to be the problematic code part 🤔 if no create mode is specified, or not explicitly set to "Update" it will force a recreation. What do the Hashicorp guys say to that?

lieberlois avatar Aug 29 '24 15:08 lieberlois

@sleenen I was also facing the same issue then found out this link please check if Timescaledb, pgaudit, dblink, orafce, pg_partman, postgres_fdw all these extensions are not present before upgrading via terraform

divyn10 avatar Sep 24 '24 11:09 divyn10

hi any update on this issue ?

mohamedltaief1994 avatar Jan 09 '25 10:01 mohamedltaief1994

Hi, when will the fix be merged? We need it to have a proper in-place upgrade using Terraform.

adlerd1 avatar Apr 02 '25 14:04 adlerd1

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

github-actions[bot] avatar May 23 '25 02:05 github-actions[bot]