Add support for PSC network attachments and interfaces in modules (#2125)
* support network attachments in net-vpc module * support network attachments in net-address module * fix examples * fix examples * add support for psc interfaces to compute-vm module
This commit is contained in:
parent
ef19524b0b
commit
da68d3cfc4
|
@ -25,6 +25,7 @@ In both modes, an optional service account can be created and assigned to either
|
|||
- [Internal and external IPs](#internal-and-external-ips)
|
||||
- [Using Alias IPs](#using-alias-ips)
|
||||
- [Using gVNIC](#using-gvnic)
|
||||
- [PSC interfaces](#psc-interfaces)
|
||||
- [Metadata](#metadata)
|
||||
- [IAM](#iam)
|
||||
- [Spot VM](#spot-vm)
|
||||
|
@ -382,6 +383,40 @@ module "vm-with-gvnic" {
|
|||
# tftest modules=1 resources=3 inventory=gvnic.yaml
|
||||
```
|
||||
|
||||
#### PSC interfaces
|
||||
|
||||
[Private Service Connect interfaces](https://cloud.google.com/vpc/docs/about-private-service-connect-interfaces) can be configured via the `network_attached_interfaces` variable, which is a simple list of network attachment ids, one per interface. PSC interfaces will be defined after regular interfaces.
|
||||
|
||||
```hcl
|
||||
|
||||
# create the network attachment from a service project
|
||||
module "net-attachment" {
|
||||
source = "./fabric/modules/net-address"
|
||||
project_id = "prj-svc"
|
||||
network_attachments = {
|
||||
svc-0 = {
|
||||
subnet_self_link = "projects/prj-host/regions/europe-west8/subnetworks/gce"
|
||||
producer_accept_lists = ["my-vm-project"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module "vm-psc-interface" {
|
||||
source = "./fabric/modules/compute-vm"
|
||||
project_id = "my-vm-project"
|
||||
zone = "europe-west8-b"
|
||||
name = "vm-internal-ip"
|
||||
network_interfaces = [{
|
||||
network = "internal"
|
||||
subnetwork = "internal"
|
||||
}]
|
||||
network_attached_interfaces = [
|
||||
module.net-attachment.network_attachment_ids["svc-0"]
|
||||
]
|
||||
}
|
||||
# tftest modules=2 resources=2
|
||||
```
|
||||
|
||||
### Metadata
|
||||
|
||||
You can define labels and custom metadata values. Metadata can be leveraged, for example, to define a custom startup script.
|
||||
|
@ -773,9 +808,9 @@ module "sole-tenancy" {
|
|||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [name](variables.tf#L235) | Instance name. | <code>string</code> | ✓ | |
|
||||
| [network_interfaces](variables.tf#L240) | Network interfaces configuration. Use self links for Shared VPC, set addresses to null if not needed. | <code title="list(object({ network = string subnetwork = string alias_ips = optional(map(string), {}) nat = optional(bool, false) nic_type = optional(string) stack_type = optional(string) addresses = optional(object({ internal = optional(string) external = optional(string) }), null) }))">list(object({…}))</code> | ✓ | |
|
||||
| [project_id](variables.tf#L282) | Project id. | <code>string</code> | ✓ | |
|
||||
| [zone](variables.tf#L380) | Compute zone. | <code>string</code> | ✓ | |
|
||||
| [network_interfaces](variables.tf#L247) | Network interfaces configuration. Use self links for Shared VPC, set addresses to null if not needed. | <code title="list(object({ network = string subnetwork = string alias_ips = optional(map(string), {}) nat = optional(bool, false) nic_type = optional(string) stack_type = optional(string) addresses = optional(object({ internal = optional(string) external = optional(string) }), null) }))">list(object({…}))</code> | ✓ | |
|
||||
| [project_id](variables.tf#L289) | Project id. | <code>string</code> | ✓ | |
|
||||
| [zone](variables.tf#L387) | Compute zone. | <code>string</code> | ✓ | |
|
||||
| [attached_disk_defaults](variables.tf#L17) | Defaults for attached disks options. | <code title="object({ auto_delete = optional(bool, false) mode = string replica_zone = string type = string })">object({…})</code> | | <code title="{ auto_delete = true mode = "READ_WRITE" replica_zone = null type = "pd-balanced" }">{…}</code> |
|
||||
| [attached_disks](variables.tf#L37) | Additional disks, if options is null defaults will be used in its place. Source type is one of 'image' (zonal disks in vms and template), 'snapshot' (vm), 'existing', and null. | <code title="list(object({ name = string device_name = optional(string) size = string snapshot_schedule = optional(string) source = optional(string) source_type = optional(string) options = optional( object({ auto_delete = optional(bool, false) mode = optional(string, "READ_WRITE") replica_zone = optional(string) type = optional(string, "pd-balanced") }), { auto_delete = true mode = "READ_WRITE" replica_zone = null type = "pd-balanced" } ) }))">list(object({…}))</code> | | <code>[]</code> |
|
||||
| [boot_disk](variables.tf#L83) | Boot disk properties. | <code title="object({ auto_delete = optional(bool, true) snapshot_schedule = optional(string) source = optional(string) initialize_params = optional(object({ image = optional(string, "projects/debian-cloud/global/images/family/debian-11") size = optional(number, 10) type = optional(string, "pd-balanced") })) use_independent_disk = optional(bool, false) })">object({…})</code> | | <code title="{ initialize_params = {} }">{…}</code> |
|
||||
|
@ -793,14 +828,15 @@ module "sole-tenancy" {
|
|||
| [labels](variables.tf#L217) | Instance labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [metadata](variables.tf#L223) | Instance metadata. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [min_cpu_platform](variables.tf#L229) | Minimum CPU platform. | <code>string</code> | | <code>null</code> |
|
||||
| [options](variables.tf#L256) | Instance options. | <code title="object({ allow_stopping_for_update = optional(bool, true) deletion_protection = optional(bool, false) node_affinities = optional(map(object({ values = list(string) in = optional(bool, true) })), {}) spot = optional(bool, false) termination_action = optional(string) })">object({…})</code> | | <code title="{ allow_stopping_for_update = true deletion_protection = false spot = false termination_action = null }">{…}</code> |
|
||||
| [scratch_disks](variables.tf#L287) | Scratch disks configuration. | <code title="object({ count = number interface = string })">object({…})</code> | | <code title="{ count = 0 interface = "NVME" }">{…}</code> |
|
||||
| [service_account](variables.tf#L299) | Service account email and scopes. If email is null, the default Compute service account will be used unless auto_create is true, in which case a service account will be created. Set the variable to null to avoid attaching a service account. | <code title="object({ auto_create = optional(bool, false) email = optional(string) scopes = optional(list(string)) })">object({…})</code> | | <code>{}</code> |
|
||||
| [shielded_config](variables.tf#L309) | Shielded VM configuration of the instances. | <code title="object({ enable_secure_boot = bool enable_vtpm = bool enable_integrity_monitoring = bool })">object({…})</code> | | <code>null</code> |
|
||||
| [snapshot_schedules](variables.tf#L319) | Snapshot schedule resource policies that can be attached to disks. | <code title="map(object({ schedule = object({ daily = optional(object({ days_in_cycle = number start_time = string })) hourly = optional(object({ hours_in_cycle = number start_time = string })) weekly = optional(list(object({ day = string start_time = string }))) }) description = optional(string) retention_policy = optional(object({ max_retention_days = number on_source_disk_delete_keep = optional(bool) })) snapshot_properties = optional(object({ chain_name = optional(string) guest_flush = optional(bool) labels = optional(map(string)) storage_locations = optional(list(string)) })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [tag_bindings](variables.tf#L362) | Resource manager tag bindings for this instance, in tag key => tag value format. | <code>map(string)</code> | | <code>null</code> |
|
||||
| [tag_bindings_firewall](variables.tf#L368) | Firewall (network scoped) tag bindings for this instance, in tag key => tag value format. | <code>map(string)</code> | | <code>null</code> |
|
||||
| [tags](variables.tf#L374) | Instance network tags for firewall rule targets. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [network_attached_interfaces](variables.tf#L240) | Network interfaces using network attachments. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [options](variables.tf#L263) | Instance options. | <code title="object({ allow_stopping_for_update = optional(bool, true) deletion_protection = optional(bool, false) node_affinities = optional(map(object({ values = list(string) in = optional(bool, true) })), {}) spot = optional(bool, false) termination_action = optional(string) })">object({…})</code> | | <code title="{ allow_stopping_for_update = true deletion_protection = false spot = false termination_action = null }">{…}</code> |
|
||||
| [scratch_disks](variables.tf#L294) | Scratch disks configuration. | <code title="object({ count = number interface = string })">object({…})</code> | | <code title="{ count = 0 interface = "NVME" }">{…}</code> |
|
||||
| [service_account](variables.tf#L306) | Service account email and scopes. If email is null, the default Compute service account will be used unless auto_create is true, in which case a service account will be created. Set the variable to null to avoid attaching a service account. | <code title="object({ auto_create = optional(bool, false) email = optional(string) scopes = optional(list(string)) })">object({…})</code> | | <code>{}</code> |
|
||||
| [shielded_config](variables.tf#L316) | Shielded VM configuration of the instances. | <code title="object({ enable_secure_boot = bool enable_vtpm = bool enable_integrity_monitoring = bool })">object({…})</code> | | <code>null</code> |
|
||||
| [snapshot_schedules](variables.tf#L326) | Snapshot schedule resource policies that can be attached to disks. | <code title="map(object({ schedule = object({ daily = optional(object({ days_in_cycle = number start_time = string })) hourly = optional(object({ hours_in_cycle = number start_time = string })) weekly = optional(list(object({ day = string start_time = string }))) }) description = optional(string) retention_policy = optional(object({ max_retention_days = number on_source_disk_delete_keep = optional(bool) })) snapshot_properties = optional(object({ chain_name = optional(string) guest_flush = optional(bool) labels = optional(map(string)) storage_locations = optional(list(string)) })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [tag_bindings](variables.tf#L369) | Resource manager tag bindings for this instance, in tag key => tag value format. | <code>map(string)</code> | | <code>null</code> |
|
||||
| [tag_bindings_firewall](variables.tf#L375) | Firewall (network scoped) tag bindings for this instance, in tag key => tag value format. | <code>map(string)</code> | | <code>null</code> |
|
||||
| [tags](variables.tf#L381) | Instance network tags for firewall rule targets. | <code>list(string)</code> | | <code>[]</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -267,6 +267,13 @@ resource "google_compute_instance" "default" {
|
|||
}
|
||||
}
|
||||
|
||||
dynamic "network_interface" {
|
||||
for_each = var.network_attached_interfaces
|
||||
content {
|
||||
network_attachment = network_interface.value
|
||||
}
|
||||
}
|
||||
|
||||
scheduling {
|
||||
automatic_restart = !var.options.spot
|
||||
instance_termination_action = local.termination_action
|
||||
|
@ -425,6 +432,13 @@ resource "google_compute_instance_template" "default" {
|
|||
}
|
||||
}
|
||||
|
||||
dynamic "network_interface" {
|
||||
for_each = var.network_attached_interfaces
|
||||
content {
|
||||
network_attachment = network_interface.value
|
||||
}
|
||||
}
|
||||
|
||||
scheduling {
|
||||
automatic_restart = !var.options.spot
|
||||
instance_termination_action = local.termination_action
|
||||
|
|
|
@ -237,6 +237,13 @@ variable "name" {
|
|||
type = string
|
||||
}
|
||||
|
||||
variable "network_attached_interfaces" {
|
||||
description = "Network interfaces using network attachments."
|
||||
type = list(string)
|
||||
nullable = false
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "network_interfaces" {
|
||||
description = "Network interfaces configuration. Use self links for Shared VPC, set addresses to null if not needed."
|
||||
type = list(object({
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
# Net Address Reservation Module
|
||||
|
||||
This module allows reserving Compute Engine external, global, and internal addresses.
|
||||
This module allows reserving Compute Engine external, global, and internal addresses. The module also supports managing VPC network attachments from service projects.
|
||||
|
||||
<!-- BEGIN TOC -->
|
||||
- [Examples](#examples)
|
||||
- [External and global addresses](#external-and-global-addresses)
|
||||
- [Internal addresses](#internal-addresses)
|
||||
- [IPv6 addresses](#ipv6-addresses)
|
||||
- [PSA addresses](#psa-addresses)
|
||||
- [PSC addresses](#psc-addresses)
|
||||
- [IPSec Interconnect addresses](#ipsec-interconnect-addresses)
|
||||
- [PSC Network Attachments](#psc-network-attachments)
|
||||
- [Variables](#variables)
|
||||
- [Outputs](#outputs)
|
||||
- [Fixtures](#fixtures)
|
||||
<!-- END TOC -->
|
||||
|
||||
## Examples
|
||||
|
||||
|
@ -108,7 +122,7 @@ module "addresses" {
|
|||
# tftest modules=1 resources=1 inventory=psc.yaml e2e
|
||||
```
|
||||
|
||||
# IPSec Interconnect addresses
|
||||
### IPSec Interconnect addresses
|
||||
|
||||
```hcl
|
||||
module "addresses" {
|
||||
|
@ -131,18 +145,39 @@ module "addresses" {
|
|||
}
|
||||
# tftest modules=1 resources=2 inventory=ipsec-interconnect.yaml e2e
|
||||
```
|
||||
|
||||
### PSC Network Attachments
|
||||
|
||||
The project where the network attachment is created must be either the VPC project, or a Shared VPC service project of the host owning the VPC.
|
||||
|
||||
```hcl
|
||||
module "addresses" {
|
||||
source = "./fabric/modules/net-address"
|
||||
project_id = var.project_id
|
||||
network_attachments = {
|
||||
gce-0 = {
|
||||
subnet_self_link = (
|
||||
"projects/net-host/regions/europe-west8/subnetworks/gce"
|
||||
)
|
||||
producer_accept_lists = [var.project_id]
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=1 inventory=network-attachments.yaml
|
||||
```
|
||||
<!-- BEGIN TFDOC -->
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [project_id](variables.tf#L84) | Project where the addresses will be created. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L97) | Project where the addresses will be created. | <code>string</code> | ✓ | |
|
||||
| [external_addresses](variables.tf#L17) | Map of external addresses, keyed by name. | <code title="map(object({ region = string description = optional(string, "Terraform managed.") ipv6 = optional(object({ endpoint_type = string })) labels = optional(map(string), {}) name = optional(string) subnetwork = optional(string) # for IPv6 tier = optional(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [global_addresses](variables.tf#L40) | List of global addresses to create. | <code title="map(object({ description = optional(string, "Terraform managed.") ipv6 = optional(map(string)) # To be left empty for ipv6 name = 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> |
|
||||
| [psa_addresses](variables.tf#L89) | 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#L102) | 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> |
|
||||
| [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> |
|
||||
| [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> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
@ -152,8 +187,9 @@ module "addresses" {
|
|||
| [global_addresses](outputs.tf#L25) | Allocated global external addresses. | |
|
||||
| [internal_addresses](outputs.tf#L33) | Allocated internal addresses. | |
|
||||
| [ipsec_interconnect_addresses](outputs.tf#L41) | Allocated internal addresses for HA VPN over Cloud Interconnect. | |
|
||||
| [psa_addresses](outputs.tf#L49) | Allocated internal addresses for PSA endpoints. | |
|
||||
| [psc_addresses](outputs.tf#L57) | Allocated internal addresses for PSC endpoints. | |
|
||||
| [network_attachment_ids](outputs.tf#L49) | IDs of network attachments. | |
|
||||
| [psa_addresses](outputs.tf#L57) | Allocated internal addresses for PSA endpoints. | |
|
||||
| [psc_addresses](outputs.tf#L65) | Allocated internal addresses for PSC endpoints. | |
|
||||
|
||||
## Fixtures
|
||||
|
||||
|
|
|
@ -14,6 +14,20 @@
|
|||
* 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" {
|
||||
for_each = var.global_addresses
|
||||
project = var.project_id
|
||||
|
@ -89,3 +103,18 @@ resource "google_compute_address" "ipsec_interconnect" {
|
|||
prefix_length = each.value.prefix_length
|
||||
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
|
||||
}
|
||||
|
|
|
@ -46,6 +46,14 @@ output "ipsec_interconnect_addresses" {
|
|||
}
|
||||
}
|
||||
|
||||
output "network_attachment_ids" {
|
||||
description = "IDs of network attachments."
|
||||
value = {
|
||||
for k, v in google_compute_network_attachment.default :
|
||||
k => v.id
|
||||
}
|
||||
}
|
||||
|
||||
output "psa_addresses" {
|
||||
description = "Allocated internal addresses for PSA endpoints."
|
||||
value = {
|
||||
|
@ -60,4 +68,4 @@ output "psc_addresses" {
|
|||
for address in google_compute_global_address.psc :
|
||||
address.name => address
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,6 +81,19 @@ variable "ipsec_interconnect_addresses" {
|
|||
# default = {}
|
||||
# }
|
||||
|
||||
variable "network_attachments" {
|
||||
description = "PSC network attachments, names as keys."
|
||||
type = 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))
|
||||
}))
|
||||
nullable = false
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Project where the addresses will be created."
|
||||
type = string
|
||||
|
|
|
@ -14,6 +14,7 @@ This module allows creation and management of VPC networks including subnetworks
|
|||
- [Private Service Networking](#private-service-networking)
|
||||
- [Private Service Networking with peering routes and peered Cloud DNS domains](#private-service-networking-with-peering-routes-and-peered-cloud-dns-domains)
|
||||
- [Subnets for Private Service Connect, Proxy-only subnets](#subnets-for-private-service-connect-proxy-only-subnets)
|
||||
- [PSC Network Attachments](#psc-network-attachments)
|
||||
- [DNS Policies](#dns-policies)
|
||||
- [Subnet Factory](#subnet-factory)
|
||||
- [Custom Routes](#custom-routes)
|
||||
|
@ -318,6 +319,43 @@ module "vpc" {
|
|||
# tftest modules=1 resources=6 inventory=proxy-only-subnets.yaml e2e
|
||||
```
|
||||
|
||||
### PSC Network Attachments
|
||||
|
||||
[Network attachments](https://cloud.google.com/vpc/docs/about-network-attachments) are only supported for subnets directly managed by the module. To create network attachments in service projects, refer to the [`net-address`](../net-address/) module documentation.
|
||||
|
||||
```hcl
|
||||
module "vpc" {
|
||||
source = "./fabric/modules/net-vpc"
|
||||
project_id = var.project_id
|
||||
name = "my-network"
|
||||
network_attachments = {
|
||||
prod-ew1 = {
|
||||
subnet = "europe-west1/production"
|
||||
producer_accept_lists = [
|
||||
"my-project-1"
|
||||
]
|
||||
}
|
||||
prod-ew2 = {
|
||||
subnet = "europe-west2/production"
|
||||
automatic_connection = true
|
||||
}
|
||||
}
|
||||
subnets = [
|
||||
{
|
||||
ip_cidr_range = "10.0.0.0/24"
|
||||
name = "production"
|
||||
region = "europe-west1"
|
||||
},
|
||||
{
|
||||
ip_cidr_range = "10.0.16.0/24"
|
||||
name = "production"
|
||||
region = "europe-west2"
|
||||
}
|
||||
]
|
||||
}
|
||||
# tftest modules=1 resources=7 inventory=network-attachments.yaml
|
||||
```
|
||||
|
||||
### DNS Policies
|
||||
|
||||
```hcl
|
||||
|
@ -576,7 +614,7 @@ module "vpc" {
|
|||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [name](variables.tf#L95) | The name of the network being created. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L159) | The ID of the project where this VPC will be created. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L172) | The ID of the project where this VPC will be created. | <code>string</code> | ✓ | |
|
||||
| [auto_create_subnetworks](variables.tf#L17) | Set to true to create an auto mode subnet, defaults to custom mode. | <code>bool</code> | | <code>false</code> |
|
||||
| [create_googleapis_routes](variables.tf#L23) | Toggle creation of googleapis private/restricted routes. Disabled when vpc creation is turned off, or when set to null. | <code title="object({ private = optional(bool, true) private-6 = optional(bool, false) restricted = optional(bool, true) restricted-6 = optional(bool, false) })">object({…})</code> | | <code>{}</code> |
|
||||
| [delete_default_routes_on_create](variables.tf#L34) | Set to true to delete the default routes at creation time. | <code>bool</code> | | <code>false</code> |
|
||||
|
@ -586,17 +624,18 @@ module "vpc" {
|
|||
| [firewall_policy_enforcement_order](variables.tf#L67) | Order that Firewall Rules and Firewall Policies are evaluated. Can be either 'BEFORE_CLASSIC_FIREWALL' or 'AFTER_CLASSIC_FIREWALL'. | <code>string</code> | | <code>"AFTER_CLASSIC_FIREWALL"</code> |
|
||||
| [ipv6_config](variables.tf#L79) | Optional IPv6 configuration for this network. | <code title="object({ enable_ula_internal = optional(bool) internal_range = optional(string) })">object({…})</code> | | <code>{}</code> |
|
||||
| [mtu](variables.tf#L89) | Maximum Transmission Unit in bytes. The minimum value for this field is 1460 (the default) and the maximum value is 1500 bytes. | <code>number</code> | | <code>null</code> |
|
||||
| [peering_config](variables.tf#L100) | VPC peering configuration. | <code title="object({ peer_vpc_self_link = string create_remote_peer = optional(bool, true) export_routes = optional(bool) import_routes = optional(bool) })">object({…})</code> | | <code>null</code> |
|
||||
| [policy_based_routes](variables.tf#L111) | Policy based routes, keyed by name. | <code title="map(object({ description = optional(string, "Terraform-managed.") labels = optional(map(string)) priority = optional(number) next_hop_ilb_ip = optional(string) use_default_routing = optional(bool, false) filter = optional(object({ ip_protocol = optional(string) dest_range = optional(string) src_range = optional(string) }), {}) target = optional(object({ interconnect_attachment = optional(string) tags = optional(list(string)) }), {}) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [psa_config](variables.tf#L164) | The Private Service Access configuration for Service Networking. | <code title="object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) })">object({…})</code> | | <code>null</code> |
|
||||
| [routes](variables.tf#L175) | Network routes, keyed by name. | <code title="map(object({ description = optional(string, "Terraform-managed.") dest_range = string next_hop_type = string # gateway, instance, ip, vpn_tunnel, ilb next_hop = string priority = optional(number) tags = optional(list(string)) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [routing_mode](variables.tf#L196) | The network routing mode (default 'GLOBAL'). | <code>string</code> | | <code>"GLOBAL"</code> |
|
||||
| [shared_vpc_host](variables.tf#L206) | Enable shared VPC for this project. | <code>bool</code> | | <code>false</code> |
|
||||
| [shared_vpc_service_projects](variables.tf#L212) | Shared VPC service projects to register with this host. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [subnets](variables.tf#L218) | Subnet configuration. | <code title="list(object({ name = string ip_cidr_range = string region = string description = optional(string) enable_private_access = optional(bool, true) flow_logs_config = optional(object({ aggregation_interval = optional(string) filter_expression = optional(string) flow_sampling = optional(number) metadata = optional(string) metadata_fields = optional(list(string)) })) ipv6 = optional(object({ access_type = optional(string, "INTERNAL") })) secondary_ip_ranges = optional(map(string)) iam = optional(map(list(string)), {}) iam_bindings = optional(map(object({ role = string members = list(string) condition = optional(object({ expression = string title = string description = optional(string) })) })), {}) iam_bindings_additive = optional(map(object({ member = string role = string condition = optional(object({ expression = string title = string description = optional(string) })) })), {}) }))">list(object({…}))</code> | | <code>[]</code> |
|
||||
| [subnets_proxy_only](variables.tf#L265) | List of proxy-only subnets for Regional HTTPS or Internal HTTPS load balancers. Note: Only one proxy-only subnet for each VPC network in each region can be active. | <code title="list(object({ name = string ip_cidr_range = string region = string description = optional(string) active = optional(bool, true) global = optional(bool, false) iam = optional(map(list(string)), {}) iam_bindings = optional(map(object({ role = string members = list(string) condition = optional(object({ expression = string title = string description = optional(string) })) })), {}) iam_bindings_additive = optional(map(object({ member = string role = string condition = optional(object({ expression = string title = string description = optional(string) })) })), {}) }))">list(object({…}))</code> | | <code>[]</code> |
|
||||
| [subnets_psc](variables.tf#L299) | List of subnets for Private Service Connect service producers. | <code title="list(object({ name = string ip_cidr_range = string region = string description = optional(string) iam = optional(map(list(string)), {}) iam_bindings = optional(map(object({ role = string members = list(string) condition = optional(object({ expression = string title = string description = optional(string) })) })), {}) iam_bindings_additive = optional(map(object({ member = string role = string condition = optional(object({ expression = string title = string description = optional(string) })) })), {}) }))">list(object({…}))</code> | | <code>[]</code> |
|
||||
| [vpc_create](variables.tf#L331) | Create VPC. When set to false, uses a data source to reference existing VPC. | <code>bool</code> | | <code>true</code> |
|
||||
| [network_attachments](variables.tf#L100) | PSC network attachments, names as keys. | <code title="map(object({ subnet = 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> |
|
||||
| [peering_config](variables.tf#L113) | VPC peering configuration. | <code title="object({ peer_vpc_self_link = string create_remote_peer = optional(bool, true) export_routes = optional(bool) import_routes = optional(bool) })">object({…})</code> | | <code>null</code> |
|
||||
| [policy_based_routes](variables.tf#L124) | Policy based routes, keyed by name. | <code title="map(object({ description = optional(string, "Terraform-managed.") labels = optional(map(string)) priority = optional(number) next_hop_ilb_ip = optional(string) use_default_routing = optional(bool, false) filter = optional(object({ ip_protocol = optional(string) dest_range = optional(string) src_range = optional(string) }), {}) target = optional(object({ interconnect_attachment = optional(string) tags = optional(list(string)) }), {}) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [psa_config](variables.tf#L177) | The Private Service Access configuration for Service Networking. | <code title="object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) })">object({…})</code> | | <code>null</code> |
|
||||
| [routes](variables.tf#L188) | Network routes, keyed by name. | <code title="map(object({ description = optional(string, "Terraform-managed.") dest_range = string next_hop_type = string # gateway, instance, ip, vpn_tunnel, ilb next_hop = string priority = optional(number) tags = optional(list(string)) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [routing_mode](variables.tf#L209) | The network routing mode (default 'GLOBAL'). | <code>string</code> | | <code>"GLOBAL"</code> |
|
||||
| [shared_vpc_host](variables.tf#L219) | Enable shared VPC for this project. | <code>bool</code> | | <code>false</code> |
|
||||
| [shared_vpc_service_projects](variables.tf#L225) | Shared VPC service projects to register with this host. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [subnets](variables.tf#L231) | Subnet configuration. | <code title="list(object({ name = string ip_cidr_range = string region = string description = optional(string) enable_private_access = optional(bool, true) flow_logs_config = optional(object({ aggregation_interval = optional(string) filter_expression = optional(string) flow_sampling = optional(number) metadata = optional(string) metadata_fields = optional(list(string)) })) ipv6 = optional(object({ access_type = optional(string, "INTERNAL") })) secondary_ip_ranges = optional(map(string)) iam = optional(map(list(string)), {}) iam_bindings = optional(map(object({ role = string members = list(string) condition = optional(object({ expression = string title = string description = optional(string) })) })), {}) iam_bindings_additive = optional(map(object({ member = string role = string condition = optional(object({ expression = string title = string description = optional(string) })) })), {}) }))">list(object({…}))</code> | | <code>[]</code> |
|
||||
| [subnets_proxy_only](variables.tf#L278) | List of proxy-only subnets for Regional HTTPS or Internal HTTPS load balancers. Note: Only one proxy-only subnet for each VPC network in each region can be active. | <code title="list(object({ name = string ip_cidr_range = string region = string description = optional(string) active = optional(bool, true) global = optional(bool, false) iam = optional(map(list(string)), {}) iam_bindings = optional(map(object({ role = string members = list(string) condition = optional(object({ expression = string title = string description = optional(string) })) })), {}) iam_bindings_additive = optional(map(object({ member = string role = string condition = optional(object({ expression = string title = string description = optional(string) })) })), {}) }))">list(object({…}))</code> | | <code>[]</code> |
|
||||
| [subnets_psc](variables.tf#L312) | List of subnets for Private Service Connect service producers. | <code title="list(object({ name = string ip_cidr_range = string region = string description = optional(string) iam = optional(map(list(string)), {}) iam_bindings = optional(map(object({ role = string members = list(string) condition = optional(object({ expression = string title = string description = optional(string) })) })), {}) iam_bindings_additive = optional(map(object({ member = string role = string condition = optional(object({ expression = string title = string description = optional(string) })) })), {}) }))">list(object({…}))</code> | | <code>[]</code> |
|
||||
| [vpc_create](variables.tf#L344) | Create VPC. When set to false, uses a data source to reference existing VPC. | <code>bool</code> | | <code>true</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
@ -606,15 +645,16 @@ module "vpc" {
|
|||
| [internal_ipv6_range](outputs.tf#L29) | ULA range. | |
|
||||
| [name](outputs.tf#L34) | Network name. | |
|
||||
| [network](outputs.tf#L46) | Network resource. | |
|
||||
| [project_id](outputs.tf#L58) | Project ID containing the network. Use this when you need to create resources *after* the VPC is fully set up (e.g. subnets created, shared VPC service projects attached, Private Service Networking configured). | |
|
||||
| [self_link](outputs.tf#L71) | Network self link. | |
|
||||
| [subnet_ids](outputs.tf#L83) | Map of subnet IDs keyed by name. | |
|
||||
| [subnet_ips](outputs.tf#L92) | Map of subnet address ranges keyed by name. | |
|
||||
| [subnet_ipv6_external_prefixes](outputs.tf#L99) | Map of subnet external IPv6 prefixes keyed by name. | |
|
||||
| [subnet_regions](outputs.tf#L107) | Map of subnet regions keyed by name. | |
|
||||
| [subnet_secondary_ranges](outputs.tf#L114) | Map of subnet secondary ranges keyed by name. | |
|
||||
| [subnet_self_links](outputs.tf#L125) | Map of subnet self links keyed by name. | |
|
||||
| [subnets](outputs.tf#L134) | Subnet resources. | |
|
||||
| [subnets_proxy_only](outputs.tf#L143) | L7 ILB or L7 Regional LB subnet resources. | |
|
||||
| [subnets_psc](outputs.tf#L148) | Private Service Connect subnet resources. | |
|
||||
| [network_attachment_ids](outputs.tf#L58) | IDs of network attachments. | |
|
||||
| [project_id](outputs.tf#L66) | Project ID containing the network. Use this when you need to create resources *after* the VPC is fully set up (e.g. subnets created, shared VPC service projects attached, Private Service Networking configured). | |
|
||||
| [self_link](outputs.tf#L79) | Network self link. | |
|
||||
| [subnet_ids](outputs.tf#L91) | Map of subnet IDs keyed by name. | |
|
||||
| [subnet_ips](outputs.tf#L100) | Map of subnet address ranges keyed by name. | |
|
||||
| [subnet_ipv6_external_prefixes](outputs.tf#L107) | Map of subnet external IPv6 prefixes keyed by name. | |
|
||||
| [subnet_regions](outputs.tf#L115) | Map of subnet regions keyed by name. | |
|
||||
| [subnet_secondary_ranges](outputs.tf#L122) | Map of subnet secondary ranges keyed by name. | |
|
||||
| [subnet_self_links](outputs.tf#L133) | Map of subnet self links keyed by name. | |
|
||||
| [subnets](outputs.tf#L142) | Subnet resources. | |
|
||||
| [subnets_proxy_only](outputs.tf#L151) | L7 ILB or L7 Regional LB subnet resources. | |
|
||||
| [subnets_psc](outputs.tf#L156) | Private Service Connect subnet resources. | |
|
||||
<!-- END TFDOC -->
|
||||
|
|
|
@ -55,6 +55,14 @@ output "network" {
|
|||
]
|
||||
}
|
||||
|
||||
output "network_attachment_ids" {
|
||||
description = "IDs of network attachments."
|
||||
value = {
|
||||
for k, v in google_compute_network_attachment.default :
|
||||
k => v.id
|
||||
}
|
||||
}
|
||||
|
||||
output "project_id" {
|
||||
description = "Project ID containing the network. Use this when you need to create resources *after* the VPC is fully set up (e.g. subnets created, shared VPC service projects attached, Private Service Networking configured)."
|
||||
value = var.project_id
|
||||
|
|
|
@ -251,3 +251,20 @@ resource "google_compute_subnetwork_iam_member" "bindings" {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_network_attachment" "default" {
|
||||
provider = google-beta
|
||||
for_each = var.network_attachments
|
||||
project = var.project_id
|
||||
region = google_compute_subnetwork.subnetwork[each.value.subnet].region
|
||||
name = each.key
|
||||
description = each.value.description
|
||||
connection_preference = (
|
||||
each.value.automatic_connection ? "ACCEPT_AUTOMATIC" : "ACCEPT_MANUAL"
|
||||
)
|
||||
subnetworks = [
|
||||
google_compute_subnetwork.subnetwork[each.value.subnet].self_link
|
||||
]
|
||||
producer_accept_lists = each.value.producer_accept_lists
|
||||
producer_reject_lists = each.value.producer_reject_lists
|
||||
}
|
||||
|
|
|
@ -97,6 +97,19 @@ variable "name" {
|
|||
type = string
|
||||
}
|
||||
|
||||
variable "network_attachments" {
|
||||
description = "PSC network attachments, names as keys."
|
||||
type = map(object({
|
||||
subnet = string
|
||||
automatic_connection = optional(bool, false)
|
||||
description = optional(string, "Terraform-managed.")
|
||||
producer_accept_lists = optional(list(string))
|
||||
producer_reject_lists = optional(list(string))
|
||||
}))
|
||||
nullable = false
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "peering_config" {
|
||||
description = "VPC peering configuration."
|
||||
type = object({
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# 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_network_attachment.default["gce-0"]:
|
||||
connection_preference: ACCEPT_MANUAL
|
||||
description: Terraform-managed.
|
||||
name: gce-0
|
||||
producer_accept_lists:
|
||||
- project-id
|
||||
producer_reject_lists: null
|
||||
project: project-id
|
||||
region: europe-west8
|
||||
subnetworks:
|
||||
- https://www.googleapis.com/compute/v1/projects/net-host/regions/europe-west8/subnetworks/gce
|
||||
timeouts: null
|
||||
|
||||
counts:
|
||||
google_compute_network_attachment: 1
|
||||
modules: 1
|
||||
resources: 1
|
||||
|
||||
outputs: {}
|
|
@ -0,0 +1,44 @@
|
|||
# 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.vpc.google_compute_network_attachment.default["prod-ew1"]:
|
||||
connection_preference: ACCEPT_MANUAL
|
||||
description: Terraform-managed.
|
||||
name: prod-ew1
|
||||
producer_accept_lists:
|
||||
- my-project-1
|
||||
producer_reject_lists: null
|
||||
project: project-id
|
||||
region: europe-west1
|
||||
timeouts: null
|
||||
module.vpc.google_compute_network_attachment.default["prod-ew2"]:
|
||||
connection_preference: ACCEPT_AUTOMATIC
|
||||
description: Terraform-managed.
|
||||
name: prod-ew2
|
||||
producer_accept_lists: null
|
||||
producer_reject_lists: null
|
||||
project: project-id
|
||||
region: europe-west2
|
||||
timeouts: null
|
||||
|
||||
counts:
|
||||
google_compute_network: 1
|
||||
google_compute_network_attachment: 2
|
||||
google_compute_route: 2
|
||||
google_compute_subnetwork: 2
|
||||
modules: 1
|
||||
resources: 7
|
||||
|
||||
outputs: {}
|
Loading…
Reference in New Issue