Skip to content

Commit

Permalink
feat: replace "azurerm_sql_failover_group" with "azurerm_mssql_failov…
Browse files Browse the repository at this point in the history
…er_group"

The resource "azurerm_sql_failover_group" has been deprecated and is removed in the next
version of the AzureRM provider. In order to prepare for this, we are replacing it with
the new alternative "azurerm_mssql_failover_group". Because OpenTofu will run the delete
of "azurerm_sql_failover_group" in parallel with the creation of "azurerm_mssql_failover_group",
we need to create a resource with a different name so that Azure does not fail with
a name conflict error.

- Whether or not `instance_name` is set, a `-g` will be appended to the name of the failover
  group in Azure
- Because the name of the failover group has changed, existing bindings will cease to work,
  and apps must be rebound and restaged.
  • Loading branch information
blgm committed Jan 22, 2025
1 parent 0d231c3 commit 775d1af
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 25 deletions.
10 changes: 10 additions & 0 deletions acceptance-tests/helpers/apps/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ func (a *App) GET(format string, s ...any) string {
return string(data)
}

func (a *App) GETResponse(format string, s ...any) *http.Response {
GinkgoHelper()

url := a.urlf(format, s...)
GinkgoWriter.Printf("HTTP GET: %s\n", url)
response, err := http.Get(url)
Expect(err).NotTo(HaveOccurred())
return response
}

