Search code examples
azureterraformterraform-provider-azure

"context deadline exceeded" after running Terraform apply but Azure resource still created. Terraform Import wants to recreate resource


I was creating an azurerm_postgresql_flexible_server replica resource but the apply command timed out. The resource still created however and after trying to import it into state Terraform plan is trying to destroy and recreate it. I haven't encountered this before so is there an elegant way to handle this type of situation? The main problem I think is the "create_mode" parameter...but this should be Replica because I'm creating a replica? I'm not sure how to work around that requirement

Here is my current config:

import {
  to = azurerm_postgresql_flexible_server.main_replica[0]
  id = "/subscriptions/something/.../Microsoft.DBforPostgreSQL/flexibleServers/some-resource-name"
}


resource "azurerm_postgresql_flexible_server" "main_replica" {
  count = var.environment == "p" ? 1 : 0


  name                   = "some-resource-name"
  resource_group_name    = var.resource_group_name
  location               = "centralus"
  version                = "12"
  administrator_login    = "postgres"
  administrator_password = "xxxxxx"
  zone                   = "2"
  create_mode            = "Replica"
  source_server_id       = azurerm_postgresql_flexible_server.main.id
  storage_mb             = var.postgresql_storage_mb
  storage_tier           = var.postgresql_storage_tier
  sku_name               = var.postgresql_sku_name
  auto_grow_enabled      = var.environment == "p" ? true : false


  tags = merge(local.tags, { location = "centralus" })


  lifecycle {
    prevent_destroy = true
  }
}

-/+ destroy and then create replacement

Terraform planned the following actions, but then encountered a problem:

  # azurerm_postgresql_flexible_server.main_replica[0] must be replaced
  # (imported from "/subscriptions/.../Microsoft.DBforPostgreSQL/flexibleServers/some-resource-name")
  # Warning: this will destroy the imported resource
-/+ resource "azurerm_postgresql_flexible_server" "main_replica" {
        administrator_login           = "postgres"
      + administrator_password        = (sensitive value)
        auto_grow_enabled             = true
      ~ backup_retention_days         = 7 -> (known after apply)
      + create_mode                   = "Replica" # forces replacement
        delegated_subnet_id           = null
      ~ fqdn                          = "xxxxx.postgres.database.azure.com" -> (known after apply)
        geo_redundant_backup_enabled  = false
      ~ id                            = "/subscriptions/..../Microsoft.DBforPostgreSQL/flexibleServers/some-resource-name" -> (known after apply)
        location                      = "centralus"
        name                          = "some-resource-name"
      + private_dns_zone_id           = (known after apply)
      ~ public_network_access_enabled = true -> (known after apply)
        replication_role              = null
        resource_group_name           = "..."
        sku_name                      = "GP_Standard_D32ds_v4"
      + source_server_id              = "/subscriptions/.../" # forces replacement
        storage_mb                    = 2097152
        storage_tier                  = "P40"
      ~ tags                          = {
            "..." = "..."
        }
        version                       = "12"
        zone                          = "2"

      ~ authentication {
          + administrator_login               = (known after apply)
          + administrator_password            = (known after apply)
          + auto_grow_enabled                 = (known after apply)
          + backup_retention_days             = (known after apply)
          + create_mode                       = (known after apply)
          + delegated_subnet_id               = (known after apply)
          + fqdn                              = (known after apply)
          + geo_redundant_backup_enabled      = (known after apply)
          + id                                = (known after apply)
          + location                          = (known after apply)
          + name                              = (known after apply)
          + point_in_time_restore_time_in_utc = (known after apply)
          + private_dns_zone_id               = (known after apply)
          + public_network_access_enabled     = (known after apply)
          + replication_role                  = (known after apply)
          + resource_group_name               = (known after apply)
          + sku_name                          = (known after apply)
          + source_server_id                  = (known after apply)
          + storage_mb                        = (known after apply)
          + storage_tier                      = (known after apply)
          + tags                              = (known after apply)
          + version                           = (known after apply)
          + zone                              = (known after apply)
        } -> (known after apply)
    }

Solution

  • The resource still created however and after trying to import it into state Terraform plan is trying to destroy and recreate it. I haven't encountered this before so is there an elegant way to handle this type of situation?

    To handle this type of scenario, there is a block called ignore_changes available in terraform which is used to ignore the changes for the given specific attributes.

    In general, the functionality of the argument create_mode is:

    The creation mode which can be used to restore or replicate existing servers. Changing these forces a new PostgreSQL Flexible Server to be created.

    I have used the ignore_changes block by passing create_mode and source_server_id as shown below. It means the changes will not be applied to these attributes and work as usual.

    lifecycle {
        prevent_destroy = true
        ignore_changes = [
          create_mode,
          source_server_id
        ]
      }
    

    Complete code:

    resource "azurerm_postgresql_flexible_server" "main_replica" {
    
      name                   = "replicaservers"
      resource_group_name    = data.azurerm_resource_group.example.name
      location               = "centralus"
      version                = "12"
      administrator_login    = "user"
      administrator_password = "xxx"
      zone                   = "1"
      create_mode            = "Replica"
      source_server_id       = data.azurerm_postgresql_flexible_server.example.id
      storage_mb             = 32768
      storage_tier           = "P30"
      sku_name               = "GP_Standard_D4s_v3"
    
      lifecycle {
        prevent_destroy = true
        ignore_changes = [
          create_mode,
          source_server_id
        ]
      }
    }
    

    enter image description here

    enter image description here

    Refer Github for the relevant issue.