AlloyDB read poll support and various usability fixes (#3061)
* AlloyDB read poll support and various usability fixes * Added support for read poll instances. * Added support for public (outbound) IPs. * Added new arguments: `machine_type`, `skip_await_major_version_upgrade`, and `subscription_type`. * Added outputs for key cluster attributes, including ID and name. * Improved input variable validations and simplified configurations. * Fixed bug where AlloyDB user accounts always had null passwords. * Resolved Terraform state drift issues for `network_config` and `psc_config`. * Fixed `continuous_backup_config` always being implicitly or explicitly enabled. * Fixed `automated_backup_policy` and `maintenance_update_policy`, which do not support non-zero minutes, seconds and nanos. * Fixed various typos. * Aligned the format of test examples. * Fixed invalid condition: authorized external networks require enabled public IP, however enabled public IP can have empty authorized external networks * Formatting * Fix PSA block --------- Co-authored-by: Julio Castillo <jccb@google.com>
This commit is contained in:
@@ -22,7 +22,6 @@ variable "annotations" {
|
||||
|
||||
variable "automated_backup_configuration" {
|
||||
description = "Automated backup settings for cluster."
|
||||
nullable = false
|
||||
type = object({
|
||||
enabled = optional(bool, false)
|
||||
backup_window = optional(string, "1800s")
|
||||
@@ -32,44 +31,27 @@ variable "automated_backup_configuration" {
|
||||
"MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"
|
||||
])
|
||||
start_times = optional(object({
|
||||
hours = optional(number, 23)
|
||||
minutes = optional(number, 0)
|
||||
seconds = optional(number, 0)
|
||||
nanos = optional(number, 0)
|
||||
hours = optional(number, 23)
|
||||
}), {})
|
||||
}), {})
|
||||
retention_count = optional(number, 7)
|
||||
retention_period = optional(string, null)
|
||||
retention_period = optional(string)
|
||||
})
|
||||
default = {
|
||||
enabled = false
|
||||
backup_window = "1800s"
|
||||
location = null
|
||||
weekly_schedule = {
|
||||
days_of_week = ["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"]
|
||||
start_times = {
|
||||
hours = 23
|
||||
minutes = 0
|
||||
seconds = 0
|
||||
nanos = 0
|
||||
}
|
||||
}
|
||||
retention_count = 7
|
||||
retention_period = null
|
||||
}
|
||||
default = {}
|
||||
nullable = false
|
||||
validation {
|
||||
condition = (
|
||||
var.automated_backup_configuration.enabled ? (
|
||||
# Maintenance window validation below
|
||||
# Backup window validation below
|
||||
!(var.automated_backup_configuration.retention_count != null && var.automated_backup_configuration.retention_period != null) &&
|
||||
# Maintenance window day validation
|
||||
length([
|
||||
for day in var.automated_backup_configuration.weekly_schedule.days_of_week : true
|
||||
if contains(["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"], day)
|
||||
]) == length(var.automated_backup_configuration.weekly_schedule.days_of_week)
|
||||
# Backup window hours below
|
||||
var.automated_backup_configuration.weekly_schedule.start_times.hours >= 0 &&
|
||||
var.automated_backup_configuration.weekly_schedule.start_times.hours <= 23 &&
|
||||
# Backup window day validation
|
||||
setintersection(["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"], var.automated_backup_configuration.weekly_schedule.days_of_week) == toset(var.automated_backup_configuration.weekly_schedule.days_of_week)
|
||||
) : true
|
||||
)
|
||||
error_message = "Days of week must contains one or more days with the following format 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'. You can only specify retention_count or retention_period."
|
||||
error_message = "Days of week must contains one or more days with the following format 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'. Backup window hour must be between 0 and 23. You can only specify retention_count or retention_period."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +67,7 @@ variable "client_connection_config" {
|
||||
require_connectors = optional(bool, false)
|
||||
ssl_config = optional(object({
|
||||
ssl_mode = string
|
||||
}), null)
|
||||
}))
|
||||
})
|
||||
default = null
|
||||
}
|
||||
@@ -99,19 +81,17 @@ variable "cluster_display_name" {
|
||||
variable "cluster_name" {
|
||||
description = "Name of the primary cluster."
|
||||
type = string
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "continuous_backup_configuration" {
|
||||
description = "Continuous backup settings for cluster."
|
||||
nullable = true
|
||||
type = object({
|
||||
enabled = optional(bool, false)
|
||||
enabled = optional(bool, true)
|
||||
recovery_window_days = optional(number, 14)
|
||||
})
|
||||
default = {
|
||||
enabled = true
|
||||
recovery_window_days = 14
|
||||
}
|
||||
nullable = false
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "cross_region_replication" {
|
||||
@@ -120,23 +100,29 @@ variable "cross_region_replication" {
|
||||
enabled = optional(bool, false)
|
||||
promote_secondary = optional(bool, false)
|
||||
switchover_mode = optional(bool, false)
|
||||
region = optional(string, null)
|
||||
secondary_cluster_display_name = optional(string, null)
|
||||
secondary_cluster_name = optional(string, null)
|
||||
secondary_instance_display_name = optional(string, null)
|
||||
secondary_instance_name = optional(string, null)
|
||||
region = optional(string)
|
||||
secondary_cluster_display_name = optional(string)
|
||||
secondary_cluster_name = optional(string)
|
||||
secondary_instance_display_name = optional(string)
|
||||
secondary_instance_name = optional(string)
|
||||
secondary_machine_config = optional(object({
|
||||
cpu_count = number
|
||||
}), null)
|
||||
cpu_count = number
|
||||
machine_type = optional(string)
|
||||
}))
|
||||
})
|
||||
default = {}
|
||||
default = {}
|
||||
nullable = false
|
||||
validation {
|
||||
condition = !var.cross_region_replication.enabled || var.cross_region_replication.enabled && var.cross_region_replication.region != null
|
||||
error_message = "Region must be available when cross region replication is enabled."
|
||||
}
|
||||
validation {
|
||||
condition = !(var.cross_region_replication.switchover_mode && var.cross_region_replication.promote_secondary)
|
||||
error_message = "Please choose to either promote secondary cluster or align an existing cluster after swtichover."
|
||||
error_message = "Please choose to either promote secondary cluster or align an existing cluster after switchover."
|
||||
}
|
||||
validation {
|
||||
condition = contains([2, 4, 8, 16, 32, 64, 96, 128], try(var.cross_region_replication.secondary_machine_config.cpu_count, 2))
|
||||
error_message = "The number of CPU's in the VM instance must be one of [2, 4, 8, 16, 32, 64, 96, 128]"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,10 +148,9 @@ variable "encryption_config" {
|
||||
description = "Set encryption configuration. KMS name format: 'projects/[PROJECT]/locations/[REGION]/keyRings/[RING]/cryptoKeys/[KEY_NAME]'."
|
||||
type = object({
|
||||
primary_kms_key_name = string
|
||||
secondary_kms_key_name = optional(string, null)
|
||||
secondary_kms_key_name = optional(string)
|
||||
})
|
||||
default = null
|
||||
nullable = true
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "flags" {
|
||||
@@ -183,7 +168,7 @@ variable "gce_zone" {
|
||||
variable "initial_user" {
|
||||
description = "AlloyDB cluster initial user credentials."
|
||||
type = object({
|
||||
user = optional(string, "root")
|
||||
user = optional(string, "postgres")
|
||||
password = string
|
||||
})
|
||||
default = null
|
||||
@@ -192,6 +177,7 @@ variable "initial_user" {
|
||||
variable "instance_name" {
|
||||
description = "Name of primary instance."
|
||||
type = string
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "labels" {
|
||||
@@ -203,16 +189,20 @@ variable "labels" {
|
||||
variable "location" {
|
||||
description = "Region or zone of the cluster and instance."
|
||||
type = string
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "machine_config" {
|
||||
description = "AlloyDB machine config."
|
||||
type = object({
|
||||
cpu_count = optional(number, 2)
|
||||
cpu_count = optional(number, 2)
|
||||
machine_type = optional(string)
|
||||
})
|
||||
nullable = false
|
||||
default = {
|
||||
cpu_count = 2
|
||||
default = {}
|
||||
validation {
|
||||
condition = contains([2, 4, 8, 16, 32, 64, 96, 128], var.machine_config.cpu_count)
|
||||
error_message = "The number of CPU's in the VM instance must be one of [2, 4, 8, 16, 32, 64, 96, 128]"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,37 +212,22 @@ variable "maintenance_config" {
|
||||
enabled = optional(bool, false)
|
||||
day = optional(string, "SUNDAY")
|
||||
start_time = optional(object({
|
||||
hours = optional(number, 23)
|
||||
minutes = optional(number, 0)
|
||||
seconds = optional(number, 0)
|
||||
nanos = optional(number, 0)
|
||||
hours = optional(number, 23)
|
||||
}), {})
|
||||
})
|
||||
default = {
|
||||
enabled = false
|
||||
day = "SUNDAY"
|
||||
start_time = {
|
||||
hours = 23
|
||||
minutes = 0
|
||||
seconds = 0
|
||||
nanos = 0
|
||||
}
|
||||
}
|
||||
default = {}
|
||||
validation {
|
||||
condition = (
|
||||
var.maintenance_config.enabled ? (
|
||||
# Maintenance window validation below
|
||||
var.maintenance_config.start_time.hours >= 0 &&
|
||||
var.maintenance_config.start_time.hours <= 23 &&
|
||||
var.maintenance_config.start_time.minutes == 0 &&
|
||||
var.maintenance_config.start_time.seconds == 0 &&
|
||||
var.maintenance_config.start_time.nanos == 0 &&
|
||||
# Maintenance window day validation
|
||||
contains([
|
||||
"MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"
|
||||
], var.maintenance_config.day)) : true
|
||||
)
|
||||
error_message = "Maintenance window day must one of 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'. Maintenance window hour must be between 0 and 23 and maintenance window minutes, seconds and nanos should be 0."
|
||||
error_message = "Maintenance window day must one of 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'. Maintenance window hour must be between 0 and 23."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,28 +235,20 @@ variable "network_config" {
|
||||
description = "Network configuration for cluster and instance. Only one between psa_config and psc_config can be used."
|
||||
type = object({
|
||||
psa_config = optional(object({
|
||||
network = optional(string)
|
||||
network = string
|
||||
allocated_ip_range = optional(string)
|
||||
authorized_external_networks = optional(list(string), [])
|
||||
enable_public_ip = optional(bool, false)
|
||||
enable_outbound_public_ip = optional(bool, false)
|
||||
}))
|
||||
psc_config = optional(object({
|
||||
allowed_consumer_projects = optional(list(string), [])
|
||||
}), null)
|
||||
allowed_consumer_projects = list(string)
|
||||
}))
|
||||
})
|
||||
nullable = false
|
||||
validation {
|
||||
condition = (
|
||||
var.network_config.psa_config == null || (
|
||||
(
|
||||
try(var.network_config.psa_config.enable_public_ip, false) &&
|
||||
try(length(var.network_config.psa_config.authorized_external_networks), 0) > 0
|
||||
) || (
|
||||
try(length(var.network_config.psa_config.authorized_external_networks), 0) == 0
|
||||
)
|
||||
)
|
||||
)
|
||||
error_message = "A list of external network authorized to access this instance is required only in case public ip is enabled for the instance."
|
||||
condition = try(length(var.network_config.psa_config.authorized_external_networks) > 0, false) ? try(var.network_config.psa_config.enable_public_ip, false) : true
|
||||
error_message = "A list of external network authorized to access this instance is required only in case public IP is enabled for the instance."
|
||||
}
|
||||
validation {
|
||||
condition = (var.network_config.psc_config == null) != (var.network_config.psa_config == null)
|
||||
@@ -318,12 +285,64 @@ variable "query_insights_config" {
|
||||
record_client_address = optional(bool, true)
|
||||
query_plans_per_minute = optional(number, 5)
|
||||
})
|
||||
default = {
|
||||
query_string_length = 1024
|
||||
record_application_tags = true
|
||||
record_client_address = true
|
||||
query_plans_per_minute = 5
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "read_pool" {
|
||||
description = "Map of read pool instances to create in the primary cluster."
|
||||
type = map(object({
|
||||
display_name = optional(string)
|
||||
node_count = optional(number, 1)
|
||||
flags = optional(map(string))
|
||||
client_connection_config = optional(object({
|
||||
require_connectors = optional(bool, false)
|
||||
ssl_config = optional(object({
|
||||
ssl_mode = string
|
||||
}))
|
||||
}))
|
||||
machine_config = optional(object({
|
||||
cpu_count = optional(number, 2)
|
||||
machine_type = optional(string)
|
||||
}), {})
|
||||
network_config = optional(object({
|
||||
authorized_external_networks = optional(list(string), [])
|
||||
enable_public_ip = optional(bool, false)
|
||||
}), {})
|
||||
query_insights_config = optional(object({
|
||||
query_string_length = optional(number, 1024)
|
||||
record_application_tags = optional(bool, true)
|
||||
record_client_address = optional(bool, true)
|
||||
query_plans_per_minute = optional(number, 5)
|
||||
}))
|
||||
}))
|
||||
nullable = false
|
||||
default = {}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for k, v in var.read_pool :
|
||||
contains([2, 4, 8, 16, 32, 64, 96, 128], v.machine_config.cpu_count)
|
||||
])
|
||||
error_message = "The number of CPU's in the VM instance must be one of [2, 4, 8, 16, 32, 64, 96, 128]"
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for k, v in var.read_pool :
|
||||
try(length(v.network_config.psa_config.authorized_external_networks) > 0, false) ? try(v.network_config.psa_config.enable_public_ip, false) : true
|
||||
])
|
||||
error_message = "A list of external network authorized to access this replica pool instance is required only in case public IP is enabled for the replica pool instance."
|
||||
}
|
||||
}
|
||||
|
||||
variable "skip_await_major_version_upgrade" {
|
||||
description = "Set to true to skip awaiting on the major version upgrade of the cluster."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "subscription_type" {
|
||||
description = "The subscription type of cluster. Possible values are: 'STANDARD' or 'TRIAL'."
|
||||
type = string
|
||||
default = "STANDARD"
|
||||
}
|
||||
|
||||
variable "tag_bindings" {
|
||||
@@ -338,14 +357,15 @@ variable "users" {
|
||||
type = map(object({
|
||||
password = optional(string)
|
||||
roles = optional(list(string), ["alloydbsuperuser"])
|
||||
type = optional(string)
|
||||
type = optional(string, "ALLOYDB_BUILT_IN")
|
||||
}))
|
||||
default = null
|
||||
nullable = false
|
||||
default = {}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for user in coalesce(var.users, {}) :
|
||||
try(contains(["ALLOYDB_BUILT_IN", "ALLOYDB_IAM_USER"], user.type), true)
|
||||
for user in var.users :
|
||||
contains(["ALLOYDB_BUILT_IN", "ALLOYDB_IAM_USER"], user.type)
|
||||
])
|
||||
error_message = "User type must one of 'ALLOYDB_BUILT_IN', 'ALLOYDB_IAM_USER'"
|
||||
error_message = "User type must one of 'ALLOYDB_BUILT_IN', 'ALLOYDB_IAM_USER'."
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user