Skip to content

Commit 06cc050

Browse files
dploegerDennis Ploeger
authored andcommitted
BREAKING CHANGE: Support for flexible server
This commit switches from the deprecated single server solution to the new flexible server. The configuration is nearly the same as before, but the different network handling makes the configuration incompatible. Warning: Using this version DESTROYS the previously deployed server, so a manual migration using dumps and restore is required. Additionally, additional mysql configurations are supported in this as well.
1 parent 0d4eb1a commit 06cc050

File tree

7 files changed

+192
-93
lines changed

7 files changed

+192
-93
lines changed

README.md

Lines changed: 77 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
## Introduction
44

5-
This module manages resources for Azure DB for MySQL.
5+
This module manages resources for Azure DB for MySQL using the flexible server deployment.
6+
7+
More details are available in the following sources:
8+
9+
- [Terraform AzureRM provider flexible server resource type](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mysql_flexible_server)
10+
- [Microsoft flexible server documentation](https://learn.microsoft.com/en-us/azure/mysql/flexible-server/)
611

712
## Usage
813

@@ -34,11 +39,12 @@ No modules.
3439

3540
The following resources are used by this module:
3641

37-
- [azurerm_mysql_database.db](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mysql_database) (resource)
38-
- [azurerm_mysql_firewall_rule.firewall](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mysql_firewall_rule) (resource)
39-
- [azurerm_mysql_server.server](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mysql_server) (resource)
40-
- [azurerm_mysql_virtual_network_rule.virtualnetworks](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mysql_virtual_network_rule) (resource)
41-
- [azurerm_private_endpoint.mysql-private-endpoint](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint) (resource)
42+
- [azurerm_mysql_flexible_database.db](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mysql_flexible_database) (resource)
43+
- [azurerm_mysql_flexible_server.server](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mysql_flexible_server) (resource)
44+
- [azurerm_mysql_flexible_server_configuration.configuration](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mysql_flexible_server_configuration) (resource)
45+
- [azurerm_mysql_flexible_server_configuration.require-secure-transport](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mysql_flexible_server_configuration) (resource)
46+
- [azurerm_mysql_flexible_server_configuration.tls-version](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mysql_flexible_server_configuration) (resource)
47+
- [azurerm_mysql_flexible_server_firewall_rule.firewall](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mysql_flexible_server_firewall_rule) (resource)
4248

4349
## Required Inputs
4450

@@ -52,14 +58,13 @@ Type: `string`
5258

5359
### charset
5460

55-
Description: Charset for the databases, which needs to be a valid PostgreSQL charset
61+
Description: Charset for the databases, which needs to be a valid MySQL charset
5662

5763
Type: `string`
5864

5965
### collation
6066

61-
Description: Collation for the databases, which needs to be a valid PostgreSQL collation. Note that Microsoft uses
62-
different notation - f.e. en-US instead of en\_US
67+
Description: Charset for the databases, which needs to be a valid MySQL charset
6368

6469
Type: `string`
6570

@@ -122,6 +127,14 @@ map(object({
122127

123128
Default: `{}`
124129

130+
### availability\_zone
131+
132+
Description: The availability zone the server will be created in
133+
134+
Type: `string`
135+
136+
Default: `"1"`
137+
125138
### backup\_retention\_days
126139

127140
Description: Number of days to keep backups
@@ -130,48 +143,89 @@ Type: `number`
130143

131144
Default: `7`
132145

146+
### configurations
147+
148+
Description: Additional MySQL configurations
149+
150+
Type: `map(string)`
151+
152+
Default: `{}`
153+
133154
### database\_host\_sku
134155

135156
Description: SKU for the database server to use
136157

137158
Type: `string`
138159

139-
Default: `"GP_Gen5_2"`
160+
Default: `"GP_Standard_D4ds_v4"`
161+
162+
### database\_storage\_autogrow
163+
164+
Description: Autogrow storage when limit is reached?
165+
166+
Type: `bool`
140167

141-
### database\_storage
168+
Default: `true`
142169

143-
Description: Required database storage (in MB)
170+
### database\_storage\_iops
171+
172+
Description: IO operations per second
173+
174+
Type: `number`
175+
176+
Default: `3600`
177+
178+
### database\_storage\_size
179+
180+
Description: Required database storage (in GB)
144181

145182
Type: `string`
146183

147-
Default: `"5120"`
184+
Default: `"20"`
148185

149186
### database\_version
150187

151188
Description: Database version to use
152189

153190
Type: `string`
154191

155-
Default: `"8.0"`
192+
Default: `"8.0.21"`
193+
194+
### delegated\_subnet\_id
195+
196+
Description: The id of a subnet that the server will be created in if private-only access is required.
197+
This subnet requires a service delegation definition like this:
198+
```hcl
199+
delegation {
200+
name = "fs"
201+
service_delegation {
202+
name = "Microsoft.DBforMySQL/flexibleServers"
203+
actions = [
204+
"Microsoft.Network/virtualNetworks/subnets/join/action",
205+
]
206+
}
207+
}
208+
```
209+
210+
Type: `string`
211+
212+
Default: `null`
156213

157-
### public\_access
214+
### geo\_redundant\_backup\_enabled
158215

159-
Description: Wether to allow public access to the database server. True will create firewall rules for allowed\_ips and for subnets. False will
160-
create a private endpoint in each given subnet (allowed\_ips will not be used then) - you have to set
161-
enforce\_private\_link\_endpoint\_network\_policies = true on your subnet in this case (see
162-
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet#enforce_private_link_endpoint_network_policies).
216+
Description: Whether backups should be geo redundant
163217

164218
Type: `bool`
165219

166220
Default: `false`
167221

168-
### subnets
222+
### private\_dns\_zone\_id
169223

170-
Description: Maps of prefix => subnet id that has access to the server
224+
Description: The id of the private dns zone when using private-only access
171225

172-
Type: `map(string)`
226+
Type: `string`
173227

174-
Default: `{}`
228+
Default: `null`
175229

176230
### suffix
177231

configuration.tf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
resource "azurerm_mysql_flexible_server_configuration" "require-secure-transport" {
2+
resource_group_name = var.resource_group
3+
server_name = azurerm_mysql_flexible_server.server.name
4+
name = "require_secure_transport"
5+
value = "ON"
6+
}
7+
8+
resource "azurerm_mysql_flexible_server_configuration" "tls-version" {
9+
resource_group_name = var.resource_group
10+
server_name = azurerm_mysql_flexible_server.server.name
11+
name = "tls_version"
12+
value = "TLSv1.2"
13+
}
14+
15+
resource "azurerm_mysql_flexible_server_configuration" "configuration" {
16+
for_each = var.configurations
17+
resource_group_name = var.resource_group
18+
server_name = azurerm_mysql_flexible_server.server.name
19+
name = each.key
20+
value = each.value
21+
}

databases.tf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
resource "azurerm_mysql_database" "db" {
1+
resource "azurerm_mysql_flexible_database" "db" {
22
for_each = toset(var.database_suffixes)
3-
name = "${var.project}${var.stage}db${each.value}"
43
resource_group_name = var.resource_group
5-
server_name = azurerm_mysql_server.server.name
4+
server_name = azurerm_mysql_flexible_server.server.name
5+
name = "${var.project}${var.stage}db${each.value}"
66
charset = var.charset
77
collation = var.collation
8-
}
8+
}

firewall.tf

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,8 @@
1-
resource "azurerm_mysql_firewall_rule" "firewall" {
2-
for_each = var.public_access == true ? var.allowed_ips : {}
1+
resource "azurerm_mysql_flexible_server_firewall_rule" "firewall" {
2+
for_each = var.allowed_ips
33
start_ip_address = each.value.start
44
end_ip_address = each.value.end
55
name = "${var.project}${var.stage}dbfw${each.key}"
66
resource_group_name = var.resource_group
7-
server_name = azurerm_mysql_server.server.name
7+
server_name = azurerm_mysql_flexible_server.server.name
88
}
9-
10-
resource "azurerm_mysql_virtual_network_rule" "virtualnetworks" {
11-
for_each = var.public_access == true ? var.subnets : {}
12-
name = "${var.project}${var.stage}dbfwnet${each.key}"
13-
resource_group_name = var.resource_group
14-
server_name = azurerm_mysql_server.server.name
15-
subnet_id = each.value
16-
}
17-
18-
resource "azurerm_private_endpoint" "mysql-private-endpoint" {
19-
for_each = var.public_access == false ? var.subnets : {}
20-
name = "${each.value}-mysql-${azurerm_mysql_server.server.id}-endpoint"
21-
location = var.location
22-
resource_group_name = var.resource_group
23-
subnet_id = each.value
24-
25-
private_service_connection {
26-
name = "${each.value}-mysql-${azurerm_mysql_server.server.id}-privateserviceconnection"
27-
private_connection_resource_id = azurerm_mysql_server.server.id
28-
subresource_names = ["mysqlServer"]
29-
is_manual_connection = false
30-
}
31-
}

outputs.tf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
output "server_fqdn" {
22
description = "FQDN of the database service"
3-
value = azurerm_mysql_server.server.fqdn
3+
value = azurerm_mysql_flexible_server.server.fqdn
44
}
55

66
output "admin_login" {
@@ -12,7 +12,7 @@ output "admin_password" {
1212
}
1313

1414
output "databases" {
15-
value = length(azurerm_mysql_database.db) > 0 ? {
16-
for index, suffix in var.database_suffixes : suffix => azurerm_mysql_database.db[suffix].name
15+
value = length(azurerm_mysql_flexible_database.db) > 0 ? {
16+
for index, suffix in var.database_suffixes : suffix => azurerm_mysql_flexible_database.db[suffix].name
1717
} : {}
1818
}

server.tf

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,29 @@
1-
resource "azurerm_mysql_server" "server" {
2-
name = "${var.project}${var.stage}dbsrv"
3-
location = var.location
4-
resource_group_name = var.resource_group
5-
administrator_login = var.admin_login
6-
administrator_login_password = var.admin_password
7-
sku_name = var.database_host_sku
8-
storage_mb = var.database_storage
9-
version = var.database_version
10-
backup_retention_days = var.backup_retention_days
11-
public_network_access_enabled = var.public_access
1+
resource "azurerm_mysql_flexible_server" "server" {
2+
name = "${var.project}${var.stage}dbsrv"
3+
location = var.location
4+
resource_group_name = var.resource_group
5+
administrator_login = var.admin_login
6+
administrator_password = var.admin_password
7+
sku_name = var.database_host_sku
8+
storage {
9+
size_gb = var.database_storage_size
10+
auto_grow_enabled = var.database_storage_autogrow
11+
iops = var.database_storage_iops
12+
}
13+
version = var.database_version
14+
backup_retention_days = var.backup_retention_days
1215

13-
auto_grow_enabled = true
14-
geo_redundant_backup_enabled = false
15-
infrastructure_encryption_enabled = true
16-
ssl_enforcement_enabled = true
17-
ssl_minimal_tls_version_enforced = "TLS1_2"
18-
}
16+
delegated_subnet_id = var.delegated_subnet_id
17+
private_dns_zone_id = var.private_dns_zone_id
18+
19+
geo_redundant_backup_enabled = var.geo_redundant_backup_enabled
20+
21+
zone = var.availability_zone
22+
23+
lifecycle {
24+
precondition {
25+
condition = (var.private_dns_zone_id == null && var.delegated_subnet_id == null) || (var.private_dns_zone_id != null && var.delegated_subnet_id != null)
26+
error_message = "The parameter private_dns_zone_id requires the parameter delegated_subnet_id and vice versa."
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)