CloudSQL PSC Endpoints support (#2242)
* Add PSC endpoints consumers to net-address * Cloud SQL E2E tests
This commit is contained in:
committed by
GitHub
parent
35a17a46ba
commit
6a3c7fe444
@@ -1,4 +1,4 @@
|
|||||||
# Cloud SQL instance with read replicas
|
# Cloud SQL instance module
|
||||||
|
|
||||||
This module manages the creation of Cloud SQL instances with potential read replicas in other regions. It can also create an initial set of users and databases via the `users` and `databases` parameters.
|
This module manages the creation of Cloud SQL instances with potential read replicas in other regions. It can also create an initial set of users and databases via the `users` and `databases` parameters.
|
||||||
|
|
||||||
@@ -6,7 +6,24 @@ Note that this module assumes that some options are the same for both the primar
|
|||||||
|
|
||||||
*Warning:* if you use the `users` field, you terraform state will contain each user's password in plain text.
|
*Warning:* if you use the `users` field, you terraform state will contain each user's password in plain text.
|
||||||
|
|
||||||
## Simple example
|
<!-- BEGIN TOC -->
|
||||||
|
- [Examples](#examples)
|
||||||
|
- [Simple example](#simple-example)
|
||||||
|
- [Cross-regional read replica](#cross-regional-read-replica)
|
||||||
|
- [Custom flags, databases and users](#custom-flags-databases-and-users)
|
||||||
|
- [CMEK encryption](#cmek-encryption)
|
||||||
|
- [Instance with PSC enabled](#instance-with-psc-enabled)
|
||||||
|
- [Enable public IP](#enable-public-ip)
|
||||||
|
- [Query Insights](#query-insights)
|
||||||
|
- [Maintenance Config](#maintenance-config)
|
||||||
|
- [SSL Config](#ssl-config)
|
||||||
|
- [Variables](#variables)
|
||||||
|
- [Outputs](#outputs)
|
||||||
|
- [Fixtures](#fixtures)
|
||||||
|
<!-- END TOC -->
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
### Simple example
|
||||||
|
|
||||||
This example shows how to setup a project, VPC and a standalone Cloud SQL instance.
|
This example shows how to setup a project, VPC and a standalone Cloud SQL instance.
|
||||||
|
|
||||||
@@ -14,10 +31,12 @@ This example shows how to setup a project, VPC and a standalone Cloud SQL instan
|
|||||||
module "project" {
|
module "project" {
|
||||||
source = "./fabric/modules/project"
|
source = "./fabric/modules/project"
|
||||||
billing_account = var.billing_account_id
|
billing_account = var.billing_account_id
|
||||||
parent = var.organization_id
|
parent = var.folder_id
|
||||||
name = "my-db-project"
|
name = "db-prj"
|
||||||
|
prefix = var.prefix
|
||||||
services = [
|
services = [
|
||||||
"servicenetworking.googleapis.com"
|
"servicenetworking.googleapis.com",
|
||||||
|
"sqladmin.googleapis.com",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,9 +44,18 @@ module "vpc" {
|
|||||||
source = "./fabric/modules/net-vpc"
|
source = "./fabric/modules/net-vpc"
|
||||||
project_id = module.project.project_id
|
project_id = module.project.project_id
|
||||||
name = "my-network"
|
name = "my-network"
|
||||||
|
# need only one - psa_config or subnets_psc
|
||||||
psa_configs = [{
|
psa_configs = [{
|
||||||
ranges = { cloud-sql = "10.60.0.0/16" }
|
ranges = { cloud-sql = "10.60.0.0/16" }
|
||||||
|
deletion_policy = "ABANDON"
|
||||||
}]
|
}]
|
||||||
|
subnets_psc = [
|
||||||
|
{
|
||||||
|
ip_cidr_range = "10.0.3.0/24"
|
||||||
|
name = "psc"
|
||||||
|
region = var.region
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
module "db" {
|
module "db" {
|
||||||
@@ -38,17 +66,20 @@ module "db" {
|
|||||||
psa_config = {
|
psa_config = {
|
||||||
private_network = module.vpc.self_link
|
private_network = module.vpc.self_link
|
||||||
}
|
}
|
||||||
|
# psc_allowed_consumer_projects = [var.project_id]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name = "db"
|
name = "db"
|
||||||
region = "europe-west1"
|
region = var.region
|
||||||
database_version = "POSTGRES_13"
|
database_version = "POSTGRES_13"
|
||||||
tier = "db-g1-small"
|
tier = "db-g1-small"
|
||||||
|
gcp_deletion_protection = false
|
||||||
|
terraform_deletion_protection = false
|
||||||
}
|
}
|
||||||
# tftest modules=3 resources=11 inventory=simple.yaml
|
# tftest modules=3 resources=14 inventory=simple.yaml e2e
|
||||||
```
|
```
|
||||||
|
|
||||||
## Cross-regional read replica
|
### Cross-regional read replica
|
||||||
|
|
||||||
```hcl
|
```hcl
|
||||||
module "db" {
|
module "db" {
|
||||||
@@ -61,21 +92,23 @@ module "db" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prefix = "myprefix"
|
|
||||||
name = "db"
|
name = "db"
|
||||||
region = "europe-west1"
|
prefix = "myprefix"
|
||||||
|
region = var.region
|
||||||
database_version = "POSTGRES_13"
|
database_version = "POSTGRES_13"
|
||||||
tier = "db-g1-small"
|
tier = "db-g1-small"
|
||||||
|
|
||||||
replicas = {
|
replicas = {
|
||||||
replica1 = { region = "europe-west3", encryption_key_name = null }
|
replica1 = { region = "europe-west3" }
|
||||||
replica2 = { region = "us-central1", encryption_key_name = null }
|
replica2 = { region = "us-central1" }
|
||||||
}
|
}
|
||||||
|
gcp_deletion_protection = false
|
||||||
|
terraform_deletion_protection = false
|
||||||
}
|
}
|
||||||
# tftest modules=1 resources=3 inventory=replicas.yaml
|
# tftest modules=1 resources=3 inventory=replicas.yaml e2e
|
||||||
```
|
```
|
||||||
|
|
||||||
## Custom flags, databases and users
|
### Custom flags, databases and users
|
||||||
|
|
||||||
```hcl
|
```hcl
|
||||||
module "db" {
|
module "db" {
|
||||||
@@ -89,7 +122,7 @@ module "db" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
name = "db"
|
name = "db"
|
||||||
region = "europe-west1"
|
region = var.region
|
||||||
database_version = "MYSQL_8_0"
|
database_version = "MYSQL_8_0"
|
||||||
tier = "db-g1-small"
|
tier = "db-g1-small"
|
||||||
|
|
||||||
@@ -112,47 +145,19 @@ module "db" {
|
|||||||
password = "mypassword"
|
password = "mypassword"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
gcp_deletion_protection = false
|
||||||
|
terraform_deletion_protection = false
|
||||||
}
|
}
|
||||||
# tftest modules=1 resources=6 inventory=custom.yaml
|
# tftest modules=1 resources=6 inventory=custom.yaml e2e
|
||||||
```
|
```
|
||||||
|
|
||||||
### CMEK encryption
|
### CMEK encryption
|
||||||
|
|
||||||
```hcl
|
```hcl
|
||||||
|
|
||||||
module "project" {
|
|
||||||
source = "./fabric/modules/project"
|
|
||||||
billing_account = var.billing_account_id
|
|
||||||
parent = var.organization_id
|
|
||||||
name = "my-db-project"
|
|
||||||
services = [
|
|
||||||
"servicenetworking.googleapis.com",
|
|
||||||
"sqladmin.googleapis.com",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
module "kms" {
|
|
||||||
source = "./fabric/modules/kms"
|
|
||||||
project_id = module.project.project_id
|
|
||||||
keyring = {
|
|
||||||
name = "keyring"
|
|
||||||
location = var.region
|
|
||||||
}
|
|
||||||
keys = {
|
|
||||||
key-sql = {
|
|
||||||
iam = {
|
|
||||||
"roles/cloudkms.cryptoKeyEncrypterDecrypter" = [
|
|
||||||
"serviceAccount:${module.project.service_accounts.robots.sqladmin}"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module "db" {
|
module "db" {
|
||||||
source = "./fabric/modules/cloudsql-instance"
|
source = "./fabric/modules/cloudsql-instance"
|
||||||
project_id = module.project.project_id
|
project_id = var.project_id
|
||||||
encryption_key_name = module.kms.keys["key-sql"].id
|
encryption_key_name = var.kms_key.id
|
||||||
network_config = {
|
network_config = {
|
||||||
connectivity = {
|
connectivity = {
|
||||||
psa_config = {
|
psa_config = {
|
||||||
@@ -160,13 +165,15 @@ module "db" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name = "db"
|
name = "db"
|
||||||
region = var.region
|
region = var.region
|
||||||
database_version = "POSTGRES_13"
|
database_version = "POSTGRES_13"
|
||||||
tier = "db-g1-small"
|
tier = "db-g1-small"
|
||||||
|
gcp_deletion_protection = false
|
||||||
|
terraform_deletion_protection = false
|
||||||
}
|
}
|
||||||
|
|
||||||
# tftest modules=3 resources=10
|
# tftest modules=1 resources=2 fixtures=fixtures/cloudsql-kms-iam-grant.tf e2e
|
||||||
```
|
```
|
||||||
|
|
||||||
### Instance with PSC enabled
|
### Instance with PSC enabled
|
||||||
@@ -177,22 +184,25 @@ module "db" {
|
|||||||
project_id = var.project_id
|
project_id = var.project_id
|
||||||
network_config = {
|
network_config = {
|
||||||
connectivity = {
|
connectivity = {
|
||||||
psc_allowed_consumer_projects = ["my-project-id"]
|
psc_allowed_consumer_projects = [var.project_id]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prefix = "myprefix"
|
prefix = "myprefix"
|
||||||
name = "db"
|
name = "db"
|
||||||
region = "europe-west1"
|
region = var.region
|
||||||
availability_type = "REGIONAL"
|
availability_type = "REGIONAL"
|
||||||
database_version = "POSTGRES_13"
|
database_version = "POSTGRES_13"
|
||||||
tier = "db-g1-small"
|
tier = "db-g1-small"
|
||||||
|
|
||||||
|
gcp_deletion_protection = false
|
||||||
|
terraform_deletion_protection = false
|
||||||
}
|
}
|
||||||
# tftest modules=1 resources=1
|
# tftest modules=1 resources=1 inventory=psc.yaml e2e
|
||||||
```
|
```
|
||||||
|
|
||||||
### Enable public IP
|
### Enable public IP
|
||||||
|
|
||||||
Use `ipv_enabled` to create instances with a public IP.
|
Use `public_ipv4` to create instances with a public IP.
|
||||||
|
|
||||||
```hcl
|
```hcl
|
||||||
module "db" {
|
module "db" {
|
||||||
@@ -206,15 +216,14 @@ module "db" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name = "db"
|
name = "db"
|
||||||
region = "europe-west1"
|
region = var.region
|
||||||
tier = "db-g1-small"
|
tier = "db-g1-small"
|
||||||
database_version = "MYSQL_8_0"
|
database_version = "MYSQL_8_0"
|
||||||
replicas = {
|
gcp_deletion_protection = false
|
||||||
replica1 = { region = "europe-west3", encryption_key_name = null }
|
terraform_deletion_protection = false
|
||||||
}
|
|
||||||
}
|
}
|
||||||
# tftest modules=1 resources=2 inventory=public-ip.yaml
|
# tftest modules=1 resources=1 inventory=public-ip.yaml e2e
|
||||||
```
|
```
|
||||||
|
|
||||||
### Query Insights
|
### Query Insights
|
||||||
@@ -233,15 +242,17 @@ module "db" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
name = "db"
|
name = "db"
|
||||||
region = "europe-west1"
|
region = var.region
|
||||||
database_version = "POSTGRES_13"
|
database_version = "POSTGRES_13"
|
||||||
tier = "db-g1-small"
|
tier = "db-g1-small"
|
||||||
|
|
||||||
insights_config = {
|
insights_config = {
|
||||||
query_string_length = 2048
|
query_string_length = 2048
|
||||||
}
|
}
|
||||||
|
gcp_deletion_protection = false
|
||||||
|
terraform_deletion_protection = false
|
||||||
}
|
}
|
||||||
# tftest modules=1 resources=1 inventory=insights.yaml
|
# tftest modules=1 resources=1 inventory=insights.yaml e2e
|
||||||
```
|
```
|
||||||
|
|
||||||
### Maintenance Config
|
### Maintenance Config
|
||||||
@@ -260,13 +271,15 @@ module "db" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
name = "db"
|
name = "db"
|
||||||
region = "europe-west1"
|
region = var.region
|
||||||
database_version = "POSTGRES_13"
|
database_version = "POSTGRES_13"
|
||||||
tier = "db-g1-small"
|
tier = "db-g1-small"
|
||||||
|
|
||||||
maintenance_config = {}
|
maintenance_config = {}
|
||||||
|
gcp_deletion_protection = false
|
||||||
|
terraform_deletion_protection = false
|
||||||
}
|
}
|
||||||
# tftest modules=1 resources=1
|
# tftest modules=1 resources=1 e2e
|
||||||
```
|
```
|
||||||
|
|
||||||
### SSL Config
|
### SSL Config
|
||||||
@@ -285,13 +298,15 @@ module "db" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
name = "db"
|
name = "db"
|
||||||
region = "europe-west1"
|
region = var.region
|
||||||
database_version = "POSTGRES_13"
|
database_version = "POSTGRES_13"
|
||||||
tier = "db-g1-small"
|
tier = "db-g1-small"
|
||||||
|
|
||||||
ssl = {}
|
ssl = {}
|
||||||
|
gcp_deletion_protection = false
|
||||||
|
terraform_deletion_protection = false
|
||||||
}
|
}
|
||||||
# tftest modules=1 resources=1
|
# tftest modules=1 resources=1 e2e
|
||||||
```
|
```
|
||||||
<!-- BEGIN TFDOC -->
|
<!-- BEGIN TFDOC -->
|
||||||
## Variables
|
## Variables
|
||||||
@@ -322,7 +337,7 @@ module "db" {
|
|||||||
| [labels](variables.tf#L140) | Labels to be attached to all instances. | <code>map(string)</code> | | <code>null</code> |
|
| [labels](variables.tf#L140) | Labels to be attached to all instances. | <code>map(string)</code> | | <code>null</code> |
|
||||||
| [maintenance_config](variables.tf#L146) | Set maintenance window configuration and maintenance deny period (up to 90 days). Date format: 'yyyy-mm-dd'. | <code title="object({ maintenance_window = optional(object({ day = number hour = number update_track = optional(string, null) }), null) deny_maintenance_period = optional(object({ start_date = string end_date = string start_time = optional(string, "00:00:00") }), null) })">object({…})</code> | | <code>{}</code> |
|
| [maintenance_config](variables.tf#L146) | Set maintenance window configuration and maintenance deny period (up to 90 days). Date format: 'yyyy-mm-dd'. | <code title="object({ maintenance_window = optional(object({ day = number hour = number update_track = optional(string, null) }), null) deny_maintenance_period = optional(object({ start_date = string end_date = string start_time = optional(string, "00:00:00") }), null) })">object({…})</code> | | <code>{}</code> |
|
||||||
| [prefix](variables.tf#L207) | Optional prefix used to generate instance names. | <code>string</code> | | <code>null</code> |
|
| [prefix](variables.tf#L207) | Optional prefix used to generate instance names. | <code>string</code> | | <code>null</code> |
|
||||||
| [replicas](variables.tf#L227) | Map of NAME=> {REGION, KMS_KEY} for additional read replicas. Set to null to disable replica creation. | <code title="map(object({ region = string encryption_key_name = string }))">map(object({…}))</code> | | <code>{}</code> |
|
| [replicas](variables.tf#L227) | Map of NAME=> {REGION, KMS_KEY} for additional read replicas. Set to null to disable replica creation. | <code title="map(object({ region = string encryption_key_name = optional(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [root_password](variables.tf#L236) | Root password of the Cloud SQL instance. Required for MS SQL Server. | <code>string</code> | | <code>null</code> |
|
| [root_password](variables.tf#L236) | Root password of the Cloud SQL instance. Required for MS SQL Server. | <code>string</code> | | <code>null</code> |
|
||||||
| [ssl](variables.tf#L242) | Setting to enable SSL, set config and certificates. | <code title="object({ client_certificates = optional(list(string)) require_ssl = optional(bool) ssl_mode = optional(string) })">object({…})</code> | | <code>{}</code> |
|
| [ssl](variables.tf#L242) | Setting to enable SSL, set config and certificates. | <code title="object({ client_certificates = optional(list(string)) require_ssl = optional(bool) ssl_mode = optional(string) })">object({…})</code> | | <code>{}</code> |
|
||||||
| [terraform_deletion_protection](variables.tf#L258) | Prevent terraform from deleting instances. | <code>bool</code> | | <code>true</code> |
|
| [terraform_deletion_protection](variables.tf#L258) | Prevent terraform from deleting instances. | <code>bool</code> | | <code>true</code> |
|
||||||
@@ -350,4 +365,8 @@ module "db" {
|
|||||||
| [self_link](outputs.tf#L114) | Self link of the primary instance. | |
|
| [self_link](outputs.tf#L114) | Self link of the primary instance. | |
|
||||||
| [self_links](outputs.tf#L119) | Self links of all instances. | |
|
| [self_links](outputs.tf#L119) | Self links of all instances. | |
|
||||||
| [user_passwords](outputs.tf#L127) | Map of containing the password of all users created through terraform. | ✓ |
|
| [user_passwords](outputs.tf#L127) | Map of containing the password of all users created through terraform. | ✓ |
|
||||||
|
|
||||||
|
## Fixtures
|
||||||
|
|
||||||
|
- [cloudsql-kms-iam-grant.tf](../../tests/fixtures/cloudsql-kms-iam-grant.tf)
|
||||||
<!-- END TFDOC -->
|
<!-- END TFDOC -->
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ variable "replicas" {
|
|||||||
description = "Map of NAME=> {REGION, KMS_KEY} for additional read replicas. Set to null to disable replica creation."
|
description = "Map of NAME=> {REGION, KMS_KEY} for additional read replicas. Set to null to disable replica creation."
|
||||||
type = map(object({
|
type = map(object({
|
||||||
region = string
|
region = string
|
||||||
encryption_key_name = string
|
encryption_key_name = optional(string)
|
||||||
}))
|
}))
|
||||||
default = {}
|
default = {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,6 +122,26 @@ module "addresses" {
|
|||||||
# tftest modules=1 resources=1 inventory=psc.yaml e2e
|
# tftest modules=1 resources=1 inventory=psc.yaml e2e
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To create PSC address targeting a service regional provider use the `service_attachment` property.
|
||||||
|
```hcl
|
||||||
|
module "addresses" {
|
||||||
|
source = "./fabric/modules/net-address"
|
||||||
|
project_id = var.project_id
|
||||||
|
psc_addresses = {
|
||||||
|
cloudsql-one = {
|
||||||
|
address = "10.0.16.32"
|
||||||
|
subnet_self_link = var.subnet.self_link
|
||||||
|
region = var.region
|
||||||
|
service_attachment = {
|
||||||
|
psc_service_attachment_link = module.cloudsql-instance.psc_service_attachment_link
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# tftest modules=2 resources=3 fixtures=fixtures/cloudsql-instance.tf inventory=psc-service-attachment.yaml e2e
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### IPSec Interconnect addresses
|
### IPSec Interconnect addresses
|
||||||
|
|
||||||
```hcl
|
```hcl
|
||||||
@@ -176,8 +196,8 @@ module "addresses" {
|
|||||||
| [internal_addresses](variables.tf#L50) | Map of internal addresses to create, keyed by name. | <code title="map(object({ region = string subnetwork = string address = optional(string) description = optional(string, "Terraform managed.") ipv6 = optional(map(string)) # To be left empty for ipv6 labels = optional(map(string)) name = optional(string) purpose = optional(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
| [internal_addresses](variables.tf#L50) | Map of internal addresses to create, keyed by name. | <code title="map(object({ region = string subnetwork = string address = optional(string) description = optional(string, "Terraform managed.") ipv6 = optional(map(string)) # To be left empty for ipv6 labels = optional(map(string)) name = optional(string) purpose = optional(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [ipsec_interconnect_addresses](variables.tf#L65) | Map of internal addresses used for HPA VPN over Cloud Interconnect. | <code title="map(object({ region = string address = string network = string description = optional(string, "Terraform managed.") name = optional(string) prefix_length = number }))">map(object({…}))</code> | | <code>{}</code> |
|
| [ipsec_interconnect_addresses](variables.tf#L65) | Map of internal addresses used for HPA VPN over Cloud Interconnect. | <code title="map(object({ region = string address = string network = string description = optional(string, "Terraform managed.") name = optional(string) prefix_length = number }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [network_attachments](variables.tf#L84) | PSC network attachments, names as keys. | <code title="map(object({ subnet_self_link = string automatic_connection = optional(bool, false) description = optional(string, "Terraform-managed.") producer_accept_lists = optional(list(string)) producer_reject_lists = optional(list(string)) }))">map(object({…}))</code> | | <code>{}</code> |
|
| [network_attachments](variables.tf#L84) | PSC network attachments, names as keys. | <code title="map(object({ subnet_self_link = string automatic_connection = optional(bool, false) description = optional(string, "Terraform-managed.") producer_accept_lists = optional(list(string)) producer_reject_lists = optional(list(string)) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [psa_addresses](variables.tf#L102) | Map of internal addresses used for Private Service Access. | <code title="map(object({ address = string network = string prefix_length = number description = optional(string, "Terraform managed.") name = optional(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
| [psa_addresses](variables.tf#L102) | Map of internal addresses used for Private Service Access. | <code title="map(object({ address = string network = string prefix_length = number description = optional(string, "Terraform managed.") name = optional(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [psc_addresses](variables.tf#L115) | Map of internal addresses used for Private Service Connect. | <code title="map(object({ address = string network = string description = optional(string, "Terraform managed.") name = optional(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
| [psc_addresses](variables.tf#L114) | Map of internal addresses used for Private Service Connect. | <code title="map(object({ address = string description = optional(string, "Terraform managed.") name = optional(string) network = optional(string) region = optional(string) subnet_self_link = optional(string) service_attachment = optional(object({ # so we can safely check if service_attachemnt != null in for_each psc_service_attachment_link = string })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
|
|
||||||
## Outputs
|
## Outputs
|
||||||
|
|
||||||
@@ -193,5 +213,6 @@ module "addresses" {
|
|||||||
|
|
||||||
## Fixtures
|
## Fixtures
|
||||||
|
|
||||||
|
- [cloudsql-instance.tf](../../tests/fixtures/cloudsql-instance.tf)
|
||||||
- [net-vpc-ipv6.tf](../../tests/fixtures/net-vpc-ipv6.tf)
|
- [net-vpc-ipv6.tf](../../tests/fixtures/net-vpc-ipv6.tf)
|
||||||
<!-- END TFDOC -->
|
<!-- END TFDOC -->
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2022 Google LLC
|
* Copyright 2024 Google LLC
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -14,20 +14,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
locals {
|
|
||||||
network_attachments = {
|
|
||||||
for k, v in var.network_attachments : k => merge(v, {
|
|
||||||
region = regex("regions/([^/]+)", v.subnet_self_link)[0]
|
|
||||||
# not using the full self link generates a permadiff
|
|
||||||
subnet_self_link = (
|
|
||||||
startswith(v.subnet_self_link, "https://")
|
|
||||||
? v.subnet_self_link
|
|
||||||
: "https://www.googleapis.com/compute/v1/${v.subnet_self_link}"
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "google_compute_global_address" "global" {
|
resource "google_compute_global_address" "global" {
|
||||||
for_each = var.global_addresses
|
for_each = var.global_addresses
|
||||||
project = var.project_id
|
project = var.project_id
|
||||||
@@ -66,18 +52,6 @@ resource "google_compute_address" "internal" {
|
|||||||
subnetwork = each.value.subnetwork
|
subnetwork = each.value.subnetwork
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "google_compute_global_address" "psc" {
|
|
||||||
for_each = var.psc_addresses
|
|
||||||
project = var.project_id
|
|
||||||
name = coalesce(each.value.name, each.key)
|
|
||||||
description = each.value.description
|
|
||||||
address = try(each.value.address, null)
|
|
||||||
address_type = "INTERNAL"
|
|
||||||
network = each.value.network
|
|
||||||
purpose = "PRIVATE_SERVICE_CONNECT"
|
|
||||||
# labels = lookup(var.internal_address_labels, each.key, {})
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "google_compute_global_address" "psa" {
|
resource "google_compute_global_address" "psa" {
|
||||||
for_each = var.psa_addresses
|
for_each = var.psa_addresses
|
||||||
project = var.project_id
|
project = var.project_id
|
||||||
@@ -104,17 +78,3 @@ resource "google_compute_address" "ipsec_interconnect" {
|
|||||||
purpose = "IPSEC_INTERCONNECT"
|
purpose = "IPSEC_INTERCONNECT"
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "google_compute_network_attachment" "default" {
|
|
||||||
provider = google-beta
|
|
||||||
for_each = local.network_attachments
|
|
||||||
project = var.project_id
|
|
||||||
region = each.value.region
|
|
||||||
name = each.key
|
|
||||||
description = each.value.description
|
|
||||||
connection_preference = (
|
|
||||||
each.value.automatic_connection ? "ACCEPT_AUTOMATIC" : "ACCEPT_MANUAL"
|
|
||||||
)
|
|
||||||
subnetworks = [each.value.subnet_self_link]
|
|
||||||
producer_accept_lists = each.value.producer_accept_lists
|
|
||||||
producer_reject_lists = each.value.producer_reject_lists
|
|
||||||
}
|
|
||||||
|
|||||||
102
modules/net-address/psc.tf
Normal file
102
modules/net-address/psc.tf
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
locals {
|
||||||
|
network_attachments = {
|
||||||
|
for k, v in var.network_attachments : k => merge(v, {
|
||||||
|
region = regex("regions/([^/]+)", v.subnet_self_link)[0]
|
||||||
|
# not using the full self link generates a permadiff
|
||||||
|
subnet_self_link = (
|
||||||
|
startswith(v.subnet_self_link, "https://")
|
||||||
|
? v.subnet_self_link
|
||||||
|
: "https://www.googleapis.com/compute/v1/${v.subnet_self_link}"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
regional_psc = {
|
||||||
|
for name, psc in var.psc_addresses : name => psc if psc.region != null
|
||||||
|
|
||||||
|
}
|
||||||
|
global_psc = {
|
||||||
|
for name, psc in var.psc_addresses : name => psc if psc.region == null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_network_attachment" "default" {
|
||||||
|
provider = google-beta
|
||||||
|
for_each = local.network_attachments
|
||||||
|
project = var.project_id
|
||||||
|
region = each.value.region
|
||||||
|
name = each.key
|
||||||
|
description = each.value.description
|
||||||
|
connection_preference = (
|
||||||
|
each.value.automatic_connection ? "ACCEPT_AUTOMATIC" : "ACCEPT_MANUAL"
|
||||||
|
)
|
||||||
|
subnetworks = [each.value.subnet_self_link]
|
||||||
|
producer_accept_lists = each.value.producer_accept_lists
|
||||||
|
producer_reject_lists = each.value.producer_reject_lists
|
||||||
|
}
|
||||||
|
|
||||||
|
# global PSC services
|
||||||
|
resource "google_compute_global_address" "psc" {
|
||||||
|
for_each = local.global_psc
|
||||||
|
project = var.project_id
|
||||||
|
name = coalesce(each.value.name, each.key)
|
||||||
|
description = each.value.description
|
||||||
|
address = try(each.value.address, null)
|
||||||
|
address_type = "INTERNAL"
|
||||||
|
network = each.value.network
|
||||||
|
purpose = "PRIVATE_SERVICE_CONNECT"
|
||||||
|
# labels = lookup(var.internal_address_labels, each.key, {})
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_global_forwarding_rule" "psc_consumer" {
|
||||||
|
for_each = { for name, psc in local.global_psc : name => psc if psc.service_attachment != null }
|
||||||
|
name = coalesce(each.value.name, each.key)
|
||||||
|
project = var.project_id
|
||||||
|
subnetwork = each.value.subnet_self_link
|
||||||
|
ip_address = google_compute_global_address.psc[each.key].self_link
|
||||||
|
load_balancing_scheme = ""
|
||||||
|
target = each.value.service_attachment.psc_service_attachment_link
|
||||||
|
}
|
||||||
|
|
||||||
|
# regional PSC services
|
||||||
|
resource "google_compute_address" "psc" {
|
||||||
|
for_each = local.regional_psc
|
||||||
|
project = var.project_id
|
||||||
|
name = coalesce(each.value.name, each.key)
|
||||||
|
address = try(each.value.address, null)
|
||||||
|
address_type = "INTERNAL"
|
||||||
|
description = each.value.description
|
||||||
|
network = each.value.network
|
||||||
|
# purpose not applicable for regional address
|
||||||
|
# purpose = "PRIVATE_SERVICE_CONNECT"
|
||||||
|
region = each.value.region
|
||||||
|
subnetwork = each.value.subnet_self_link
|
||||||
|
# labels = lookup(var.internal_address_labels, each.key, {})
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_forwarding_rule" "psc_consumer" {
|
||||||
|
for_each = { for name, psc in local.regional_psc : name => psc if psc.service_attachment != null }
|
||||||
|
name = coalesce(each.value.name, each.key)
|
||||||
|
project = var.project_id
|
||||||
|
region = each.value.region
|
||||||
|
subnetwork = each.value.subnet_self_link
|
||||||
|
ip_address = google_compute_address.psc[each.key].self_link
|
||||||
|
load_balancing_scheme = ""
|
||||||
|
recreate_closed_psc = true
|
||||||
|
target = each.value.service_attachment.psc_service_attachment_link
|
||||||
|
}
|
||||||
@@ -107,7 +107,6 @@ variable "psa_addresses" {
|
|||||||
prefix_length = number
|
prefix_length = number
|
||||||
description = optional(string, "Terraform managed.")
|
description = optional(string, "Terraform managed.")
|
||||||
name = optional(string)
|
name = optional(string)
|
||||||
|
|
||||||
}))
|
}))
|
||||||
default = {}
|
default = {}
|
||||||
}
|
}
|
||||||
@@ -115,10 +114,27 @@ variable "psa_addresses" {
|
|||||||
variable "psc_addresses" {
|
variable "psc_addresses" {
|
||||||
description = "Map of internal addresses used for Private Service Connect."
|
description = "Map of internal addresses used for Private Service Connect."
|
||||||
type = map(object({
|
type = map(object({
|
||||||
address = string
|
address = string
|
||||||
network = string
|
description = optional(string, "Terraform managed.")
|
||||||
description = optional(string, "Terraform managed.")
|
name = optional(string)
|
||||||
name = optional(string)
|
network = optional(string)
|
||||||
|
region = optional(string)
|
||||||
|
subnet_self_link = optional(string)
|
||||||
|
service_attachment = optional(object({ # so we can safely check if service_attachemnt != null in for_each
|
||||||
|
psc_service_attachment_link = string
|
||||||
|
}))
|
||||||
}))
|
}))
|
||||||
default = {}
|
default = {}
|
||||||
|
validation {
|
||||||
|
condition = alltrue([for key, value in var.psc_addresses : (value.region != null || (value.region == null && value.network != null))])
|
||||||
|
error_message = "Provide network if creating global PSC addresses / endpoints."
|
||||||
|
}
|
||||||
|
validation {
|
||||||
|
condition = alltrue([for key, value in var.psc_addresses : (value.region == null || (value.region != null && value.subnet_self_link != null))])
|
||||||
|
error_message = "Provide subnet_self_link if creating regional PSC addresses / endpoints."
|
||||||
|
}
|
||||||
|
validation {
|
||||||
|
condition = alltrue([for key, value in var.psc_addresses : !(value.subnet_self_link != null && value.network != null)])
|
||||||
|
error_message = "Do not provide network and subnet_self_link at the same time"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,8 +87,15 @@ class FabricTestItem(pytest.Item):
|
|||||||
self.extra_files = extra_files
|
self.extra_files = extra_files
|
||||||
|
|
||||||
def runtest(self):
|
def runtest(self):
|
||||||
s = plan_validator(self.module, self.inventory, self.parent.path.parent,
|
try:
|
||||||
self.tf_var_files, self.extra_files)
|
summary = plan_validator(self.module, self.inventory, self.parent.path.parent,
|
||||||
|
self.tf_var_files, self.extra_files)
|
||||||
|
except AssertionError:
|
||||||
|
def full_paths(x):
|
||||||
|
return [(self.parent.path.parent / x ) for x in x]
|
||||||
|
print(f'Error in inventory file: {" ".join(full_paths(self.inventory))}')
|
||||||
|
print(f'To regenerate inventory run: python tools/plan_summary.py {self.module} {" ".join(full_paths(self.tf_var_files))}')
|
||||||
|
raise
|
||||||
|
|
||||||
def reportinfo(self):
|
def reportinfo(self):
|
||||||
return self.path, None, self.name
|
return self.path, None, self.name
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ variable "subnet_psc_1" {
|
|||||||
name = "subnet_name"
|
name = "subnet_name"
|
||||||
region = "subnet_region"
|
region = "subnet_region"
|
||||||
cidr = "subnet_cidr"
|
cidr = "subnet_cidr"
|
||||||
self_link = "subnet_self_link"
|
self_link = "https://www.googleapis.com/compute/v1/projects/my-project/regions/europe-west8/subnetworks/subnet"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,12 @@ subnet = {
|
|||||||
cidr = "${subnet.ip_cidr_range}"
|
cidr = "${subnet.ip_cidr_range}"
|
||||||
self_link = "${subnet.self_link}"
|
self_link = "${subnet.self_link}"
|
||||||
}
|
}
|
||||||
|
subnet_psc_1 = {
|
||||||
|
name = "${subnet_psc_1.name}"
|
||||||
|
region = "${subnet_psc_1.region}"
|
||||||
|
cidr = "${subnet_psc_1.ip_cidr_range}"
|
||||||
|
self_link = "${subnet_psc_1.self_link}"
|
||||||
|
}
|
||||||
vpc = {
|
vpc = {
|
||||||
name = "${vpc.name}"
|
name = "${vpc.name}"
|
||||||
self_link = "${vpc.self_link}"
|
self_link = "${vpc.self_link}"
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
locals {
|
locals {
|
||||||
prefix = "${var.prefix}-${var.timestamp}${var.suffix}"
|
prefix = "${var.prefix}-${var.timestamp}${var.suffix}"
|
||||||
jit_services = [
|
jit_services = [
|
||||||
"storage.googleapis.com", # no permissions granted by default
|
"storage.googleapis.com", # no permissions granted by default
|
||||||
|
"sqladmin.googleapis.com", # roles/cloudsql.serviceAgent
|
||||||
]
|
]
|
||||||
services = [
|
services = [
|
||||||
# trimmed down list of services, to be extended as needed
|
# trimmed down list of services, to be extended as needed
|
||||||
@@ -35,6 +36,7 @@ locals {
|
|||||||
"secretmanager.googleapis.com",
|
"secretmanager.googleapis.com",
|
||||||
"servicenetworking.googleapis.com",
|
"servicenetworking.googleapis.com",
|
||||||
"serviceusage.googleapis.com",
|
"serviceusage.googleapis.com",
|
||||||
|
"sqladmin.googleapis.com",
|
||||||
"stackdriver.googleapis.com",
|
"stackdriver.googleapis.com",
|
||||||
"storage-component.googleapis.com",
|
"storage-component.googleapis.com",
|
||||||
"storage.googleapis.com",
|
"storage.googleapis.com",
|
||||||
@@ -114,6 +116,36 @@ resource "google_compute_subnetwork" "proxy_only_regional" {
|
|||||||
role = "ACTIVE"
|
role = "ACTIVE"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "google_compute_subnetwork" "psc" {
|
||||||
|
project = google_project.project.project_id
|
||||||
|
network = google_compute_network.network.name
|
||||||
|
name = "psc-regional"
|
||||||
|
region = var.region
|
||||||
|
ip_cidr_range = "10.0.19.0/24"
|
||||||
|
purpose = "PRIVATE_SERVICE_CONNECT"
|
||||||
|
}
|
||||||
|
|
||||||
|
### PSA ###
|
||||||
|
|
||||||
|
resource "google_compute_global_address" "psa_ranges" {
|
||||||
|
project = google_project.project.project_id
|
||||||
|
network = google_compute_network.network.id
|
||||||
|
name = "psa-range"
|
||||||
|
purpose = "VPC_PEERING"
|
||||||
|
address_type = "INTERNAL"
|
||||||
|
address = "10.0.20.0"
|
||||||
|
prefix_length = 22
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_service_networking_connection" "psa_connection" {
|
||||||
|
network = google_compute_network.network.id
|
||||||
|
service = "servicenetworking.googleapis.com"
|
||||||
|
reserved_peering_ranges = [google_compute_global_address.psa_ranges.name]
|
||||||
|
deletion_policy = "ABANDON"
|
||||||
|
}
|
||||||
|
|
||||||
|
### END OF PSA
|
||||||
|
|
||||||
resource "google_service_account" "service_account" {
|
resource "google_service_account" "service_account" {
|
||||||
account_id = "e2e-service-account"
|
account_id = "e2e-service-account"
|
||||||
project = google_project.project.project_id
|
project = google_project.project.project_id
|
||||||
@@ -141,6 +173,12 @@ resource "google_project_service_identity" "jit_si" {
|
|||||||
depends_on = [google_project_service.project_service]
|
depends_on = [google_project_service.project_service]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "google_project_iam_binding" "cloudsql_agent" {
|
||||||
|
members = ["serviceAccount:service-${google_project.project.number}@gcp-sa-cloud-sql.iam.gserviceaccount.com"]
|
||||||
|
project = google_project.project.project_id
|
||||||
|
role = "roles/cloudsql.serviceAgent"
|
||||||
|
depends_on = [google_project_service_identity.jit_si]
|
||||||
|
}
|
||||||
|
|
||||||
resource "local_file" "terraform_tfvars" {
|
resource "local_file" "terraform_tfvars" {
|
||||||
filename = "e2e_tests.tfvars"
|
filename = "e2e_tests.tfvars"
|
||||||
@@ -168,6 +206,12 @@ resource "local_file" "terraform_tfvars" {
|
|||||||
ip_cidr_range = google_compute_subnetwork.subnetwork.ip_cidr_range
|
ip_cidr_range = google_compute_subnetwork.subnetwork.ip_cidr_range
|
||||||
self_link = google_compute_subnetwork.subnetwork.self_link
|
self_link = google_compute_subnetwork.subnetwork.self_link
|
||||||
}
|
}
|
||||||
|
subnet_psc_1 = {
|
||||||
|
name = google_compute_subnetwork.psc.name
|
||||||
|
region = google_compute_subnetwork.psc.region
|
||||||
|
ip_cidr_range = google_compute_subnetwork.psc.ip_cidr_range
|
||||||
|
self_link = google_compute_subnetwork.psc.self_link
|
||||||
|
}
|
||||||
vpc = {
|
vpc = {
|
||||||
name = google_compute_network.network.name
|
name = google_compute_network.network.name
|
||||||
self_link = google_compute_network.network.self_link
|
self_link = google_compute_network.network.self_link
|
||||||
|
|||||||
@@ -186,8 +186,13 @@ def plan_validator(module_path, inventory_paths, basedir, tf_var_files=None,
|
|||||||
# print(yaml.dump({'counts': summary.counts}))
|
# print(yaml.dump({'counts': summary.counts}))
|
||||||
|
|
||||||
if 'values' in inventory:
|
if 'values' in inventory:
|
||||||
validate_plan_object(inventory['values'], summary.values, relative_path,
|
try:
|
||||||
"")
|
validate_plan_object(inventory['values'], summary.values, relative_path,
|
||||||
|
"")
|
||||||
|
except AssertionError:
|
||||||
|
print(f'\n{path}')
|
||||||
|
print(yaml.dump({'values': summary.values}))
|
||||||
|
raise
|
||||||
|
|
||||||
if 'counts' in inventory:
|
if 'counts' in inventory:
|
||||||
try:
|
try:
|
||||||
@@ -199,6 +204,7 @@ def plan_validator(module_path, inventory_paths, basedir, tf_var_files=None,
|
|||||||
assert plan_count == expected_count, \
|
assert plan_count == expected_count, \
|
||||||
f'{relative_path}: count of {type_} resources failed. Got {plan_count}, expected {expected_count}'
|
f'{relative_path}: count of {type_} resources failed. Got {plan_count}, expected {expected_count}'
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
|
print(f'\n{path}')
|
||||||
print(yaml.dump({'counts': summary.counts}))
|
print(yaml.dump({'counts': summary.counts}))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@@ -218,6 +224,7 @@ def plan_validator(module_path, inventory_paths, basedir, tf_var_files=None,
|
|||||||
f'{relative_path}: output {output_name} failed. Got `{plan_output}`, expected `{expected_output}`'
|
f'{relative_path}: output {output_name} failed. Got `{plan_output}`, expected `{expected_output}`'
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
if _buffer:
|
if _buffer:
|
||||||
|
print(f'\n{path}')
|
||||||
print(yaml.dump(_buffer))
|
print(yaml.dump(_buffer))
|
||||||
raise
|
raise
|
||||||
return summary
|
return summary
|
||||||
|
|||||||
33
tests/fixtures/cloudsql-instance.tf
vendored
Normal file
33
tests/fixtures/cloudsql-instance.tf
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module "cloudsql-instance" {
|
||||||
|
source = "./fabric/modules/cloudsql-instance"
|
||||||
|
project_id = var.project_id
|
||||||
|
network_config = {
|
||||||
|
connectivity = {
|
||||||
|
psc_allowed_consumer_projects = [var.project_id]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
## define a consumer project with an endpoint within the project
|
||||||
|
name = "db"
|
||||||
|
region = var.region
|
||||||
|
availability_type = "REGIONAL"
|
||||||
|
database_version = "POSTGRES_13"
|
||||||
|
tier = "db-g1-small"
|
||||||
|
gcp_deletion_protection = false
|
||||||
|
terraform_deletion_protection = false
|
||||||
|
}
|
||||||
23
tests/fixtures/cloudsql-kms-iam-grant.tf
vendored
Normal file
23
tests/fixtures/cloudsql-kms-iam-grant.tf
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
resource "google_kms_crypto_key_iam_binding" "encrypt_decrypt" {
|
||||||
|
crypto_key_id = var.kms_key.id
|
||||||
|
members = [
|
||||||
|
"serviceAccount:service-${var.project_number}@gcp-sa-cloud-sql.iam.gserviceaccount.com"
|
||||||
|
]
|
||||||
|
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
|
||||||
|
}
|
||||||
@@ -17,11 +17,11 @@ values:
|
|||||||
database_version: POSTGRES_13
|
database_version: POSTGRES_13
|
||||||
name: db
|
name: db
|
||||||
project: project-id
|
project: project-id
|
||||||
region: europe-west1
|
region: europe-west8
|
||||||
settings:
|
settings:
|
||||||
- activation_policy: ALWAYS
|
- activation_policy: ALWAYS
|
||||||
availability_type: ZONAL
|
availability_type: ZONAL
|
||||||
deletion_protection_enabled: true
|
deletion_protection_enabled: false
|
||||||
disk_autoresize: true
|
disk_autoresize: true
|
||||||
disk_type: PD_SSD
|
disk_type: PD_SSD
|
||||||
insights_config:
|
insights_config:
|
||||||
|
|||||||
38
tests/modules/cloudsql_instance/examples/psc.yaml
Normal file
38
tests/modules/cloudsql_instance/examples/psc.yaml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# 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.db.google_sql_database_instance.primary:
|
||||||
|
database_version: POSTGRES_13
|
||||||
|
deletion_protection: false
|
||||||
|
name: myprefix-db
|
||||||
|
project: project-id
|
||||||
|
region: europe-west8
|
||||||
|
settings:
|
||||||
|
- activation_policy: ALWAYS
|
||||||
|
availability_type: REGIONAL
|
||||||
|
deletion_protection_enabled: false
|
||||||
|
ip_configuration:
|
||||||
|
- ipv4_enabled: false
|
||||||
|
private_network: null
|
||||||
|
psc_config:
|
||||||
|
- allowed_consumer_projects:
|
||||||
|
- project-id
|
||||||
|
psc_enabled: true
|
||||||
|
tier: db-g1-small
|
||||||
|
|
||||||
|
counts:
|
||||||
|
google_sql_database_instance: 1
|
||||||
|
modules: 1
|
||||||
|
resources: 1
|
||||||
@@ -17,30 +17,11 @@ values:
|
|||||||
database_version: MYSQL_8_0
|
database_version: MYSQL_8_0
|
||||||
name: db
|
name: db
|
||||||
project: project-id
|
project: project-id
|
||||||
region: europe-west1
|
region: europe-west8
|
||||||
settings:
|
settings:
|
||||||
- activation_policy: ALWAYS
|
- activation_policy: ALWAYS
|
||||||
availability_type: ZONAL
|
availability_type: ZONAL
|
||||||
deletion_protection_enabled: true
|
deletion_protection_enabled: false
|
||||||
disk_autoresize: true
|
|
||||||
disk_type: PD_SSD
|
|
||||||
insights_config: []
|
|
||||||
ip_configuration:
|
|
||||||
- allocated_ip_range: null
|
|
||||||
authorized_networks: []
|
|
||||||
ipv4_enabled: true
|
|
||||||
private_network: projects/xxx/global/networks/aaa
|
|
||||||
tier: db-g1-small
|
|
||||||
module.db.google_sql_database_instance.replicas["replica1"]:
|
|
||||||
database_version: MYSQL_8_0
|
|
||||||
master_instance_name: db
|
|
||||||
name: replica1
|
|
||||||
project: project-id
|
|
||||||
region: europe-west3
|
|
||||||
settings:
|
|
||||||
- activation_policy: ALWAYS
|
|
||||||
availability_type: ZONAL
|
|
||||||
deletion_protection_enabled: true
|
|
||||||
disk_autoresize: true
|
disk_autoresize: true
|
||||||
disk_type: PD_SSD
|
disk_type: PD_SSD
|
||||||
insights_config: []
|
insights_config: []
|
||||||
@@ -52,4 +33,4 @@ values:
|
|||||||
tier: db-g1-small
|
tier: db-g1-small
|
||||||
|
|
||||||
counts:
|
counts:
|
||||||
google_sql_database_instance: 2
|
google_sql_database_instance: 1
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ values:
|
|||||||
database_version: POSTGRES_13
|
database_version: POSTGRES_13
|
||||||
name: myprefix-db
|
name: myprefix-db
|
||||||
project: project-id
|
project: project-id
|
||||||
region: europe-west1
|
region: europe-west8
|
||||||
module.db.google_sql_database_instance.replicas["replica1"]:
|
module.db.google_sql_database_instance.replicas["replica1"]:
|
||||||
clone: []
|
clone: []
|
||||||
database_version: POSTGRES_13
|
database_version: POSTGRES_13
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ values:
|
|||||||
module.db.google_sql_database_instance.primary:
|
module.db.google_sql_database_instance.primary:
|
||||||
clone: []
|
clone: []
|
||||||
database_version: POSTGRES_13
|
database_version: POSTGRES_13
|
||||||
deletion_protection: true
|
deletion_protection: false
|
||||||
name: db
|
name: db
|
||||||
project: my-db-project
|
project: test-db-prj
|
||||||
region: europe-west1
|
region: europe-west8
|
||||||
restore_backup_context: []
|
restore_backup_context: []
|
||||||
root_password: null
|
root_password: null
|
||||||
settings:
|
settings:
|
||||||
@@ -30,7 +30,7 @@ values:
|
|||||||
collation: null
|
collation: null
|
||||||
data_cache_config: []
|
data_cache_config: []
|
||||||
database_flags: []
|
database_flags: []
|
||||||
deletion_protection_enabled: true
|
deletion_protection_enabled: false
|
||||||
deny_maintenance_period: []
|
deny_maintenance_period: []
|
||||||
disk_autoresize: true
|
disk_autoresize: true
|
||||||
disk_autoresize_limit: 0
|
disk_autoresize_limit: 0
|
||||||
@@ -54,25 +54,25 @@ values:
|
|||||||
module.project.google_project.project[0]:
|
module.project.google_project.project[0]:
|
||||||
auto_create_network: false
|
auto_create_network: false
|
||||||
billing_account: 123456-123456-123456
|
billing_account: 123456-123456-123456
|
||||||
folder_id: null
|
folder_id: '1122334455'
|
||||||
labels: null
|
labels: null
|
||||||
name: my-db-project
|
name: test-db-prj
|
||||||
org_id: '1122334455'
|
org_id: null
|
||||||
project_id: my-db-project
|
project_id: test-db-prj
|
||||||
skip_delete: false
|
skip_delete: false
|
||||||
timeouts: null
|
timeouts: null
|
||||||
module.project.google_project_iam_member.servicenetworking[0]:
|
module.project.google_project_iam_member.servicenetworking[0]:
|
||||||
condition: []
|
condition: []
|
||||||
project: my-db-project
|
project: test-db-prj
|
||||||
role: roles/servicenetworking.serviceAgent
|
role: roles/servicenetworking.serviceAgent
|
||||||
module.project.google_project_service.project_services["servicenetworking.googleapis.com"]:
|
module.project.google_project_service.project_services["servicenetworking.googleapis.com"]:
|
||||||
disable_dependent_services: false
|
disable_dependent_services: false
|
||||||
disable_on_destroy: false
|
disable_on_destroy: false
|
||||||
project: my-db-project
|
project: test-db-prj
|
||||||
service: servicenetworking.googleapis.com
|
service: servicenetworking.googleapis.com
|
||||||
timeouts: null
|
timeouts: null
|
||||||
module.project.google_project_service_identity.servicenetworking[0]:
|
module.project.google_project_service_identity.servicenetworking[0]:
|
||||||
project: my-db-project
|
project: test-db-prj
|
||||||
service: servicenetworking.googleapis.com
|
service: servicenetworking.googleapis.com
|
||||||
timeouts: null
|
timeouts: null
|
||||||
module.vpc.google_compute_global_address.psa_ranges["servicenetworking-googleapis-com-cloud-sql"]:
|
module.vpc.google_compute_global_address.psa_ranges["servicenetworking-googleapis-com-cloud-sql"]:
|
||||||
@@ -82,7 +82,7 @@ values:
|
|||||||
ip_version: null
|
ip_version: null
|
||||||
name: servicenetworking-googleapis-com-cloud-sql
|
name: servicenetworking-googleapis-com-cloud-sql
|
||||||
prefix_length: 16
|
prefix_length: 16
|
||||||
project: my-db-project
|
project: test-db-prj
|
||||||
purpose: VPC_PEERING
|
purpose: VPC_PEERING
|
||||||
timeouts: null
|
timeouts: null
|
||||||
module.vpc.google_compute_network.network[0]:
|
module.vpc.google_compute_network.network[0]:
|
||||||
@@ -92,14 +92,14 @@ values:
|
|||||||
enable_ula_internal_ipv6: null
|
enable_ula_internal_ipv6: null
|
||||||
name: my-network
|
name: my-network
|
||||||
network_firewall_policy_enforcement_order: AFTER_CLASSIC_FIREWALL
|
network_firewall_policy_enforcement_order: AFTER_CLASSIC_FIREWALL
|
||||||
project: my-db-project
|
project: test-db-prj
|
||||||
routing_mode: GLOBAL
|
routing_mode: GLOBAL
|
||||||
timeouts: null
|
timeouts: null
|
||||||
module.vpc.google_compute_network_peering_routes_config.psa_routes["servicenetworking.googleapis.com"]:
|
module.vpc.google_compute_network_peering_routes_config.psa_routes["servicenetworking.googleapis.com"]:
|
||||||
export_custom_routes: false
|
export_custom_routes: false
|
||||||
import_custom_routes: false
|
import_custom_routes: false
|
||||||
network: my-network
|
network: my-network
|
||||||
project: my-db-project
|
project: test-db-prj
|
||||||
timeouts: null
|
timeouts: null
|
||||||
module.vpc.google_compute_route.gateway["private-googleapis"]:
|
module.vpc.google_compute_route.gateway["private-googleapis"]:
|
||||||
description: Terraform-managed.
|
description: Terraform-managed.
|
||||||
@@ -111,7 +111,7 @@ values:
|
|||||||
next_hop_instance: null
|
next_hop_instance: null
|
||||||
next_hop_vpn_tunnel: null
|
next_hop_vpn_tunnel: null
|
||||||
priority: 1000
|
priority: 1000
|
||||||
project: my-db-project
|
project: test-db-prj
|
||||||
tags: null
|
tags: null
|
||||||
timeouts: null
|
timeouts: null
|
||||||
module.vpc.google_compute_route.gateway["restricted-googleapis"]:
|
module.vpc.google_compute_route.gateway["restricted-googleapis"]:
|
||||||
@@ -124,11 +124,11 @@ values:
|
|||||||
next_hop_instance: null
|
next_hop_instance: null
|
||||||
next_hop_vpn_tunnel: null
|
next_hop_vpn_tunnel: null
|
||||||
priority: 1000
|
priority: 1000
|
||||||
project: my-db-project
|
project: test-db-prj
|
||||||
tags: null
|
tags: null
|
||||||
timeouts: null
|
timeouts: null
|
||||||
module.vpc.google_service_networking_connection.psa_connection["servicenetworking.googleapis.com"]:
|
module.vpc.google_service_networking_connection.psa_connection["servicenetworking.googleapis.com"]:
|
||||||
deletion_policy: null
|
deletion_policy: ABANDON
|
||||||
reserved_peering_ranges:
|
reserved_peering_ranges:
|
||||||
- servicenetworking-googleapis-com-cloud-sql
|
- servicenetworking-googleapis-com-cloud-sql
|
||||||
service: servicenetworking.googleapis.com
|
service: servicenetworking.googleapis.com
|
||||||
@@ -141,11 +141,11 @@ counts:
|
|||||||
google_compute_route: 2
|
google_compute_route: 2
|
||||||
google_project: 1
|
google_project: 1
|
||||||
google_project_iam_member: 1
|
google_project_iam_member: 1
|
||||||
google_project_service: 1
|
google_project_service: 2
|
||||||
google_project_service_identity: 1
|
google_project_service_identity: 2
|
||||||
google_service_networking_connection: 1
|
google_service_networking_connection: 1
|
||||||
google_sql_database_instance: 1
|
google_sql_database_instance: 1
|
||||||
modules: 3
|
modules: 3
|
||||||
resources: 11
|
resources: 14
|
||||||
|
|
||||||
outputs: {}
|
outputs: {}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# 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.addresses.google_compute_forwarding_rule.psc_consumer["cloudsql-one"]:
|
||||||
|
load_balancing_scheme: ''
|
||||||
|
name: cloudsql-one
|
||||||
|
project: project-id
|
||||||
|
recreate_closed_psc: true
|
||||||
|
region: europe-west8
|
||||||
|
subnetwork: subnet_self_link
|
||||||
|
module.addresses.google_compute_address.psc["cloudsql-one"]:
|
||||||
|
address: 10.0.16.32
|
||||||
|
address_type: INTERNAL
|
||||||
|
description: Terraform managed.
|
||||||
|
name: cloudsql-one
|
||||||
|
project: project-id
|
||||||
|
subnetwork: subnet_self_link
|
||||||
Reference in New Issue
Block a user