From 2b8150715edf974941df8441f93c116b9b52e88e Mon Sep 17 00:00:00 2001 From: Lyudmil Ilchev Date: Tue, 20 Jan 2026 15:43:59 +0200 Subject: [PATCH 1/6] add failover group module --- src/modules/mssql_failover_group/_locals.tf | 23 ++++++++++++++ src/modules/mssql_failover_group/_outputs.tf | 7 +++++ .../mssql_failover_group/_variables.tf | 18 +++++++++++ src/modules/mssql_failover_group/main.tf | 25 +++++++++++++++ src/modules/mssql_server/_outputs.tf | 5 +++ src/mssql_servers.tf | 31 +++++++++++++++++++ 6 files changed, 109 insertions(+) create mode 100644 src/modules/mssql_failover_group/_locals.tf create mode 100644 src/modules/mssql_failover_group/_outputs.tf create mode 100644 src/modules/mssql_failover_group/_variables.tf create mode 100644 src/modules/mssql_failover_group/main.tf diff --git a/src/modules/mssql_failover_group/_locals.tf b/src/modules/mssql_failover_group/_locals.tf new file mode 100644 index 00000000..45074f58 --- /dev/null +++ b/src/modules/mssql_failover_group/_locals.tf @@ -0,0 +1,23 @@ +locals { + primary_server = var.resources[ + try(var.settings.primary.lz_key, var.client_config.landingzone_key) + ].mssql_servers[var.settings.primary.server_ref] + + secondary_server = var.resources[ + try(var.settings.secondary.lz_key, var.client_config.landingzone_key) + ].mssql_servers[var.settings.secondary.server_ref] + + primary_server_id = local.primary_server.id + secondary_server_id = local.secondary_server.id + + database_ids = [ + for db_ref in sort(try(var.settings.database_refs, [])) : + local.primary_server.databases[db_ref].id + ] + + tags = merge( + var.global_settings.tags, + var.global_settings.inherit_resource_group_tags ? local.resource_group.tags : {}, + try(var.settings.tags, {}) + ) +} diff --git a/src/modules/mssql_failover_group/_outputs.tf b/src/modules/mssql_failover_group/_outputs.tf new file mode 100644 index 00000000..12490513 --- /dev/null +++ b/src/modules/mssql_failover_group/_outputs.tf @@ -0,0 +1,7 @@ +output "id" { + value = azurerm_mssql_failover_group.main.id +} + +output "name" { + value = azurerm_mssql_failover_group.main.name +} \ No newline at end of file diff --git a/src/modules/mssql_failover_group/_variables.tf b/src/modules/mssql_failover_group/_variables.tf new file mode 100644 index 00000000..bb7a9d86 --- /dev/null +++ b/src/modules/mssql_failover_group/_variables.tf @@ -0,0 +1,18 @@ +variable "global_settings" { + description = "Global settings for tinycaf" +} + +variable "settings" { + description = "All the configuration for this resource" +} + +variable "resources" { + description = "All required resources" +} + +variable "client_config" { + description = "Client config such as current landingzone key" + type = object({ + landingzone_key = string + }) +} diff --git a/src/modules/mssql_failover_group/main.tf b/src/modules/mssql_failover_group/main.tf new file mode 100644 index 00000000..3acea167 --- /dev/null +++ b/src/modules/mssql_failover_group/main.tf @@ -0,0 +1,25 @@ +resource "azurerm_mssql_failover_group" "main" { + name = var.settings.name + server_id = local.primary_server_id + + partner_server { + id = local.secondary_server_id + } + + databases = local.database_ids + + read_write_endpoint_failover_policy { + mode = try(var.settings.read_write_endpoint_failover_policy.mode, "Automatic") + grace_minutes = try(var.settings.read_write_endpoint_failover_policy.grace_minutes, 60) + } + + dynamic "readonly_endpoint_failover_policy" { + for_each = can(var.settings.readonly_endpoint_failover_policy) ? [1] : [] + content { + mode = try(var.settings.readonly_endpoint_failover_policy.mode, "Enabled") + } + } + + tags = local.tags + +} diff --git a/src/modules/mssql_server/_outputs.tf b/src/modules/mssql_server/_outputs.tf index f062ede7..0e7143b3 100644 --- a/src/modules/mssql_server/_outputs.tf +++ b/src/modules/mssql_server/_outputs.tf @@ -9,3 +9,8 @@ output "name" { output "fully_qualified_domain_name" { value = azurerm_mssql_server.main.fully_qualified_domain_name } + +output "databases" { + description = "Map of database refs to database module outputs (includes id)" + value = module.mssql_databases +} diff --git a/src/mssql_servers.tf b/src/mssql_servers.tf index 9da908e3..ea264dec 100644 --- a/src/mssql_servers.tf +++ b/src/mssql_servers.tf @@ -24,3 +24,34 @@ module "mssql_servers" { } ) } + + +module "mssql_failover_group" { + source = "./modules/mssql_failover_group" + for_each = var.mssql_failover_groups + + settings = each.value + global_settings = local.global_settings + client_config = { + landingzone_key = var.landingzone.key + } + + resources = merge( + { + (var.landingzone.key) = { + resource_groups = module.resource_groups + managed_identities = module.managed_identities + key_vault_keys = module.key_vault_keys + keyvaults = module.keyvaults + virtual_networks = module.virtual_networks + private_dns_zones = module.private_dns_zones + mssql_servers = module.mssql_servers + } + }, + { + for k, v in module.remote_states : k => v.outputs + } + ) +} + + From a33d174dc9bacf4a988de85d7ce3e544992bc15f Mon Sep 17 00:00:00 2001 From: Lyudmil Ilchev Date: Tue, 20 Jan 2026 15:45:19 +0200 Subject: [PATCH 2/6] add failover group module --- src/_variables.resources.tf | 2 ++ src/mssql_servers.tf | 6 ------ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/_variables.resources.tf b/src/_variables.resources.tf index e48bef3b..fa58dd4d 100644 --- a/src/_variables.resources.tf +++ b/src/_variables.resources.tf @@ -12,6 +12,8 @@ variable "network_interfaces" { default = {} } variable "nat_gateway_public_ip_association" { default = {} } +variable "mssql_failover_groups" { default = {} } + variable "network_interface_security_group_associations" { default = {} } variable "mssql_virtual_machines" { default = {} } diff --git a/src/mssql_servers.tf b/src/mssql_servers.tf index ea264dec..e8dd0073 100644 --- a/src/mssql_servers.tf +++ b/src/mssql_servers.tf @@ -39,12 +39,6 @@ module "mssql_failover_group" { resources = merge( { (var.landingzone.key) = { - resource_groups = module.resource_groups - managed_identities = module.managed_identities - key_vault_keys = module.key_vault_keys - keyvaults = module.keyvaults - virtual_networks = module.virtual_networks - private_dns_zones = module.private_dns_zones mssql_servers = module.mssql_servers } }, From 750533f4928fdb56013989cecdf7593e529a3e46 Mon Sep 17 00:00:00 2001 From: Lyudmil Ilchev Date: Tue, 20 Jan 2026 15:49:28 +0200 Subject: [PATCH 3/6] add failover group module --- src/modules/mssql_failover_group/_locals.tf | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/modules/mssql_failover_group/_locals.tf b/src/modules/mssql_failover_group/_locals.tf index 45074f58..76756f00 100644 --- a/src/modules/mssql_failover_group/_locals.tf +++ b/src/modules/mssql_failover_group/_locals.tf @@ -3,12 +3,18 @@ locals { try(var.settings.primary.lz_key, var.client_config.landingzone_key) ].mssql_servers[var.settings.primary.server_ref] - secondary_server = var.resources[ - try(var.settings.secondary.lz_key, var.client_config.landingzone_key) - ].mssql_servers[var.settings.secondary.server_ref] + secondary_server = try( + var.resources[ + try(var.settings.secondary.lz_key, var.client_config.landingzone_key) + ].mssql_servers[var.settings.secondary.server_ref], + null + ) - primary_server_id = local.primary_server.id - secondary_server_id = local.secondary_server.id + primary_server_id = local.primary_server.id + secondary_server_id = try( + local.secondary_server.id, + var.settings.secondary.server_id + ) database_ids = [ for db_ref in sort(try(var.settings.database_refs, [])) : From b19e174e79accaa950ba708be66525c72aca7cdb Mon Sep 17 00:00:00 2001 From: Lyudmil Ilchev Date: Tue, 20 Jan 2026 15:58:56 +0200 Subject: [PATCH 4/6] fix tags due to no resource group in the resource --- src/modules/mssql_failover_group/_locals.tf | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/modules/mssql_failover_group/_locals.tf b/src/modules/mssql_failover_group/_locals.tf index 76756f00..4f31fbd1 100644 --- a/src/modules/mssql_failover_group/_locals.tf +++ b/src/modules/mssql_failover_group/_locals.tf @@ -21,9 +21,5 @@ locals { local.primary_server.databases[db_ref].id ] - tags = merge( - var.global_settings.tags, - var.global_settings.inherit_resource_group_tags ? local.resource_group.tags : {}, - try(var.settings.tags, {}) - ) + tags = try(var.settings.tags, null) } From 64aa0740ff5ec860bcd476310a6d6369c3589aeb Mon Sep 17 00:00:00 2001 From: Lyudmil Ilchev Date: Tue, 20 Jan 2026 16:02:39 +0200 Subject: [PATCH 5/6] remove unused attribute block --- src/modules/mssql_failover_group/main.tf | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/modules/mssql_failover_group/main.tf b/src/modules/mssql_failover_group/main.tf index 3acea167..101620f9 100644 --- a/src/modules/mssql_failover_group/main.tf +++ b/src/modules/mssql_failover_group/main.tf @@ -12,13 +12,10 @@ resource "azurerm_mssql_failover_group" "main" { mode = try(var.settings.read_write_endpoint_failover_policy.mode, "Automatic") grace_minutes = try(var.settings.read_write_endpoint_failover_policy.grace_minutes, 60) } - - dynamic "readonly_endpoint_failover_policy" { - for_each = can(var.settings.readonly_endpoint_failover_policy) ? [1] : [] - content { - mode = try(var.settings.readonly_endpoint_failover_policy.mode, "Enabled") - } - } + readonly_endpoint_failover_policy_enabled = try( + var.settings.readonly_endpoint_failover_policy.enabled, + false + ) tags = local.tags From e0021d3d6404a5524f48a797d1c2eaff476f4444 Mon Sep 17 00:00:00 2001 From: Lyudmil Ilchev Date: Tue, 20 Jan 2026 16:20:07 +0200 Subject: [PATCH 6/6] fix automatic and manual blocks --- src/modules/mssql_failover_group/main.tf | 26 +++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/modules/mssql_failover_group/main.tf b/src/modules/mssql_failover_group/main.tf index 101620f9..8fba8e00 100644 --- a/src/modules/mssql_failover_group/main.tf +++ b/src/modules/mssql_failover_group/main.tf @@ -8,9 +8,29 @@ resource "azurerm_mssql_failover_group" "main" { databases = local.database_ids - read_write_endpoint_failover_policy { - mode = try(var.settings.read_write_endpoint_failover_policy.mode, "Automatic") - grace_minutes = try(var.settings.read_write_endpoint_failover_policy.grace_minutes, 60) + dynamic "read_write_endpoint_failover_policy" { + for_each = ( + try(var.settings.read_write_endpoint_failover_policy.mode, "Automatic") == "Manual" + ? [1] + : [] + ) + + content { + mode = "Manual" + } + } + + dynamic "read_write_endpoint_failover_policy" { + for_each = ( + try(var.settings.read_write_endpoint_failover_policy.mode, "Automatic") != "Manual" + ? [1] + : [] + ) + + content { + mode = try(var.settings.read_write_endpoint_failover_policy.mode, "Automatic") + grace_minutes = try(var.settings.read_write_endpoint_failover_policy.grace_minutes, 60) + } } readonly_endpoint_failover_policy_enabled = try( var.settings.readonly_endpoint_failover_policy.enabled,