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

postgresql_flexible_server_virtual_endpoint_resource incorrectly sets Replica Server ID #27453

Closed
1 task done
bruceharrison1984 opened this issue Sep 20, 2024 · 4 comments · Fixed by #27509
Closed
1 task done

Comments

@bruceharrison1984
Copy link
Contributor

bruceharrison1984 commented Sep 20, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave comments along the lines of "+1", "me too" or "any updates", 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.9.0

AzureRM Provider Version

4.3.0

Affected Resource(s)/Data Source(s)

postgresql_flexible_server_virtual_endpoint_resource

Terraform Configuration Files

resource "random_pet" "name_prefix" {
  length = 1
}

###### EAST RG ######

resource "azurerm_resource_group" "east" {
  name     = "${random_pet.name_prefix.id}-east"
  location = "eastus"
}

resource "azurerm_virtual_network" "east" {
  name                = "${random_pet.name_prefix.id}-east-vn"
  location            = azurerm_resource_group.east.location
  resource_group_name = azurerm_resource_group.east.name
  address_space       = ["10.0.0.0/16"]
}

resource "azurerm_network_security_group" "east" {
  name                = "${random_pet.name_prefix.id}-east-nsg"
  location            = azurerm_resource_group.east.location
  resource_group_name = azurerm_resource_group.east.name

  security_rule {
    name                       = "allow_all"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "*"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

resource "azurerm_subnet" "east" {
  name                 = "${random_pet.name_prefix.id}-east-sn"
  resource_group_name  = azurerm_resource_group.east.name
  virtual_network_name = azurerm_virtual_network.east.name
  address_prefixes     = ["10.0.1.0/24"]
  service_endpoints    = ["Microsoft.Storage"]

  delegation {
    name = "fs"
    service_delegation {
      name = "Microsoft.DBforPostgreSQL/flexibleServers"
      actions = [
        "Microsoft.Network/virtualNetworks/subnets/join/action",
      ]
    }
  }
}

resource "azurerm_subnet_network_security_group_association" "east" {
  subnet_id                 = azurerm_subnet.east.id
  network_security_group_id = azurerm_network_security_group.east.id
}

resource "azurerm_private_dns_zone" "east" {
  name                = "${random_pet.name_prefix.id}-pdz.postgres.database.azure.com"
  resource_group_name = azurerm_resource_group.east.name

  depends_on = [azurerm_subnet_network_security_group_association.east]
}

resource "azurerm_virtual_network_peering" "east" {
  name                         = "east-to-west"
  resource_group_name          = azurerm_resource_group.east.name
  virtual_network_name         = azurerm_virtual_network.east.name
  remote_virtual_network_id    = azurerm_virtual_network.west.id
  allow_virtual_network_access = true
  allow_forwarded_traffic      = true
}

resource "azurerm_private_dns_zone_virtual_network_link" "east" {
  name                  = "${random_pet.name_prefix.id}-east-pdzvnetlink.com"
  private_dns_zone_name = azurerm_private_dns_zone.east.name
  virtual_network_id    = azurerm_virtual_network.east.id
  resource_group_name   = azurerm_resource_group.east.name

  depends_on = [azurerm_virtual_network_peering.east]
}

resource "random_password" "pass" {
  length = 20
}

resource "azurerm_postgresql_flexible_server" "east" {
  name                          = "${random_pet.name_prefix.id}-east-pg"
  resource_group_name           = azurerm_resource_group.east.name
  location                      = azurerm_resource_group.east.location
  version                       = "13"
  public_network_access_enabled = false
  administrator_login           = "adminTerraform"
  administrator_password        = random_password.pass.result
  sku_name                      = "GP_Standard_D2s_v3"

  delegated_subnet_id = azurerm_subnet.east.id
  private_dns_zone_id = azurerm_private_dns_zone.east.id

  depends_on = [azurerm_private_dns_zone_virtual_network_link.east]

  lifecycle {
    ignore_changes = [zone]
  }

  timeouts {
    create = "120m"
  }
}

resource "azurerm_postgresql_flexible_server_virtual_endpoint" "example" {
  name              = "${random_pet.name_prefix.id}-endpoint"
  source_server_id  = azurerm_postgresql_flexible_server.east.id
  replica_server_id = azurerm_postgresql_flexible_server.west.id
  type              = "ReadWrite"
}

###### WEST RG ######

resource "azurerm_resource_group" "west" {
  name     = "${random_pet.name_prefix.id}-west"
  location = "westus"
}

resource "azurerm_virtual_network" "west" {
  name                = "${random_pet.name_prefix.id}-west-vn"
  location            = azurerm_resource_group.west.location
  resource_group_name = azurerm_resource_group.west.name
  address_space       = ["11.0.0.0/16"]
}

resource "azurerm_network_security_group" "west" {
  name                = "${random_pet.name_prefix.id}-west-nsg"
  location            = azurerm_resource_group.west.location
  resource_group_name = azurerm_resource_group.west.name

  security_rule {
    name                       = "allow_all"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "*"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

resource "azurerm_subnet" "west" {
  name                 = "${random_pet.name_prefix.id}-west-sn"
  resource_group_name  = azurerm_resource_group.west.name
  virtual_network_name = azurerm_virtual_network.west.name
  address_prefixes     = ["11.0.1.0/24"]
  service_endpoints    = ["Microsoft.Storage"]

  delegation {
    name = "fs"
    service_delegation {
      name = "Microsoft.DBforPostgreSQL/flexibleServers"
      actions = [
        "Microsoft.Network/virtualNetworks/subnets/join/action",
      ]
    }
  }
}

resource "azurerm_subnet_network_security_group_association" "west" {
  subnet_id                 = azurerm_subnet.west.id
  network_security_group_id = azurerm_network_security_group.west.id
}

resource "azurerm_private_dns_zone" "west" {
  name                = "${random_pet.name_prefix.id}-pdz.postgres.database.azure.com"
  resource_group_name = azurerm_resource_group.west.name

  depends_on = [azurerm_subnet_network_security_group_association.west]
}

resource "azurerm_virtual_network_peering" "west" {
  name                         = "west-to-east"
  resource_group_name          = azurerm_resource_group.west.name
  virtual_network_name         = azurerm_virtual_network.west.name
  remote_virtual_network_id    = azurerm_virtual_network.east.id
  allow_virtual_network_access = true
  allow_forwarded_traffic      = true
}

resource "azurerm_private_dns_zone_virtual_network_link" "west" {
  name                  = "${random_pet.name_prefix.id}-west-pdzvnetlink.com"
  private_dns_zone_name = azurerm_private_dns_zone.west.name
  virtual_network_id    = azurerm_virtual_network.west.id
  resource_group_name   = azurerm_resource_group.west.name

  depends_on = [azurerm_virtual_network_peering.west]
}

resource "azurerm_postgresql_flexible_server" "west" {
  name                          = "${random_pet.name_prefix.id}-west-pg"
  resource_group_name           = azurerm_resource_group.west.name
  location                      = azurerm_resource_group.west.location
  create_mode                   = "Replica"
  source_server_id              = azurerm_postgresql_flexible_server.east.id
  version                       = azurerm_postgresql_flexible_server.east.version
  public_network_access_enabled = azurerm_postgresql_flexible_server.east.public_network_access_enabled
  sku_name                      = azurerm_postgresql_flexible_server.east.sku_name

  delegated_subnet_id = azurerm_subnet.west.id
  private_dns_zone_id = azurerm_private_dns_zone.west.id

  depends_on = [azurerm_private_dns_zone_virtual_network_link.west]

  lifecycle {
    ignore_changes = [zone]
  }

  timeouts {
    create = "120m"
  }
}

Debug Output/Panic Output

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_virtual_endpoint.example will be updated in-place
  ~ resource "azurerm_postgresql_flexible_server_virtual_endpoint" "example" {
        id                = "/subscriptions/8ffedf3e-82d2-49f5-9603-8b318198e483/resourceGroups/cardinal-east/providers/Microsoft.DBforPostgreSQL/flexibleServers/cardinal-east-pg/virtualEndpoints/cardinal-endpoint"
        name              = "cardinal-endpoint"
      ~ replica_server_id = "/subscriptions/8ffedf3e-82d2-49f5-9603-8b318198e483/resourceGroups/cardinal-east/providers/Microsoft.DBforPostgreSQL/flexibleServers/cardinal-west-pg" -> "/subscriptions/8ffedf3e-82d2-49f5-9603-8b318198e483/resourceGroups/cardinal-west/providers/Microsoft.DBforPostgreSQL/flexibleServers/cardinal-west-pg"
        # (2 unchanged attributes hidden)
    }

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

Expected Behaviour

No changes should be detected after initial creation

Actual Behaviour

Resources deploy correctly, however the Replica Server ID changes on the endpoint on second run due to the way it is derived from the Source Server within the provider.

The Virtual Endpoint presumes the replica server is in the same RG as the source server, which is not always the case.

Steps to Reproduce

Deploy resources, then immediately deploy them again.

Important Factoids

No response

References

// Model.Properties.Members should be a tuple => [source_server, replication_server]
state.SourceServerId = servers.NewFlexibleServerID(id.SubscriptionId, id.ResourceGroupName, (*resp.Model.Properties.Members)[0]).ID()
state.ReplicaServerId = servers.NewFlexibleServerID(id.SubscriptionId, id.ResourceGroupName, (*resp.Model.Properties.Members)[1]).ID()

@github-actions github-actions bot added the v/4.x label Sep 20, 2024
@neil-yechenwei
Copy link
Contributor

Thanks raising this issue. Seems I didn't reproduce this issue with above tf config. Does this issue happen when they're in the same resource group?

@bruceharrison1984
Copy link
Contributor Author

It does not, it only occurs when they are in separate RGs. I had planned on putting in a more correct example on Monday.

I hadn't expected anyone to take a look at this before then 😬

@leonrob
Copy link

leonrob commented Sep 23, 2024

@bruceharrison1984 is the real MVP

Copy link

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 github-actions bot locked as resolved and limited conversation to collaborators Nov 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.