Merge branch 'master' into fast-dev

This commit is contained in:
Julio Castillo
2025-05-09 14:23:43 +03:00
10 changed files with 641 additions and 347 deletions

View File

@@ -12,6 +12,7 @@ Note that this module assumes that some options are the same for both the primar
* [AlloyDB module](#alloydb-module)
* [Examples](#examples)
* [Simple example](#simple-example)
* [Read pool](#read-pool)
* [Cross region replication](#cross-region-replication)
* [PSC instance](#psc-instance)
* [Custom flags and users definition](#custom-flags-and-users-definition)
@@ -71,6 +72,33 @@ module "alloydb" {
# tftest modules=3 resources=17 inventory=simple.yaml e2e
```
### Read pool
One node read pool instance is always zonal, two or more nodes make the instance always regional. By default a read pool instance has one node.
```hcl
module "alloydb" {
source = "./fabric/modules/alloydb"
project_id = var.project_id
project_number = var.project_number
cluster_name = "db"
location = var.region
instance_name = "db"
network_config = {
psa_config = {
network = var.vpc.id
}
}
read_pool = {
"zonal-read-pool" = {}
"regional-read-pool" = {
node_count = 2
}
}
}
# tftest modules=1 resources=4 inventory=read_pool.yaml e2e
```
### Cross region replication
```hcl
@@ -98,7 +126,7 @@ In a cross-region replication scenario (like in the previous example) this modul
* [promoting the secondary instance](https://cloud.google.com/alloydb/docs/cross-region-replication/work-with-cross-region-replication#promote-secondary-cluster) to become a primary instance via the `var.cross_region_replication.promote_secondary` flag.
* [promoting the secondary instance](https://cloud.google.com/alloydb/docs/cross-region-replication/work-with-cross-region-replication#promote-secondary-cluster) to become a primary instance via the `var.cross_region_replication.promote_secondary` flag.
* aligning an existing cluster after switchover via the `var.cross_region_replication.switchover_mode` flag.
### PSC instance
@@ -266,50 +294,63 @@ module "alloydb" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [cluster_name](variables.tf#L99) | Name of the primary cluster. | <code>string</code> | ✓ | |
| [instance_name](variables.tf#L192) | Name of primary instance. | <code>string</code> | ✓ | |
| [location](variables.tf#L203) | Region or zone of the cluster and instance. | <code>string</code> | ✓ | |
| [network_config](variables.tf#L259) | Network configuration for cluster and instance. Only one between psa_config and psc_config can be used. | <code title="object&#40;&#123;&#10; psa_config &#61; optional&#40;object&#40;&#123;&#10; network &#61; optional&#40;string&#41;&#10; allocated_ip_range &#61; optional&#40;string&#41;&#10; authorized_external_networks &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; enable_public_ip &#61; optional&#40;bool, false&#41;&#10; &#125;&#41;&#41;&#10; psc_config &#61; optional&#40;object&#40;&#123;&#10; allowed_consumer_projects &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; &#125;&#41;, null&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [project_id](variables.tf#L302) | The ID of the project where this instances will be created. | <code>string</code> | ✓ | |
| [cluster_name](variables.tf#L81) | Name of the primary cluster. | <code>string</code> | ✓ | |
| [instance_name](variables.tf#L177) | Name of primary instance. | <code>string</code> | ✓ | |
| [location](variables.tf#L189) | Region or zone of the cluster and instance. | <code>string</code> | ✓ | |
| [network_config](variables.tf#L234) | Network configuration for cluster and instance. Only one between psa_config and psc_config can be used. | <code title="object&#40;&#123;&#10; psa_config &#61; optional&#40;object&#40;&#123;&#10; network &#61; string&#10; allocated_ip_range &#61; optional&#40;string&#41;&#10; authorized_external_networks &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; enable_public_ip &#61; optional&#40;bool, false&#41;&#10; enable_outbound_public_ip &#61; optional&#40;bool, false&#41;&#10; &#125;&#41;&#41;&#10; psc_config &#61; optional&#40;object&#40;&#123;&#10; allowed_consumer_projects &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [project_id](variables.tf#L269) | The ID of the project where this instances will be created. | <code>string</code> | ✓ | |
| [annotations](variables.tf#L17) | Map FLAG_NAME=>VALUE for annotations which allow client tools to store small amount of arbitrary data. | <code>map&#40;string&#41;</code> | | <code>null</code> |
| [automated_backup_configuration](variables.tf#L23) | Automated backup settings for cluster. | <code title="object&#40;&#123;&#10; enabled &#61; optional&#40;bool, false&#41;&#10; backup_window &#61; optional&#40;string, &#34;1800s&#34;&#41;&#10; location &#61; optional&#40;string&#41;&#10; weekly_schedule &#61; optional&#40;object&#40;&#123;&#10; days_of_week &#61; optional&#40;list&#40;string&#41;, &#91;&#10; &#34;MONDAY&#34;, &#34;TUESDAY&#34;, &#34;WEDNESDAY&#34;, &#34;THURSDAY&#34;, &#34;FRIDAY&#34;, &#34;SATURDAY&#34;, &#34;SUNDAY&#34;&#10; &#93;&#41;&#10; start_times &#61; optional&#40;object&#40;&#123;&#10; hours &#61; optional&#40;number, 23&#41;&#10; minutes &#61; optional&#40;number, 0&#41;&#10; seconds &#61; optional&#40;number, 0&#41;&#10; nanos &#61; optional&#40;number, 0&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; retention_count &#61; optional&#40;number, 7&#41;&#10; retention_period &#61; optional&#40;string, null&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; enabled &#61; false&#10; backup_window &#61; &#34;1800s&#34;&#10; location &#61; null&#10; weekly_schedule &#61; &#123;&#10; days_of_week &#61; &#91;&#34;MONDAY&#34;, &#34;TUESDAY&#34;, &#34;WEDNESDAY&#34;, &#34;THURSDAY&#34;, &#34;FRIDAY&#34;, &#34;SATURDAY&#34;, &#34;SUNDAY&#34;&#93;&#10; start_times &#61; &#123;&#10; hours &#61; 23&#10; minutes &#61; 0&#10; seconds &#61; 0&#10; nanos &#61; 0&#10; &#125;&#10; &#125;&#10; retention_count &#61; 7&#10; retention_period &#61; null&#10;&#125;">&#123;&#8230;&#125;</code> |
| [availability_type](variables.tf#L76) | Availability type for the primary replica. Either `ZONAL` or `REGIONAL`. | <code>string</code> | | <code>&#34;REGIONAL&#34;</code> |
| [client_connection_config](variables.tf#L82) | Client connection config. | <code title="object&#40;&#123;&#10; require_connectors &#61; optional&#40;bool, false&#41;&#10; ssl_config &#61; optional&#40;object&#40;&#123;&#10; ssl_mode &#61; string&#10; &#125;&#41;, null&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [cluster_display_name](variables.tf#L93) | Display name of the primary cluster. | <code>string</code> | | <code>null</code> |
| [continuous_backup_configuration](variables.tf#L104) | Continuous backup settings for cluster. | <code title="object&#40;&#123;&#10; enabled &#61; optional&#40;bool, false&#41;&#10; recovery_window_days &#61; optional&#40;number, 14&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; enabled &#61; true&#10; recovery_window_days &#61; 14&#10;&#125;">&#123;&#8230;&#125;</code> |
| [cross_region_replication](variables.tf#L117) | Cross region replication config. | <code title="object&#40;&#123;&#10; enabled &#61; optional&#40;bool, false&#41;&#10; promote_secondary &#61; optional&#40;bool, false&#41;&#10; switchover_mode &#61; optional&#40;bool, false&#41;&#10; region &#61; optional&#40;string, null&#41;&#10; secondary_cluster_display_name &#61; optional&#40;string, null&#41;&#10; secondary_cluster_name &#61; optional&#40;string, null&#41;&#10; secondary_instance_display_name &#61; optional&#40;string, null&#41;&#10; secondary_instance_name &#61; optional&#40;string, null&#41;&#10; secondary_machine_config &#61; optional&#40;object&#40;&#123;&#10; cpu_count &#61; number&#10; &#125;&#41;, null&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [database_version](variables.tf#L143) | Database type and version to create. | <code>string</code> | | <code>&#34;POSTGRES_15&#34;</code> |
| [deletion_policy](variables.tf#L149) | AlloyDB cluster and instance deletion policy. | <code>string</code> | | <code>null</code> |
| [display_name](variables.tf#L155) | AlloyDB instance display name. | <code>string</code> | | <code>null</code> |
| [encryption_config](variables.tf#L161) | Set encryption configuration. KMS name format: 'projects/[PROJECT]/locations/[REGION]/keyRings/[RING]/cryptoKeys/[KEY_NAME]'. | <code title="object&#40;&#123;&#10; primary_kms_key_name &#61; string&#10; secondary_kms_key_name &#61; optional&#40;string, null&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [flags](variables.tf#L171) | Map FLAG_NAME=>VALUE for database-specific tuning. | <code>map&#40;string&#41;</code> | | <code>null</code> |
| [gce_zone](variables.tf#L177) | The GCE zone that the instance should serve from. This can ONLY be specified for ZONAL instances. If present for a REGIONAL instance, an error will be thrown. | <code>string</code> | | <code>null</code> |
| [initial_user](variables.tf#L183) | AlloyDB cluster initial user credentials. | <code title="object&#40;&#123;&#10; user &#61; optional&#40;string, &#34;root&#34;&#41;&#10; password &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [labels](variables.tf#L197) | Labels to be attached to all instances. | <code>map&#40;string&#41;</code> | | <code>null</code> |
| [machine_config](variables.tf#L208) | AlloyDB machine config. | <code title="object&#40;&#123;&#10; cpu_count &#61; optional&#40;number, 2&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; cpu_count &#61; 2&#10;&#125;">&#123;&#8230;&#125;</code> |
| [maintenance_config](variables.tf#L219) | Set maintenance window configuration. | <code title="object&#40;&#123;&#10; enabled &#61; optional&#40;bool, false&#41;&#10; day &#61; optional&#40;string, &#34;SUNDAY&#34;&#41;&#10; start_time &#61; optional&#40;object&#40;&#123;&#10; hours &#61; optional&#40;number, 23&#41;&#10; minutes &#61; optional&#40;number, 0&#41;&#10; seconds &#61; optional&#40;number, 0&#41;&#10; nanos &#61; optional&#40;number, 0&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; enabled &#61; false&#10; day &#61; &#34;SUNDAY&#34;&#10; start_time &#61; &#123;&#10; hours &#61; 23&#10; minutes &#61; 0&#10; seconds &#61; 0&#10; nanos &#61; 0&#10; &#125;&#10;&#125;">&#123;&#8230;&#125;</code> |
| [prefix](variables.tf#L292) | Optional prefix used to generate instance names. | <code>string</code> | | <code>null</code> |
| [project_number](variables.tf#L307) | The project number of the project where this instances will be created. Only used for testing purposes. | <code>string</code> | | <code>null</code> |
| [query_insights_config](variables.tf#L313) | Query insights config. | <code title="object&#40;&#123;&#10; query_string_length &#61; optional&#40;number, 1024&#41;&#10; record_application_tags &#61; optional&#40;bool, true&#41;&#10; record_client_address &#61; optional&#40;bool, true&#41;&#10; query_plans_per_minute &#61; optional&#40;number, 5&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; query_string_length &#61; 1024&#10; record_application_tags &#61; true&#10; record_client_address &#61; true&#10; query_plans_per_minute &#61; 5&#10;&#125;">&#123;&#8230;&#125;</code> |
| [tag_bindings](variables.tf#L329) | Tag bindings for this service, in key => tag value id format. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [users](variables.tf#L336) | Map of users to create in the primary instance (and replicated to other replicas). Set PASSWORD to null if you want to get an autogenerated password. The user types available are: 'ALLOYDB_BUILT_IN' or 'ALLOYDB_IAM_USER'. | <code title="map&#40;object&#40;&#123;&#10; password &#61; optional&#40;string&#41;&#10; roles &#61; optional&#40;list&#40;string&#41;, &#91;&#34;alloydbsuperuser&#34;&#93;&#41;&#10; type &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>null</code> |
| [automated_backup_configuration](variables.tf#L23) | Automated backup settings for cluster. | <code title="object&#40;&#123;&#10; enabled &#61; optional&#40;bool, false&#41;&#10; backup_window &#61; optional&#40;string, &#34;1800s&#34;&#41;&#10; location &#61; optional&#40;string&#41;&#10; weekly_schedule &#61; optional&#40;object&#40;&#123;&#10; days_of_week &#61; optional&#40;list&#40;string&#41;, &#91;&#10; &#34;MONDAY&#34;, &#34;TUESDAY&#34;, &#34;WEDNESDAY&#34;, &#34;THURSDAY&#34;, &#34;FRIDAY&#34;, &#34;SATURDAY&#34;, &#34;SUNDAY&#34;&#10; &#93;&#41;&#10; start_times &#61; optional&#40;object&#40;&#123;&#10; hours &#61; optional&#40;number, 23&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; retention_count &#61; optional&#40;number, 7&#41;&#10; retention_period &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [availability_type](variables.tf#L58) | Availability type for the primary replica. Either `ZONAL` or `REGIONAL`. | <code>string</code> | | <code>&#34;REGIONAL&#34;</code> |
| [client_connection_config](variables.tf#L64) | Client connection config. | <code title="object&#40;&#123;&#10; require_connectors &#61; optional&#40;bool, false&#41;&#10; ssl_config &#61; optional&#40;object&#40;&#123;&#10; ssl_mode &#61; string&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [cluster_display_name](variables.tf#L75) | Display name of the primary cluster. | <code>string</code> | | <code>null</code> |
| [continuous_backup_configuration](variables.tf#L87) | Continuous backup settings for cluster. | <code title="object&#40;&#123;&#10; enabled &#61; optional&#40;bool, true&#41;&#10; recovery_window_days &#61; optional&#40;number, 14&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [cross_region_replication](variables.tf#L97) | Cross region replication config. | <code title="object&#40;&#123;&#10; enabled &#61; optional&#40;bool, false&#41;&#10; promote_secondary &#61; optional&#40;bool, false&#41;&#10; switchover_mode &#61; optional&#40;bool, false&#41;&#10; region &#61; optional&#40;string&#41;&#10; secondary_cluster_display_name &#61; optional&#40;string&#41;&#10; secondary_cluster_name &#61; optional&#40;string&#41;&#10; secondary_instance_display_name &#61; optional&#40;string&#41;&#10; secondary_instance_name &#61; optional&#40;string&#41;&#10; secondary_machine_config &#61; optional&#40;object&#40;&#123;&#10; cpu_count &#61; number&#10; machine_type &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [database_version](variables.tf#L129) | Database type and version to create. | <code>string</code> | | <code>&#34;POSTGRES_15&#34;</code> |
| [deletion_policy](variables.tf#L135) | AlloyDB cluster and instance deletion policy. | <code>string</code> | | <code>null</code> |
| [display_name](variables.tf#L141) | AlloyDB instance display name. | <code>string</code> | | <code>null</code> |
| [encryption_config](variables.tf#L147) | Set encryption configuration. KMS name format: 'projects/[PROJECT]/locations/[REGION]/keyRings/[RING]/cryptoKeys/[KEY_NAME]'. | <code title="object&#40;&#123;&#10; primary_kms_key_name &#61; string&#10; secondary_kms_key_name &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [flags](variables.tf#L156) | Map FLAG_NAME=>VALUE for database-specific tuning. | <code>map&#40;string&#41;</code> | | <code>null</code> |
| [gce_zone](variables.tf#L162) | The GCE zone that the instance should serve from. This can ONLY be specified for ZONAL instances. If present for a REGIONAL instance, an error will be thrown. | <code>string</code> | | <code>null</code> |
| [initial_user](variables.tf#L168) | AlloyDB cluster initial user credentials. | <code title="object&#40;&#123;&#10; user &#61; optional&#40;string, &#34;postgres&#34;&#41;&#10; password &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [labels](variables.tf#L183) | Labels to be attached to all instances. | <code>map&#40;string&#41;</code> | | <code>null</code> |
| [machine_config](variables.tf#L195) | AlloyDB machine config. | <code title="object&#40;&#123;&#10; cpu_count &#61; optional&#40;number, 2&#41;&#10; machine_type &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [maintenance_config](variables.tf#L209) | Set maintenance window configuration. | <code title="object&#40;&#123;&#10; enabled &#61; optional&#40;bool, false&#41;&#10; day &#61; optional&#40;string, &#34;SUNDAY&#34;&#41;&#10; start_time &#61; optional&#40;object&#40;&#123;&#10; hours &#61; optional&#40;number, 23&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [prefix](variables.tf#L259) | Optional prefix used to generate instance names. | <code>string</code> | | <code>null</code> |
| [project_number](variables.tf#L274) | The project number of the project where this instances will be created. Only used for testing purposes. | <code>string</code> | | <code>null</code> |
| [query_insights_config](variables.tf#L280) | Query insights config. | <code title="object&#40;&#123;&#10; query_string_length &#61; optional&#40;number, 1024&#41;&#10; record_application_tags &#61; optional&#40;bool, true&#41;&#10; record_client_address &#61; optional&#40;bool, true&#41;&#10; query_plans_per_minute &#61; optional&#40;number, 5&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [read_pool](variables.tf#L291) | Map of read pool instances to create in the primary cluster. | <code title="map&#40;object&#40;&#123;&#10; display_name &#61; optional&#40;string&#41;&#10; node_count &#61; optional&#40;number, 1&#41;&#10; flags &#61; optional&#40;map&#40;string&#41;&#41;&#10; client_connection_config &#61; optional&#40;object&#40;&#123;&#10; require_connectors &#61; optional&#40;bool, false&#41;&#10; ssl_config &#61; optional&#40;object&#40;&#123;&#10; ssl_mode &#61; string&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#41;&#10; machine_config &#61; optional&#40;object&#40;&#123;&#10; cpu_count &#61; optional&#40;number, 2&#41;&#10; machine_type &#61; optional&#40;string&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; network_config &#61; optional&#40;object&#40;&#123;&#10; authorized_external_networks &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; enable_public_ip &#61; optional&#40;bool, false&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; query_insights_config &#61; optional&#40;object&#40;&#123;&#10; query_string_length &#61; optional&#40;number, 1024&#41;&#10; record_application_tags &#61; optional&#40;bool, true&#41;&#10; record_client_address &#61; optional&#40;bool, true&#41;&#10; query_plans_per_minute &#61; optional&#40;number, 5&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [skip_await_major_version_upgrade](variables.tf#L336) | Set to true to skip awaiting on the major version upgrade of the cluster. | <code>bool</code> | | <code>true</code> |
| [subscription_type](variables.tf#L342) | The subscription type of cluster. Possible values are: 'STANDARD' or 'TRIAL'. | <code>string</code> | | <code>&#34;STANDARD&#34;</code> |
| [tag_bindings](variables.tf#L348) | Tag bindings for this service, in key => tag value id format. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [users](variables.tf#L355) | Map of users to create in the primary instance (and replicated to other replicas). Set PASSWORD to null if you want to get an autogenerated password. The user types available are: 'ALLOYDB_BUILT_IN' or 'ALLOYDB_IAM_USER'. | <code title="map&#40;object&#40;&#123;&#10; password &#61; optional&#40;string&#41;&#10; roles &#61; optional&#40;list&#40;string&#41;, &#91;&#34;alloydbsuperuser&#34;&#93;&#41;&#10; type &#61; optional&#40;string, &#34;ALLOYDB_BUILT_IN&#34;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
## Outputs
| name | description | sensitive |
|---|---|:---:|
| [id](outputs.tf#L24) | Fully qualified primary instance id. | |
| [ids](outputs.tf#L29) | Fully qualified ids of all instances. | |
| [instances](outputs.tf#L37) | AlloyDB instance resources. | |
| [ip](outputs.tf#L43) | IP address of the primary instance. | |
| [ips](outputs.tf#L48) | IP addresses of all instances. | |
| [name](outputs.tf#L55) | Name of the primary instance. | |
| [names](outputs.tf#L60) | Names of all instances. | |
| [psc_dns_name](outputs.tf#L68) | AlloyDB Primary instance PSC DNS name. | |
| [psc_dns_names](outputs.tf#L73) | AlloyDB instances PSC DNS names. | |
| [secondary_id](outputs.tf#L80) | Fully qualified primary instance id. | |
| [secondary_ip](outputs.tf#L85) | IP address of the primary instance. | |
| [service_attachment](outputs.tf#L90) | AlloyDB Primary instance service attachment. | |
| [service_attachments](outputs.tf#L95) | AlloyDB instances service attachment. | |
| [user_passwords](outputs.tf#L102) | Map of containing the password of all users created through terraform. | |
| [cluster_id](outputs.tf#L24) | Fully qualified primary cluster id. | |
| [cluster_name](outputs.tf#L29) | Name of the primary cluster. | |
| [id](outputs.tf#L34) | Fully qualified primary instance id. | |
| [ids](outputs.tf#L39) | Fully qualified ids of all instances. | |
| [instances](outputs.tf#L47) | AlloyDB instance resources. | |
| [ip](outputs.tf#L53) | IP address of the primary instance. | |
| [ips](outputs.tf#L58) | IP addresses of all instances. | |
| [name](outputs.tf#L65) | Name of the primary instance. | |
| [names](outputs.tf#L70) | Names of all instances. | |
| [outbound_public_ips](outputs.tf#L78) | Public IP addresses of the primary instance. | |
| [psc_dns_name](outputs.tf#L83) | AlloyDB Primary instance PSC DNS name. | |
| [psc_dns_names](outputs.tf#L88) | AlloyDB instances PSC DNS names. | |
| [public_ip](outputs.tf#L95) | Public IP address of the primary instance. | |
| [read_pool_ids](outputs.tf#L100) | Fully qualified ids of all read poll instances. | |
| [read_pool_ips](outputs.tf#L108) | IP addresses of all read poll instances. | |
| [secondary_cluster_id](outputs.tf#L116) | Fully qualified secondary cluster id. | |
| [secondary_cluster_name](outputs.tf#L121) | Name of the secondary cluster. | |
| [secondary_id](outputs.tf#L126) | Fully qualified secondary instance id. | |
| [secondary_ip](outputs.tf#L131) | IP address of the secondary instance. | |
| [secondary_outbound_public_ips](outputs.tf#L136) | Public IP addresses of the primary instance. | |
| [secondary_public_ip](outputs.tf#L141) | Public IP address of the secondary instance. | |
| [service_attachment](outputs.tf#L146) | AlloyDB Primary instance service attachment. | |
| [service_attachments](outputs.tf#L151) | AlloyDB instances service attachment. | |
| [user_passwords](outputs.tf#L158) | Map of containing the password of all users created through terraform. | ✓ |
<!-- END TFDOC -->

View File

@@ -17,42 +17,63 @@
locals {
prefix = var.prefix == null ? "" : "${var.prefix}-"
is_regional = var.availability_type == "REGIONAL"
# secondary instance type is aligned with cluster type unless apply is targeting a promotion, in that
# case cluster will be 'primary' while instance still 'secondary'.
require_connectors = try(var.client_connection_config.require_connectors, false) ? true : null
ssl_mode = try(var.client_connection_config.ssl_config.ssl_mode, null)
has_public_ip = try(var.network_config.psa_config.enable_public_ip, false) || try(var.network_config.psa_config.enable_outbound_public_ip, false)
authorized_external_networks = toset(try(var.network_config.psa_config.authorized_external_networks, []))
enable_public_ip = try(var.network_config.psa_config.enable_public_ip, false) ? true : null
enable_outbound_public_ip = try(var.network_config.psa_config.enable_outbound_public_ip, false) ? true : null
allowed_consumer_projects = try(var.network_config.psc_config.allowed_consumer_projects, [])
primary_cluster_name = "${local.prefix}${var.cluster_name}"
primary_instance_name = "${local.prefix}${var.instance_name}"
primary_kms_key_name = try(var.encryption_config.primary_kms_key_name, null)
secondary_cluster_name = coalesce(var.cross_region_replication.secondary_cluster_name, "${var.cluster_name}-sec")
secondary_instance_name = coalesce(var.cross_region_replication.secondary_instance_name, "${var.instance_name}-sec")
secondary_kms_key_name = try(var.encryption_config.secondary_kms_key_name, null)
# secondary instance type is aligned with cluster type unless apply is targeting a promotion, in that
# case cluster will be 'primary' while instance still 'secondary'.
secondary_instance_type = try(
var.cross_region_replication.promote_secondary && google_alloydb_cluster.secondary[0].cluster_type == "SECONDARY"
? "SECONDARY"
: google_alloydb_cluster.secondary[0].cluster_type, null
)
users = {
for k, v in coalesce(var.users, {}) :
k => {
name = k
password = try(v.type, "ALLOYDB_BUILT_IN") == "ALLOYDB_BUILT_IN" ? try(random_password.passwords[k].result, v.password) : null
roles = v.roles
type = coalesce(v.type, "ALLOYDB_BUILT_IN")
}
secondary_machine_type = (
try(var.cross_region_replication.secondary_machine_config.machine_type, null) != null
? var.cross_region_replication.secondary_machine_config.machine_type
: var.machine_config.machine_type
)
read_pool = {
for name, instance in var.read_pool : name => merge(instance, {
require_connectors = try(instance.client_connection_config.require_connectors, false) ? true : null
ssl_mode = try(instance.client_connection_config.ssl_config.ssl_mode, null)
})
}
}
resource "google_alloydb_cluster" "primary" {
project = var.project_id
annotations = var.annotations
cluster_id = local.primary_cluster_name
cluster_type = var.cross_region_replication.switchover_mode ? "SECONDARY" : "PRIMARY"
database_version = var.database_version
deletion_policy = var.deletion_policy
display_name = coalesce(var.cluster_display_name, local.primary_cluster_name)
labels = var.labels
location = var.location
project = var.project_id
annotations = var.annotations
cluster_id = local.primary_cluster_name
cluster_type = var.cross_region_replication.switchover_mode ? "SECONDARY" : "PRIMARY"
database_version = var.database_version
deletion_policy = var.deletion_policy
display_name = coalesce(var.cluster_display_name, local.primary_cluster_name)
labels = var.labels
location = var.location
skip_await_major_version_upgrade = var.skip_await_major_version_upgrade
subscription_type = var.subscription_type
network_config {
network = try(var.network_config.psa_config.network, null)
allocated_ip_range = try(var.network_config.psa_config.allocated_ip_range, null)
# network_config block should exist only when PSA VPC resource link is present to prevent Terraform state drift
dynamic "network_config" {
for_each = var.network_config.psa_config != null ? [""] : []
content {
network = var.network_config.psa_config.network
allocated_ip_range = var.network_config.psa_config.allocated_ip_range
}
}
dynamic "automated_backup_policy" {
@@ -64,9 +85,9 @@ resource "google_alloydb_cluster" "primary" {
labels = var.labels
dynamic "encryption_config" {
for_each = var.encryption_config != null ? [""] : []
for_each = local.primary_kms_key_name != null ? [""] : []
content {
kms_key_name = var.encryption_config.primary_kms_key_name
kms_key_name = local.primary_kms_key_name
}
}
@@ -74,9 +95,9 @@ resource "google_alloydb_cluster" "primary" {
days_of_week = var.automated_backup_configuration.weekly_schedule.days_of_week
start_times {
hours = var.automated_backup_configuration.weekly_schedule.start_times.hours
minutes = var.automated_backup_configuration.weekly_schedule.start_times.minutes
seconds = var.automated_backup_configuration.weekly_schedule.start_times.seconds
nanos = var.automated_backup_configuration.weekly_schedule.start_times.nanos
minutes = 0
seconds = 0
nanos = 0
}
}
@@ -96,24 +117,21 @@ resource "google_alloydb_cluster" "primary" {
}
}
dynamic "continuous_backup_config" {
for_each = var.continuous_backup_configuration.enabled ? [""] : []
content {
enabled = true
recovery_window_days = var.continuous_backup_configuration.recovery_window_days
dynamic "encryption_config" {
for_each = var.encryption_config != null ? [""] : []
content {
kms_key_name = var.encryption_config.primary_kms_key_name
}
continuous_backup_config {
enabled = var.continuous_backup_configuration.enabled
recovery_window_days = var.continuous_backup_configuration.recovery_window_days
dynamic "encryption_config" {
for_each = local.primary_kms_key_name != null ? [""] : []
content {
kms_key_name = local.primary_kms_key_name
}
}
}
dynamic "encryption_config" {
for_each = var.encryption_config != null ? [""] : []
for_each = local.primary_kms_key_name != null ? [""] : []
content {
kms_key_name = var.encryption_config.primary_kms_key_name
kms_key_name = local.primary_kms_key_name
}
}
@@ -132,16 +150,20 @@ resource "google_alloydb_cluster" "primary" {
day = var.maintenance_config.day
start_time {
hours = var.maintenance_config.start_time.hours
minutes = var.maintenance_config.start_time.minutes
seconds = var.maintenance_config.start_time.seconds
nanos = var.maintenance_config.start_time.nanos
minutes = 0
seconds = 0
nanos = 0
}
}
}
}
psc_config {
psc_enabled = var.network_config.psc_config != null ? true : null
# psc_config block should exist only when PSC is enabled to prevent Terraform state drift
dynamic "psc_config" {
for_each = length(local.allowed_consumer_projects) > 0 ? [""] : []
content {
psc_enabled = true
}
}
dynamic "secondary_config" {
@@ -155,8 +177,6 @@ resource "google_alloydb_cluster" "primary" {
lifecycle {
ignore_changes = [
display_name,
network_config,
psc_config
]
}
}
@@ -173,42 +193,43 @@ resource "google_alloydb_instance" "primary" {
labels = var.labels
dynamic "client_connection_config" {
for_each = var.client_connection_config != null ? [""] : []
for_each = local.require_connectors != null || local.ssl_mode != null ? [""] : []
content {
require_connectors = var.client_connection_config.require_connectors
require_connectors = local.require_connectors
dynamic "ssl_config" {
for_each = var.client_connection_config.ssl_config != null ? [""] : []
for_each = local.ssl_mode != null ? [""] : []
content {
ssl_mode = var.client_connection_config.ssl_config.ssl_mode
ssl_mode = local.ssl_mode
}
}
}
}
dynamic "machine_config" {
for_each = var.machine_config != null ? [""] : []
content {
cpu_count = var.machine_config.cpu_count
}
machine_config {
cpu_count = var.machine_config.cpu_count
machine_type = var.machine_config.machine_type
}
# network_config block should exist only when (outbound) public IP is enabled to prevent Terraform state drift
dynamic "network_config" {
for_each = var.network_config.psa_config != null ? [""] : []
for_each = local.has_public_ip ? [""] : []
content {
dynamic "authorized_external_networks" {
for_each = coalesce(var.network_config.psa_config.authorized_external_networks, [])
for_each = local.authorized_external_networks
content {
cidr_range = authorized_external_networks.value
}
}
enable_public_ip = var.network_config.psa_config.enable_public_ip
enable_public_ip = local.enable_public_ip
enable_outbound_public_ip = local.enable_outbound_public_ip
}
}
# psc_instance_config block should exist only when there are PSC allowed consumer projects to prevent Terraform state drift
dynamic "psc_instance_config" {
for_each = var.network_config.psc_config != null ? [""] : []
for_each = length(local.allowed_consumer_projects) > 0 ? [""] : []
content {
allowed_consumer_projects = var.network_config.psc_config.allowed_consumer_projects
allowed_consumer_projects = local.allowed_consumer_projects
}
}
@@ -221,30 +242,29 @@ resource "google_alloydb_instance" "primary" {
query_plans_per_minute = var.query_insights_config.query_plans_per_minute
}
}
# waiting to fix this issue https://github.com/hashicorp/terraform-provider-google/issues/14944
lifecycle {
ignore_changes = [
network_config
]
}
}
resource "google_alloydb_cluster" "secondary" {
count = var.cross_region_replication.enabled ? 1 : 0
project = var.project_id
annotations = var.annotations
cluster_id = local.secondary_cluster_name
cluster_type = var.cross_region_replication.promote_secondary || var.cross_region_replication.switchover_mode ? "PRIMARY" : "SECONDARY"
database_version = var.database_version
deletion_policy = "FORCE"
display_name = coalesce(var.cross_region_replication.secondary_cluster_display_name, local.secondary_cluster_name)
labels = var.labels
location = var.cross_region_replication.region
count = var.cross_region_replication.enabled ? 1 : 0
project = var.project_id
annotations = var.annotations
cluster_id = local.secondary_cluster_name
cluster_type = var.cross_region_replication.promote_secondary || var.cross_region_replication.switchover_mode ? "PRIMARY" : "SECONDARY"
database_version = var.database_version
deletion_policy = "FORCE"
display_name = coalesce(var.cross_region_replication.secondary_cluster_display_name, local.secondary_cluster_name)
labels = var.labels
location = var.cross_region_replication.region
skip_await_major_version_upgrade = var.skip_await_major_version_upgrade
subscription_type = var.subscription_type
network_config {
network = try(var.network_config.psa_config.network, null)
allocated_ip_range = try(var.network_config.psa_config.allocated_ip_range, null)
# network_config block should exist only when PSA VPC resource link is present to prevent Terraform state drift
dynamic "network_config" {
for_each = var.network_config.psa_config != null ? [""] : []
content {
network = var.network_config.psa_config.network
allocated_ip_range = var.network_config.psa_config.allocated_ip_range
}
}
dynamic "automated_backup_policy" {
@@ -256,9 +276,9 @@ resource "google_alloydb_cluster" "secondary" {
labels = var.labels
dynamic "encryption_config" {
for_each = var.encryption_config != null ? [""] : []
for_each = local.secondary_kms_key_name != null ? [""] : []
content {
kms_key_name = var.encryption_config.secondary_kms_key_name
kms_key_name = local.secondary_kms_key_name
}
}
@@ -266,9 +286,9 @@ resource "google_alloydb_cluster" "secondary" {
days_of_week = var.automated_backup_configuration.weekly_schedule.days_of_week
start_times {
hours = var.automated_backup_configuration.weekly_schedule.start_times.hours
minutes = var.automated_backup_configuration.weekly_schedule.start_times.minutes
seconds = var.automated_backup_configuration.weekly_schedule.start_times.seconds
nanos = var.automated_backup_configuration.weekly_schedule.start_times.nanos
minutes = 0
seconds = 0
nanos = 0
}
}
@@ -288,24 +308,21 @@ resource "google_alloydb_cluster" "secondary" {
}
}
dynamic "continuous_backup_config" {
for_each = var.continuous_backup_configuration.enabled ? [""] : []
content {
enabled = true
recovery_window_days = var.continuous_backup_configuration.recovery_window_days
dynamic "encryption_config" {
for_each = var.encryption_config != null ? [""] : []
content {
kms_key_name = var.encryption_config.secondary_kms_key_name
}
continuous_backup_config {
enabled = var.continuous_backup_configuration.enabled
recovery_window_days = var.continuous_backup_configuration.recovery_window_days
dynamic "encryption_config" {
for_each = local.secondary_kms_key_name != null ? [""] : []
content {
kms_key_name = local.secondary_kms_key_name
}
}
}
dynamic "encryption_config" {
for_each = var.encryption_config != null ? [""] : []
for_each = local.secondary_kms_key_name != null ? [""] : []
content {
kms_key_name = var.encryption_config.secondary_kms_key_name
kms_key_name = local.secondary_kms_key_name
}
}
@@ -316,16 +333,20 @@ resource "google_alloydb_cluster" "secondary" {
day = var.maintenance_config.day
start_time {
hours = var.maintenance_config.start_time.hours
minutes = var.maintenance_config.start_time.minutes
seconds = var.maintenance_config.start_time.seconds
nanos = var.maintenance_config.start_time.nanos
minutes = 0
seconds = 0
nanos = 0
}
}
}
}
psc_config {
psc_enabled = var.network_config.psc_config != null ? true : null
# psc_config block should exist only when PSC is enabled to prevent Terraform state drift
dynamic "psc_config" {
for_each = length(local.allowed_consumer_projects) > 0 ? [""] : []
content {
psc_enabled = true
}
}
dynamic "secondary_config" {
@@ -336,12 +357,11 @@ resource "google_alloydb_cluster" "secondary" {
}
depends_on = [google_alloydb_instance.primary]
# waiting to fix this issue https://github.com/hashicorp/terraform-provider-google/issues/14944
lifecycle {
ignore_changes = [
display_name,
network_config,
psc_config
]
}
}
@@ -359,42 +379,43 @@ resource "google_alloydb_instance" "secondary" {
labels = var.labels
dynamic "client_connection_config" {
for_each = var.client_connection_config != null ? [""] : []
for_each = local.require_connectors != null || local.ssl_mode != null ? [""] : []
content {
require_connectors = var.client_connection_config.require_connectors
require_connectors = local.require_connectors
dynamic "ssl_config" {
for_each = var.client_connection_config.ssl_config != null ? [""] : []
for_each = local.ssl_mode != null ? [""] : []
content {
ssl_mode = var.client_connection_config.ssl_config.ssl_mode
ssl_mode = local.ssl_mode
}
}
}
}
dynamic "machine_config" {
for_each = var.machine_config != null || var.cross_region_replication.secondary_machine_config != null ? [""] : []
content {
cpu_count = coalesce(try(var.cross_region_replication.secondary_machine_config.cpu_count, null), try(var.machine_config.cpu_count, null))
}
machine_config {
cpu_count = coalesce(try(var.cross_region_replication.secondary_machine_config.cpu_count, null), var.machine_config.cpu_count)
machine_type = local.secondary_machine_type
}
# network_config block should exist only when (outbound) public IP is enabled to prevent Terraform state drift
dynamic "network_config" {
for_each = var.network_config.psa_config != null ? [""] : []
for_each = local.has_public_ip ? [""] : []
content {
dynamic "authorized_external_networks" {
for_each = coalesce(var.network_config.psa_config.authorized_external_networks, [])
for_each = local.authorized_external_networks
content {
cidr_range = authorized_external_networks.value
}
}
enable_public_ip = var.network_config.psa_config.enable_public_ip
enable_public_ip = local.enable_public_ip
enable_outbound_public_ip = local.enable_outbound_public_ip
}
}
# psc_instance_config block should exist only when there are PSC allowed consumer projects to prevent Terraform state drift
dynamic "psc_instance_config" {
for_each = var.network_config.psc_config != null ? [""] : []
for_each = length(local.allowed_consumer_projects) > 0 ? [""] : []
content {
allowed_consumer_projects = var.network_config.psc_config.allowed_consumer_projects
allowed_consumer_projects = local.allowed_consumer_projects
}
}
@@ -407,31 +428,100 @@ resource "google_alloydb_instance" "secondary" {
query_plans_per_minute = var.query_insights_config.query_plans_per_minute
}
}
}
# waiting to fix this issue https://github.com/hashicorp/terraform-provider-google/issues/14944
lifecycle {
ignore_changes = [
network_config
]
# Read pool (instance_type = "READ_POOL") cannot be created for secondary cluster
# and does not support the following attributes:
# * availability_type: Because 1 node pool (read_pool_config.node_count) is always zonal, two or more is always regional.
# * gce_zone
# * network_config.enable_outbound_public_ip
resource "google_alloydb_instance" "read_pool" {
for_each = local.read_pool
annotations = var.annotations
cluster = google_alloydb_cluster.primary.id
database_flags = each.value.flags
display_name = coalesce(each.value.display_name, "${local.prefix}${each.key}")
instance_id = "${local.prefix}${each.key}"
instance_type = "READ_POOL"
labels = var.labels
dynamic "client_connection_config" {
for_each = each.value.require_connectors != null || each.value.ssl_mode != null ? [""] : []
content {
require_connectors = each.value.require_connectors
dynamic "ssl_config" {
for_each = each.value.ssl_mode != null ? [""] : []
content {
ssl_mode = each.value.ssl_mode
}
}
}
}
machine_config {
cpu_count = each.value.machine_config.cpu_count
machine_type = each.value.machine_config.machine_type
}
# network_config block should exist only when (outbound) public IP is enabled to prevent Terraform state drift
dynamic "network_config" {
for_each = each.value.network_config.enable_public_ip ? [""] : []
content {
dynamic "authorized_external_networks" {
for_each = toset(each.value.network_config.authorized_external_networks)
content {
cidr_range = authorized_external_networks.value
}
}
enable_public_ip = true
}
}
# psc_instance_config block should exist only when there are PSC allowed consumer projects to prevent Terraform state drift
dynamic "psc_instance_config" {
for_each = length(local.allowed_consumer_projects) > 0 ? [""] : []
content {
allowed_consumer_projects = local.allowed_consumer_projects
}
}
read_pool_config {
node_count = each.value.node_count
}
dynamic "query_insights_config" {
for_each = each.value.query_insights_config != null ? [""] : []
content {
query_string_length = each.value.query_insights_config.query_string_length
record_application_tags = each.value.query_insights_config.record_application_tags
record_client_address = each.value.query_insights_config.record_client_address
query_plans_per_minute = each.value.query_insights_config.query_plans_per_minute
}
}
depends_on = [google_alloydb_instance.primary]
}
resource "random_password" "passwords" {
for_each = toset([
for k, v in coalesce(var.users, {}) :
k
if v.password == null
])
for_each = {
for k, v in var.users :
k => v
if v.type == "ALLOYDB_BUILT_IN" && v.password == null
}
length = 16
special = true
}
resource "google_alloydb_user" "users" {
for_each = local.users
cluster = google_alloydb_cluster.primary.id
user_id = each.value.name
user_type = each.value.type
password = each.value.password
for_each = var.users
cluster = google_alloydb_cluster.primary.id
user_id = each.key
user_type = each.value.type
password = (
each.value.type == "ALLOYDB_BUILT_IN" && each.value.password == null ?
random_password.passwords[each.key].result
: each.value.password
)
database_roles = each.value.roles
depends_on = [google_alloydb_instance.primary]
}

View File

@@ -21,6 +21,16 @@ locals {
}
}
output "cluster_id" {
description = "Fully qualified primary cluster id."
value = google_alloydb_cluster.primary.id
}
output "cluster_name" {
description = "Name of the primary cluster."
value = google_alloydb_cluster.primary.name
}
output "id" {
description = "Fully qualified primary instance id."
value = google_alloydb_instance.primary.id
@@ -65,6 +75,11 @@ output "names" {
}
}
output "outbound_public_ips" {
description = "Public IP addresses of the primary instance."
value = google_alloydb_instance.primary.outbound_public_ip_addresses
}
output "psc_dns_name" {
description = "AlloyDB Primary instance PSC DNS name."
value = try(google_alloydb_instance.primary.psc_instance_config[0].psc_dns_name, null)
@@ -77,16 +92,57 @@ output "psc_dns_names" {
}
}
output "public_ip" {
description = "Public IP address of the primary instance."
value = google_alloydb_instance.primary.public_ip_address
}
output "read_pool_ids" {
description = "Fully qualified ids of all read poll instances."
value = {
for name, instance in google_alloydb_instance.read_pool :
name => instance.id
}
}
output "read_pool_ips" {
description = "IP addresses of all read poll instances."
value = {
for name, instance in google_alloydb_instance.read_pool :
name => instance.ip_address
}
}
output "secondary_cluster_id" {
description = "Fully qualified secondary cluster id."
value = var.cross_region_replication.enabled ? google_alloydb_cluster.secondary[0].id : null
}
output "secondary_cluster_name" {
description = "Name of the secondary cluster."
value = var.cross_region_replication.enabled ? google_alloydb_cluster.secondary[0].name : null
}
output "secondary_id" {
description = "Fully qualified primary instance id."
description = "Fully qualified secondary instance id."
value = var.cross_region_replication.enabled ? google_alloydb_instance.secondary[0].id : null
}
output "secondary_ip" {
description = "IP address of the primary instance."
description = "IP address of the secondary instance."
value = var.cross_region_replication.enabled ? google_alloydb_instance.secondary[0].ip_address : null
}
output "secondary_outbound_public_ips" {
description = "Public IP addresses of the primary instance."
value = var.cross_region_replication.enabled ? google_alloydb_instance.secondary[0].outbound_public_ip_addresses : null
}
output "secondary_public_ip" {
description = "Public IP address of the secondary instance."
value = var.cross_region_replication.enabled ? google_alloydb_instance.secondary[0].public_ip_address : null
}
output "service_attachment" {
description = "AlloyDB Primary instance service attachment."
value = try(google_alloydb_instance.primary.psc_instance_config[0].service_attachment_link, null)

View File

@@ -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'."
}
}

View File

@@ -18,8 +18,8 @@ values:
cluster_id: primary
cluster_type: PRIMARY
continuous_backup_config:
- enabled: true
recovery_window_days: 14
- enabled: true
recovery_window_days: 14
database_version: POSTGRES_15
deletion_policy: DEFAULT
display_name: primary
@@ -28,12 +28,13 @@ values:
labels: null
location: europe-west8
maintenance_update_policy: []
network_config:
- allocated_ip_range: null
project: test-alloycmek
psc_config: []
restore_backup_source: []
restore_continuous_backup_source: []
secondary_config: []
skip_await_major_version_upgrade: true
subscription_type: STANDARD
timeouts: null
module.alloydb.google_alloydb_instance.primary:
annotations: null
@@ -44,15 +45,12 @@ values:
instance_type: PRIMARY
labels: null
machine_config:
- cpu_count: 2
network_config:
- authorized_external_networks: []
enable_public_ip: false
- cpu_count: 2
query_insights_config:
- query_plans_per_minute: 5
query_string_length: 1024
record_application_tags: true
record_client_address: true
- query_plans_per_minute: 5
query_string_length: 1024
record_application_tags: true
record_client_address: true
read_pool_config: []
timeouts: null

View File

@@ -18,9 +18,9 @@ values:
cluster_id: db
cluster_type: PRIMARY
continuous_backup_config:
- enabled: true
encryption_config: []
recovery_window_days: 14
- enabled: true
encryption_config: []
recovery_window_days: 14
database_version: POSTGRES_15
deletion_policy: DEFAULT
display_name: db
@@ -31,21 +31,24 @@ values:
location: europe-west8
maintenance_update_policy: []
network_config:
- allocated_ip_range: null
network: projects/xxx/global/networks/aaa
- allocated_ip_range: null
network: projects/xxx/global/networks/aaa
project: project-id
psc_config: []
restore_backup_source: []
restore_continuous_backup_source: []
secondary_config: []
skip_await_major_version_upgrade: true
subscription_type: STANDARD
timeouts: null
module.alloydb.google_alloydb_cluster.secondary[0]:
annotations: null
cluster_id: db-sec
cluster_type: SECONDARY
continuous_backup_config:
- enabled: true
encryption_config: []
recovery_window_days: 14
- enabled: true
encryption_config: []
recovery_window_days: 14
database_version: POSTGRES_15
deletion_policy: FORCE
display_name: db-sec
@@ -56,12 +59,16 @@ values:
location: europe-west12
maintenance_update_policy: []
network_config:
- allocated_ip_range: null
network: projects/xxx/global/networks/aaa
- allocated_ip_range: null
network: projects/xxx/global/networks/aaa
project: project-id
psc_config: []
restore_backup_source: []
restore_continuous_backup_source: []
secondary_config: [{}]
secondary_config:
- {}
skip_await_major_version_upgrade: true
subscription_type: STANDARD
timeouts: null
module.alloydb.google_alloydb_instance.primary:
annotations: null
@@ -72,15 +79,12 @@ values:
instance_type: PRIMARY
labels: null
machine_config:
- cpu_count: 2
network_config:
- authorized_external_networks: []
enable_public_ip: false
- cpu_count: 2
query_insights_config:
- query_plans_per_minute: 5
query_string_length: 1024
record_application_tags: true
record_client_address: true
- query_plans_per_minute: 5
query_string_length: 1024
record_application_tags: true
record_client_address: true
read_pool_config: []
timeouts: null
module.alloydb.google_alloydb_instance.secondary[0]:
@@ -92,15 +96,12 @@ values:
instance_type: SECONDARY
labels: null
machine_config:
- cpu_count: 2
network_config:
- authorized_external_networks: []
enable_public_ip: false
- cpu_count: 2
query_insights_config:
- query_plans_per_minute: 5
query_string_length: 1024
record_application_tags: true
record_client_address: true
- query_plans_per_minute: 5
query_string_length: 1024
record_application_tags: true
record_client_address: true
read_pool_config: []
timeouts: null

View File

@@ -18,9 +18,9 @@ values:
cluster_id: primary
cluster_type: PRIMARY
continuous_backup_config:
- enabled: true
encryption_config: []
recovery_window_days: 14
- enabled: true
encryption_config: []
recovery_window_days: 14
database_version: POSTGRES_15
deletion_policy: DEFAULT
display_name: primary
@@ -31,12 +31,15 @@ values:
location: europe-west8
maintenance_update_policy: []
network_config:
- allocated_ip_range: null
network: projects/xxx/global/networks/aaa
- allocated_ip_range: null
network: projects/xxx/global/networks/aaa
project: project-id
psc_config: []
restore_backup_source: []
restore_continuous_backup_source: []
secondary_config: []
skip_await_major_version_upgrade: true
subscription_type: STANDARD
timeouts: null
module.alloydb.google_alloydb_instance.primary:
annotations: null
@@ -52,28 +55,24 @@ values:
instance_type: PRIMARY
labels: null
machine_config:
- cpu_count: 2
network_config:
- authorized_external_networks: []
enable_public_ip: false
- cpu_count: 2
query_insights_config:
- query_plans_per_minute: 5
query_string_length: 1024
record_application_tags: true
record_client_address: true
- query_plans_per_minute: 5
query_string_length: 1024
record_application_tags: true
record_client_address: true
read_pool_config: []
timeouts: null
module.alloydb.google_alloydb_user.users["user1"]:
database_roles:
- alloydbsuperuser
password: null
- alloydbsuperuser
timeouts: null
user_id: user1
user_type: ALLOYDB_BUILT_IN
module.alloydb.google_alloydb_user.users["user2"]:
database_roles:
- alloydbsuperuser
password: null
- alloydbsuperuser
password: mypassword
timeouts: null
user_id: user2
user_type: ALLOYDB_BUILT_IN

View File

@@ -18,9 +18,9 @@ values:
cluster_id: db
cluster_type: PRIMARY
continuous_backup_config:
- enabled: true
encryption_config: []
recovery_window_days: 14
- enabled: true
encryption_config: []
recovery_window_days: 14
database_version: POSTGRES_15
deletion_policy: DEFAULT
display_name: db
@@ -30,15 +30,14 @@ values:
labels: null
location: europe-west8
maintenance_update_policy: []
network_config:
- allocated_ip_range: null
network: null
project: project-id
psc_config:
- psc_enabled: true
- psc_enabled: true
restore_backup_source: []
restore_continuous_backup_source: []
secondary_config: []
skip_await_major_version_upgrade: true
subscription_type: STANDARD
timeouts: null
module.alloydb.google_alloydb_instance.primary:
annotations: null
@@ -49,15 +48,15 @@ values:
instance_type: PRIMARY
labels: null
machine_config:
- cpu_count: 2
- cpu_count: 2
psc_instance_config:
- allowed_consumer_projects:
- '123'
- allowed_consumer_projects:
- '123'
query_insights_config:
- query_plans_per_minute: 5
query_string_length: 1024
record_application_tags: true
record_client_address: true
- query_plans_per_minute: 5
query_string_length: 1024
record_application_tags: true
record_client_address: true
read_pool_config: []
timeouts: null

View File

@@ -0,0 +1,94 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
values:
module.alloydb.google_alloydb_cluster.primary:
annotations: null
cluster_id: db
cluster_type: PRIMARY
continuous_backup_config:
- enabled: true
encryption_config: []
recovery_window_days: 14
database_version: POSTGRES_15
deletion_policy: DEFAULT
display_name: db
encryption_config: []
etag: null
initial_user: []
labels: null
location: europe-west8
maintenance_update_policy: []
network_config:
- allocated_ip_range: null
network: projects/xxx/global/networks/aaa
project: project-id
psc_config: []
restore_backup_source: []
restore_continuous_backup_source: []
secondary_config: []
skip_await_major_version_upgrade: true
subscription_type: STANDARD
timeouts: null
module.alloydb.google_alloydb_instance.primary:
annotations: null
availability_type: REGIONAL
display_name: db
gce_zone: null
instance_id: db
instance_type: PRIMARY
labels: null
machine_config:
- cpu_count: 2
query_insights_config:
- query_plans_per_minute: 5
query_string_length: 1024
record_application_tags: true
record_client_address: true
read_pool_config: []
timeouts: null
module.alloydb.google_alloydb_instance.read_pool["regional-read-pool"]:
annotations: null
display_name: regional-read-pool
gce_zone: null
instance_id: regional-read-pool
instance_type: READ_POOL
labels: null
machine_config:
- cpu_count: 2
read_pool_config:
- node_count: 2
timeouts: null
module.alloydb.google_alloydb_instance.read_pool["zonal-read-pool"]:
annotations: null
display_name: zonal-read-pool
effective_labels:
goog-terraform-provisioned: 'true'
gce_zone: null
instance_id: zonal-read-pool
instance_type: READ_POOL
labels: null
machine_config:
- cpu_count: 2
read_pool_config:
- node_count: 1
timeouts: null
counts:
google_alloydb_cluster: 1
google_alloydb_instance: 3
modules: 1
resources: 4
outputs: {}

View File

@@ -30,14 +30,13 @@ values:
labels: null
location: europe-west8
maintenance_update_policy: []
network_config:
- allocated_ip_range: null
project: test-alloydb
psc_config:
- psc_enabled: null
psc_config: []
restore_backup_source: []
restore_continuous_backup_source: []
secondary_config: []
skip_await_major_version_upgrade: true
subscription_type: STANDARD
timeouts: null
module.alloydb.google_alloydb_instance.primary:
annotations: null
@@ -49,9 +48,6 @@ values:
labels: null
machine_config:
- cpu_count: 2
network_config:
- authorized_external_networks: []
enable_public_ip: false
query_insights_config:
- query_plans_per_minute: 5
query_string_length: 1024