Skip to content

Commit df8accd

Browse files
anuhyapolisettiAnuhya P
andauthored
feat!: Add pwd validation policy for mysql modules (#409)
Co-authored-by: Anuhya P <[email protected]>
1 parent 3d2cece commit df8accd

File tree

7 files changed

+97
-4
lines changed

7 files changed

+97
-4
lines changed

examples/mysql-ha/main.tf

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ module "mysql" {
6868
]
6969
}
7070

71+
password_validation_policy_config = {
72+
enable_password_policy = true
73+
complexity = "COMPLEXITY_DEFAULT"
74+
disallow_username_substring = true
75+
min_length = 8
76+
}
77+
7178
backup_configuration = {
7279
enabled = true
7380
binary_log_enabled = true
@@ -139,19 +146,20 @@ module "mysql" {
139146
]
140147

141148
user_name = "tftest"
142-
user_password = "foobar"
149+
user_password = "Example!12345"
150+
root_password = ".5nHITPioEJk^k}="
143151

144152
additional_users = [
145153
{
146154
name = "tftest2"
147-
password = "abcdefg"
155+
password = "Example!12345"
148156
host = "localhost"
149157
type = "BUILT_IN"
150158
random_password = false
151159
},
152160
{
153161
name = "tftest3"
154-
password = "abcdefg"
162+
password = "Example!12345"
155163
host = "localhost"
156164
type = "BUILT_IN"
157165
random_password = false

modules/mysql/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Note: CloudSQL provides [disk autoresize](https://cloud.google.com/sql/docs/mysq
3737
| maintenance\_window\_update\_track | The update track of maintenance window for the master instance maintenance. Can be either `canary` or `stable`. | `string` | `"canary"` | no |
3838
| module\_depends\_on | List of modules or resources this module depends on. | `list(any)` | `[]` | no |
3939
| name | The name of the Cloud SQL resources | `string` | n/a | yes |
40+
| password\_validation\_policy\_config | The password validation policy settings for the database instance. | <pre>object({<br> enable_password_policy = bool<br> min_length = number<br> complexity = string<br> disallow_username_substring = bool<br> })</pre> | `null` | no |
4041
| pricing\_plan | The pricing plan for the master instance. | `string` | `"PER_USE"` | no |
4142
| project\_id | The project ID to manage the Cloud SQL resources | `string` | n/a | yes |
4243
| random\_instance\_name | Sets random suffix at the end of the Cloud SQL resource name | `bool` | `false` | no |
@@ -45,6 +46,7 @@ Note: CloudSQL provides [disk autoresize](https://cloud.google.com/sql/docs/mysq
4546
| read\_replicas | List of read replicas to create. Encryption key is required for replica in different region. For replica in same region as master set encryption\_key\_name = null | <pre>list(object({<br> name = string<br> name_override = optional(string)<br> tier = string<br> zone = string<br> availability_type = string<br> disk_type = string<br> disk_autoresize = bool<br> disk_autoresize_limit = number<br> disk_size = string<br> user_labels = map(string)<br> database_flags = list(object({<br> name = string<br> value = string<br> }))<br> ip_configuration = object({<br> authorized_networks = list(map(string))<br> ipv4_enabled = bool<br> private_network = string<br> require_ssl = bool<br> allocated_ip_range = string<br> })<br> encryption_key_name = string<br> }))</pre> | `[]` | no |
4647
| region | The region of the Cloud SQL resources | `string` | `"us-central1"` | no |
4748
| replica\_database\_version | The read replica database version to use. This var should only be used during a database update. The update sequence 1. read-replica 2. master, setting this to an updated version will cause the replica to update, then you may update the master with the var database\_version and remove this field after update is complete | `string` | `""` | no |
49+
| root\_password | Mysql password for the root user. If not set, a random one will be generated and available in the root\_password output variable. | `string` | `""` | no |
4850
| secondary\_zone | The preferred zone for the secondary/failover instance, it should be something like: `us-central1-a`, `us-east1-c`. | `string` | `null` | no |
4951
| tier | The tier for the master instance. | `string` | `"db-n1-standard-1"` | no |
5052
| update\_timeout | The optional timout that is applied to limit long database updates. | `string` | `"10m"` | no |

modules/mysql/main.tf

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ resource "google_sql_database_instance" "default" {
4848
region = var.region
4949
encryption_key_name = var.encryption_key_name
5050
deletion_protection = var.deletion_protection
51+
root_password = var.root_password != "" ? var.root_password : null
5152

5253
settings {
5354
tier = var.tier
@@ -90,6 +91,16 @@ resource "google_sql_database_instance" "default" {
9091
time = lookup(deny_maintenance_period.value, "time", null)
9192
}
9293
}
94+
dynamic "password_validation_policy" {
95+
for_each = var.password_validation_policy_config != null ? [var.password_validation_policy_config] : []
96+
97+
content {
98+
enable_password_policy = lookup(password_validation_policy.value, "enable_password_policy", null)
99+
min_length = lookup(password_validation_policy.value, "min_length", null)
100+
complexity = lookup(password_validation_policy.value, "complexity", null)
101+
disallow_username_substring = lookup(password_validation_policy.value, "disallow_username_substring", null)
102+
}
103+
}
93104
dynamic "ip_configuration" {
94105
for_each = [local.ip_configurations[local.ip_configuration_enabled ? "enabled" : "disabled"]]
95106
content {
@@ -178,7 +189,7 @@ resource "random_password" "user-password" {
178189
}
179190

180191
length = 32
181-
special = false
192+
special = true
182193
depends_on = [null_resource.module_depends_on, google_sql_database_instance.default]
183194
}
184195

modules/mysql/metadata.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,21 @@ spec:
143143
type: bool
144144
default: true
145145
required: false
146+
- name: deletion_protection_enabled
147+
description: Enables protection of an instance from accidental deletion protection across all surfaces (API, gcloud, Cloud Console and Terraform).
148+
type: bool
149+
default: false
150+
required: false
151+
- name: deny_maintenance_period
152+
description: The Deny Maintenance Period fields to prevent automatic maintenance from occurring during a 90-day time period. See [more details](https://cloud.google.com/sql/docs/mysql/maintenance)
153+
type: |-
154+
list(object({
155+
end_date = string
156+
start_date = string
157+
time = string
158+
}))
159+
default: []
160+
required: false
146161
- name: disk_autoresize
147162
description: Configuration to increase storage size
148163
type: bool
@@ -231,6 +246,16 @@ spec:
231246
description: The name of the Cloud SQL resources
232247
type: string
233248
required: true
249+
- name: password_validation_policy_config
250+
description: The password validation policy settings for the database instance.
251+
type: |-
252+
object({
253+
enable_password_policy = bool
254+
min_length = number
255+
complexity = string
256+
disallow_username_substring = bool
257+
})
258+
required: false
234259
- name: pricing_plan
235260
description: The pricing plan for the master instance.
236261
type: string
@@ -260,6 +285,7 @@ spec:
260285
type: |-
261286
list(object({
262287
name = string
288+
name_override = optional(string)
263289
tier = string
264290
zone = string
265291
availability_type = string
@@ -293,6 +319,11 @@ spec:
293319
type: string
294320
default: ""
295321
required: false
322+
- name: root_password
323+
description: Mysql password for the root user. If not set, a random one will be generated and available in the root_password output variable.
324+
type: string
325+
default: ""
326+
required: false
296327
- name: secondary_zone
297328
description: 'The preferred zone for the secondary/failover instance, it should be something like: `us-central1-a`, `us-east1-c`.'
298329
type: string

modules/mysql/variables.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,17 @@ variable "ip_configuration" {
215215
}
216216
}
217217

218+
variable "password_validation_policy_config" {
219+
description = "The password validation policy settings for the database instance."
220+
type = object({
221+
enable_password_policy = bool
222+
min_length = number
223+
complexity = string
224+
disallow_username_substring = bool
225+
})
226+
default = null
227+
}
228+
218229
// Read Replicas
219230
variable "read_replicas" {
220231
description = "List of read replicas to create. Encryption key is required for replica in different region. For replica in same region as master set encryption_key_name = null"
@@ -291,6 +302,12 @@ variable "user_host" {
291302
default = "%"
292303
}
293304

305+
variable "root_password" {
306+
description = "Mysql password for the root user. If not set, a random one will be generated and available in the root_password output variable."
307+
type = string
308+
default = ""
309+
}
310+
294311
variable "user_password" {
295312
description = "The password for the default user. If not set, a random one will be generated and available in the generated_user_password output variable."
296313
type = string

modules/postgresql/metadata.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,21 @@ spec:
145145
type: bool
146146
default: true
147147
required: false
148+
- name: deletion_protection_enabled
149+
description: Enables protection of an instance from accidental deletion protection across all surfaces (API, gcloud, Cloud Console and Terraform).
150+
type: bool
151+
default: false
152+
required: false
153+
- name: deny_maintenance_period
154+
description: The Deny Maintenance Period fields to prevent automatic maintenance from occurring during a 90-day time period. See [more details](https://cloud.google.com/sql/docs/postgres/maintenance)
155+
type: |-
156+
list(object({
157+
end_date = string
158+
start_date = string
159+
time = string
160+
}))
161+
default: []
162+
required: false
148163
- name: disk_autoresize
149164
description: Configuration to increase storage size.
150165
type: bool
@@ -278,6 +293,7 @@ spec:
278293
type: |-
279294
list(object({
280295
name = string
296+
name_override = optional(string)
281297
tier = string
282298
availability_type = string
283299
zone = string
@@ -348,6 +364,8 @@ spec:
348364
description: List of maps of additional users and passwords
349365
- name: generated_user_password
350366
description: The auto generated default user password if not input password was provided
367+
- name: iam_user_emails
368+
description: The list of the IAM users with the access to the Cloudsql instance
351369
- name: instance_connection_name
352370
description: The connection name of the master instance to be used in connection strings
353371
- name: instance_first_ip_address

test/integration/mysql-ha/mysql_ha_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ func TestMySqlHaModule(t *testing.T) {
9494
assert.Equal(int64(365), op.Get("settings.backupConfiguration.backupRetentionSettings.retainedBackups").Int(), "Expected 365 backupConfigurationRetainedBackups")
9595
assert.Equal("COUNT", op.Get("settings.backupConfiguration.backupRetentionSettings.retentionUnit").String(), "Expected COUNT backupConfigurationRetentionUnit")
9696

97+
// assert password policy settings
98+
assert.True(op.Get("settings.passwordValidationPolicy.enablePasswordPolicy").Bool(), "Expected TRUE enablePasswordPolicy")
99+
assert.Equal("COMPLEXITY_DEFAULT", op.Get("settings.passwordValidationPolicy.complexity").String(), "Expected COMPLEXITY_DEFAULT complexity")
100+
assert.True(op.Get("settings.passwordValidationPolicy.disallowUsernameSubstring").Bool(), "Expected TRUE disallowUsernameSubstring")
101+
assert.Equal(int64(8), op.Get("settings.passwordValidationPolicy.minLength").Int(), "Expected 8 minLength")
102+
97103
// assert users
98104
op = gcloud.Run(t, fmt.Sprintf("sql users list --instance %s --project %s", mySql.GetStringOutput("name"), mySql.GetStringOutput("project_id")))
99105
assert.Equal(3, len(op.Array()), "Expected at least 3 users")

0 commit comments

Comments
 (0)