func (a *App) PUT(data, format string, s ...any) {
url := a.urlf(format, s...)
GinkgoWriter.Printf("HTTP PUT: %s\n", url)
Expand Down
9 changes: 6 additions & 3 deletions acceptance-tests/mssql_server_pair_and_fog_db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package acceptance_test

import (
"context"
"fmt"

"csbbrokerpakazure/acceptance-tests/helpers/apps"
"csbbrokerpakazure/acceptance-tests/helpers/brokers"
Expand Down Expand Up @@ -96,9 +97,11 @@ var _ = Describe("MSSQL Server Pair and Failover Group DB", Label("mssql-db-fail
runFailoverServicePlan,
services.WithBroker(serviceBroker),
services.WithParameters(map[string]any{
"server_pair_name": serversConfig.ServerPairTag,
"server_pairs": serversConfig.ServerPairsConfig(),
"fog_instance_name": fogName,
"server_pair_name": serversConfig.ServerPairTag,
"server_pairs": serversConfig.ServerPairsConfig(),
// We now append a "-g" to the instance name as we replace the "azurerm_sql_failover_group"
// resource with the "azurerm_mssql_failover_group" to avoid name clashes.
"fog_instance_name": fmt.Sprintf("%s-g", fogName),
}),
services.WithName(serviceNameStandard),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package upgrade_test

import (
"context"
"net/http"

"csbbrokerpakazure/acceptance-tests/helpers/apps"
"csbbrokerpakazure/acceptance-tests/helpers/brokers"
Expand Down Expand Up @@ -50,7 +51,7 @@ var _ = Describe("UpgradeMssqlDBFailoverGroupTest", Label("mssql-db-failover-gro
// is cleaned up regardless as to whether it wa successful. This is important when we use our own service broker
// (which can only have 5 instances at any time) to prevent subsequent test failures.
defer services.Delete(serviceName)
fogConfig := failoverGroupConfig(serversConfig.ServerPairTag)
fogConfig := newFailoverGroupConfig(serversConfig.ServerPairTag)
initialFogInstance := services.CreateInstance(
serviceOffering,
servicePlan,
Expand All @@ -65,8 +66,8 @@ var _ = Describe("UpgradeMssqlDBFailoverGroupTest", Label("mssql-db-failover-gro
defer apps.Delete(appOne, appTwo)

By("binding to the apps")
initialFogInstance.Bind(appOne)
initialFogInstance.Bind(appTwo)
bindingOne := initialFogInstance.Bind(appOne)
bindingTwo := initialFogInstance.Bind(appTwo)

By("starting the apps")
apps.Start(appOne, appTwo)
Expand All @@ -93,17 +94,37 @@ var _ = Describe("UpgradeMssqlDBFailoverGroupTest", Label("mssql-db-failover-gro
By("upgrading previous services")
initialFogInstance.Upgrade()

// When the "azurerm_sql_failover_group" resource is updated to the "azurerm_mssql_failover_group" resource,
// the name of the FOG has to be changed (to avoid name clashes), resulting in the URL of the FOG
// changing. This means that existing bindings do not work, and apps need to be re-bound.
// At some stage this behavior will change, and this check and the subsequent re-bind can be removed.
By("observing that existing bindings do not work")
resp := appTwo.GETResponse("%s/%s", schema, keyOne)
Expect(resp).To(HaveHTTPStatus(http.StatusInternalServerError))
Expect(resp).To(HaveHTTPBody(MatchRegexp(`error preparing statement:.*no such host`)))

By("re-binding and re-staging the apps")
bindingOne.Unbind()
bindingTwo.Unbind()
initialFogInstance.Bind(appOne)
initialFogInstance.Bind(appTwo)
apps.Restage(appOne, appTwo)

By("getting the previously set value using the second app")
got = appTwo.GET("%s/%s", schema, keyOne)
Expect(got).To(Equal(valueOne))

By("updating the instance plan")
initialFogInstance.Update("-p", "medium")
By("updating the instance")
initialFogInstance.Update("-c", "{}")

By("getting the previously set value using the second app")
got = appTwo.GET("%s/%s", schema, keyOne)
Expect(got).To(Equal(valueOne))

// We now append a "-g" to the instance name as we replace the "azurerm_sql_failover_group"
// resource with the "azurerm_mssql_failover_group" to avoid name clashes.
fogConfig.InstanceName += "-g"

By("connecting to the existing failover group")
const servicePlanExisting = "existing"
serviceNameExisting := random.Name(random.WithPrefix(serviceOffering, servicePlanExisting))
Expand All @@ -119,9 +140,9 @@ var _ = Describe("UpgradeMssqlDBFailoverGroupTest", Label("mssql-db-failover-gro
By("purging the initial FOG instance")
initialFogInstance.Purge()

By("creating new bindings and testing they still work")
bindingOne := dbFogInstance.Bind(appOne)
bindingTwo := dbFogInstance.Bind(appTwo)
By("creating new bindings using the 'existing' plan")
bindingOne = dbFogInstance.Bind(appOne)
bindingTwo = dbFogInstance.Bind(appTwo)
apps.Restage(appOne, appTwo)
defer bindingOne.Unbind()
defer bindingTwo.Unbind()
Expand All @@ -143,10 +164,16 @@ var _ = Describe("UpgradeMssqlDBFailoverGroupTest", Label("mssql-db-failover-gro
})
})

func failoverGroupConfig(serverPairTag string) map[string]string {
return map[string]string{
"instance_name": random.Name(random.WithPrefix("fog")),
"db_name": random.Name(random.WithPrefix("db")),
"server_pair": serverPairTag,
type failoverGroupConfig struct {
InstanceName string `json:"instance_name"`
DBName string `json:"db_name"`
ServerPairTag string `json:"server_pair"`
}

func newFailoverGroupConfig(serverPairTag string) failoverGroupConfig {
return failoverGroupConfig{
InstanceName: random.Name(random.WithPrefix("fog")),
DBName: random.Name(random.WithPrefix("db")),
ServerPairTag: serverPairTag,
}
}
2 changes: 1 addition & 1 deletion azure-mssql-db-failover-group.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ provision:
details: Maximum storage allocated to the database instance in GB
- field_name: instance_name
type: string
details: Name for your Azure SQL Failover Group
details: Name for your Azure SQL Failover Group. Note that the resource name in Azure will have "-g" appended.
default: csb-azsql-fog-${request.instance_id}
constraints:
maxLength: 63
Expand Down
15 changes: 9 additions & 6 deletions terraform/azure-mssql-db-failover/mssql-db-fog-main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,15 @@ resource "azurerm_mssql_database" "secondary_db" {
count = var.existing ? 0 : 1
}

resource "azurerm_sql_failover_group" "failover_group" {
name = var.instance_name
resource_group_name = var.server_credential_pairs[var.server_pair].primary.resource_group
server_name = data.azurerm_mssql_server.primary_sql_db_server.name
databases = [azurerm_mssql_database.primary_db[count.index].id]
partner_servers {
resource "azurerm_mssql_failover_group" "failover_group" {
# When switching from the "azurerm_sql_failover_group" to the "azurerm_mssql_failover_group"
# resource type, it's necessary to use a different name to prevent name clashes, so we add
# the suffix "-g" just to get a different name.
name = format("%s-g", var.instance_name)

server_id = data.azurerm_mssql_server.primary_sql_db_server.id
databases = [azurerm_mssql_database.primary_db[count.index].id]
partner_server {
id = data.azurerm_mssql_server.secondary_sql_db_server.id
}

Expand Down
4 changes: 2 additions & 2 deletions terraform/azure-mssql-db-failover/mssql-db-fog-outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
locals {
primary_db_name = (length(azurerm_mssql_database.primary_db) > 0 ? azurerm_mssql_database.primary_db[0].name : "")
primary_db_id = (length(azurerm_mssql_database.primary_db) > 0 ? azurerm_mssql_database.primary_db[0].id : "")
fog_name = (length(azurerm_sql_failover_group.failover_group) > 0 ? azurerm_sql_failover_group.failover_group[0].name : "")
fog_id = (length(azurerm_sql_failover_group.failover_group) > 0 ? azurerm_sql_failover_group.failover_group[0].id : "")
fog_name = (length(azurerm_mssql_failover_group.failover_group) > 0 ? azurerm_mssql_failover_group.failover_group[0].name : "")
fog_id = (length(azurerm_mssql_failover_group.failover_group) > 0 ? azurerm_mssql_failover_group.failover_group[0].id : "")
}

output "sqldbName" { value = var.existing ? var.db_name : local.primary_db_name }
Expand Down

0 comments on commit 775d1af

Please sign in to comment.