diff --git a/docs/upgrading_to_v13.0.0.md b/docs/upgrading_to_v13.0.0.md new file mode 100644 index 000000000..0a74159fa --- /dev/null +++ b/docs/upgrading_to_v13.0.0.md @@ -0,0 +1,6 @@ +# Upgrading to v13.0.0 + +The v13.0 release contains backwards-incompatible changes. + +This update requires upgrading: +- minimum provider version of `hashicorp/google` to `7.8` for network-connectivity-center sub-module. diff --git a/examples/network_connectivity_center/main.tf b/examples/network_connectivity_center/main.tf index 3a14c0674..1e19d0b61 100644 --- a/examples/network_connectivity_center/main.tf +++ b/examples/network_connectivity_center/main.tf @@ -16,17 +16,14 @@ module "network_connectivity_center" { source = "terraform-google-modules/network/google//modules/network-connectivity-center" - version = "~> 12.0" + version = "~> 13.0" + project_id = var.project_id ncc_hub_name = var.ncc_hub_name ncc_hub_labels = { "module" = "ncc" } - spoke_labels = { - "created-by" = "terraform-google-ncc-example" - } - vpc_spokes = { "vpc-1" = { uri = module.vpc_spoke_vpc.network_id @@ -76,6 +73,36 @@ module "network_connectivity_center" { } } +module "network_connectivity_center_star" { + source = "terraform-google-modules/network/google//modules/network-connectivity-center" + version = "~> 13.0" + + project_id = var.project_id + ncc_hub_name = "${var.ncc_hub_name}-star" + ncc_hub_labels = { + "module" = "ncc" + } + ncc_hub_preset_topology = "STAR" + ncc_groups = { + "center" = { + name = "center" + labels = { + "module" = "ncc" + } + } + "edge" = { + name = "edge" + auto_accept_projects = [ + "foo", + "bar" + ] + } + } + spoke_labels = { + "created-by" = "terraform-google-ncc-example" + } +} + ################################ # VPC Spoke # ################################ diff --git a/examples/network_connectivity_center/outputs.tf b/examples/network_connectivity_center/outputs.tf index 1ac306ba6..ab331c276 100644 --- a/examples/network_connectivity_center/outputs.tf +++ b/examples/network_connectivity_center/outputs.tf @@ -29,7 +29,6 @@ output "vpc_spokes" { value = module.network_connectivity_center.vpc_spokes } - output "hybrid_spokes" { description = "All hybrid spoke objects" value = module.network_connectivity_center.hybrid_spokes @@ -44,3 +43,13 @@ output "spokes" { description = "All spoke objects prefixed with the type of spoke (vpc, hybrid, appliance)" value = module.network_connectivity_center.spokes } + +output "ncc_hub_name_star" { + description = "Name of the NCC Hub (required for testing)" + value = element(reverse(split("/", module.network_connectivity_center_star.ncc_hub.name)), 0) +} + +output "groups" { + description = "All spoke objects prefixed with the type of spoke (vpc, hybrid, appliance)" + value = module.network_connectivity_center_star.groups +} diff --git a/examples/network_connectivity_center/versions.tf b/examples/network_connectivity_center/versions.tf deleted file mode 100644 index 8aedf1350..000000000 --- a/examples/network_connectivity_center/versions.tf +++ /dev/null @@ -1,27 +0,0 @@ -/** - * 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. - */ - -terraform { - required_version = ">=1.3.0" - - required_providers { - google = { - source = "hashicorp/google" - version = ">= 6.49" - - } - } -} diff --git a/modules/network-connectivity-center/README.md b/modules/network-connectivity-center/README.md index 423372080..2d999c4de 100644 --- a/modules/network-connectivity-center/README.md +++ b/modules/network-connectivity-center/README.md @@ -23,19 +23,23 @@ An extensive example that also contains the creation and attachment of multiple | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | export\_psc | Whether Private Service Connect transitivity is enabled for the hub | `bool` | `false` | no | -| hybrid\_spokes | VLAN attachments and VPN Tunnels that are associated with the spoke. Type must be one of `interconnect` and `vpn`. |
map(object({
location = string
uris = set(string)
site_to_site_data_transfer = optional(bool, false)
type = string
description = optional(string)
labels = optional(map(string))
include_import_ranges = optional(list(string), [])
}))
| `{}` | no | +| hybrid\_spokes | VLAN attachments and VPN Tunnels that are associated with the spoke. Type must be one of `interconnect` and `vpn`. |
map(object({
location = string
uris = set(string)
site_to_site_data_transfer = optional(bool, false)
type = string
description = optional(string)
labels = optional(map(string))
include_import_ranges = optional(list(string), [])
group = optional(string)
}))
| `{}` | no | +| ncc\_groups | Groups for Hubs using the star topolgy |
map(object({
name = string
labels = optional(map(string))
description = optional(string)
auto_accept_projects = optional(list(string), [])
}))
| `{}` | no | | ncc\_hub\_description | The description of the NCC Hub | `string` | `null` | no | | ncc\_hub\_labels | These labels will be added the NCC hub | `map(string)` | `{}` | no | | ncc\_hub\_name | The Name of the NCC Hub | `string` | n/a | yes | +| ncc\_hub\_policy\_mode | The policy mode of the hub. Type must be one of `PRESET` or `CUSTOM`. | `string` | `"PRESET"` | no | +| ncc\_hub\_preset\_topology | The topology implemented in the hub. Type must be one of `STAR`, `MESH` or `HYBRID_INSPECTION`. | `string` | `null` | no | | project\_id | Project ID of the project that holds the network. | `string` | n/a | yes | -| router\_appliance\_spokes | Router appliance instances that are associated with the spoke. |
map(object({
instances = set(object({
virtual_machine = string
ip_address = string
}))
location = string
site_to_site_data_transfer = optional(bool, false)
description = optional(string)
labels = optional(map(string))
include_import_ranges = optional(list(string), [])
}))
| `{}` | no | +| router\_appliance\_spokes | Router appliance instances that are associated with the spoke. |
map(object({
instances = set(object({
virtual_machine = string
ip_address = string
}))
location = string
site_to_site_data_transfer = optional(bool, false)
description = optional(string)
labels = optional(map(string))
include_import_ranges = optional(list(string), [])
group = optional(string)
}))
| `{}` | no | | spoke\_labels | These labels will be added to all NCC spokes | `map(string)` | `{}` | no | -| vpc\_spokes | VPC network that is associated with the spoke. link\_producer\_vpc\_network: Producer VPC network that is peered with vpc network |
map(object({
uri = string
exclude_export_ranges = optional(set(string), [])
include_export_ranges = optional(set(string), [])
description = optional(string)
labels = optional(map(string))

link_producer_vpc_network = optional(object({
network_name = string
peering = string
include_export_ranges = optional(list(string))
exclude_export_ranges = optional(list(string))
description = optional(string)
labels = optional(map(string))
}))
}))
| `{}` | no | +| vpc\_spokes | VPC network that is associated with the spoke. link\_producer\_vpc\_network: Producer VPC network that is peered with vpc network |
map(object({
uri = string
exclude_export_ranges = optional(set(string), [])
include_export_ranges = optional(set(string), [])
description = optional(string)
labels = optional(map(string))
group = optional(string)

link_producer_vpc_network = optional(object({
network_name = string
peering = string
include_export_ranges = optional(list(string))
exclude_export_ranges = optional(list(string))
description = optional(string)
labels = optional(map(string))
group = optional(string)
}))
}))
| `{}` | no | ## Outputs | Name | Description | |------|-------------| +| groups | All group objects | | hybrid\_spokes | All hybrid spoke objects | | ncc\_hub | The NCC Hub object | | producer\_vpc\_network\_spoke | All producer network vpc spoke objects | diff --git a/modules/network-connectivity-center/main.tf b/modules/network-connectivity-center/main.tf index e7c0d835c..1475c88a5 100644 --- a/modules/network-connectivity-center/main.tf +++ b/modules/network-connectivity-center/main.tf @@ -31,16 +31,31 @@ locals { for k, v in google_network_connectivity_spoke.producer_vpc_network_spoke : k => v } + groups = { + for k, v in google_network_connectivity_group.group : + k => v + } } resource "google_network_connectivity_hub" "hub" { - name = var.ncc_hub_name - project = var.project_id - description = var.ncc_hub_description - export_psc = var.export_psc - labels = var.ncc_hub_labels + name = var.ncc_hub_name + project = var.project_id + description = var.ncc_hub_description + export_psc = var.export_psc + labels = var.ncc_hub_labels + policy_mode = var.ncc_hub_policy_mode + preset_topology = var.ncc_hub_policy_mode == "PRESET" ? var.ncc_hub_preset_topology : (var.ncc_hub_policy_mode == "CUSTOM" ? "PRESET_TOPOLOGY_UNSPECIFIED" : "MESH") } +resource "google_network_connectivity_group" "group" { + for_each = var.ncc_groups + name = each.value.name + hub = google_network_connectivity_hub.hub.id + project = var.project_id + auto_accept { + auto_accept_projects = each.value.auto_accept_projects + } +} resource "google_network_connectivity_spoke" "vpc_spoke" { for_each = var.vpc_spokes @@ -50,6 +65,7 @@ resource "google_network_connectivity_spoke" "vpc_spoke" { description = each.value.description hub = google_network_connectivity_hub.hub.id labels = merge(var.spoke_labels, each.value.labels) + group = each.value.group linked_vpc_network { uri = each.value.uri @@ -66,6 +82,7 @@ resource "google_network_connectivity_spoke" "producer_vpc_network_spoke" { description = each.value.description hub = google_network_connectivity_hub.hub.id labels = merge(var.spoke_labels, each.value.labels) + group = each.value.group linked_producer_vpc_network { network = each.value.network_name @@ -84,6 +101,7 @@ resource "google_network_connectivity_spoke" "hybrid_spoke" { description = each.value.description hub = google_network_connectivity_hub.hub.id labels = merge(var.spoke_labels, each.value.labels) + group = each.value.group dynamic "linked_interconnect_attachments" { for_each = each.value.type == "interconnect" ? [1] : [] @@ -112,6 +130,7 @@ resource "google_network_connectivity_spoke" "router_appliance_spoke" { description = each.value.description hub = google_network_connectivity_hub.hub.id labels = merge(var.spoke_labels, each.value.labels) + group = each.value.group linked_router_appliance_instances { dynamic "instances" { diff --git a/modules/network-connectivity-center/metadata.yaml b/modules/network-connectivity-center/metadata.yaml index 8e869a55d..509f86689 100644 --- a/modules/network-connectivity-center/metadata.yaml +++ b/modules/network-connectivity-center/metadata.yaml @@ -105,6 +105,23 @@ spec: description: These labels will be added the NCC hub varType: map(string) defaultValue: {} + - name: ncc_hub_preset_topology + description: The topology implemented in the hub. Type must be one of `STAR`, `MESH` or `HYBRID_INSPECTION`. + varType: string + - name: ncc_hub_policy_mode + description: The policy mode of the hub. Type must be one of `PRESET` or `CUSTOM`. + varType: string + defaultValue: PRESET + - name: ncc_groups + description: Groups for Hubs using the star topolgy + varType: |- + map(object({ + name = string + labels = optional(map(string)) + description = optional(string) + auto_accept_projects = optional(list(string), []) + })) + defaultValue: {} - name: export_psc description: Whether Private Service Connect transitivity is enabled for the hub varType: bool @@ -118,6 +135,7 @@ spec: include_export_ranges = optional(set(string), []) description = optional(string) labels = optional(map(string)) + group = optional(string) link_producer_vpc_network = optional(object({ network_name = string @@ -126,6 +144,7 @@ spec: exclude_export_ranges = optional(list(string)) description = optional(string) labels = optional(map(string)) + group = optional(string) })) })) defaultValue: {} @@ -140,6 +159,7 @@ spec: description = optional(string) labels = optional(map(string)) include_import_ranges = optional(list(string), []) + group = optional(string) })) defaultValue: {} - name: router_appliance_spokes @@ -155,6 +175,7 @@ spec: description = optional(string) labels = optional(map(string)) include_import_ranges = optional(list(string), []) + group = optional(string) })) defaultValue: {} - name: spoke_labels @@ -162,6 +183,8 @@ spec: varType: map(string) defaultValue: {} outputs: + - name: groups + description: All group objects - name: hybrid_spokes description: All hybrid spoke objects - name: ncc_hub @@ -204,4 +227,4 @@ spec: - servicenetworking.googleapis.com providerVersions: - source: hashicorp/google - version: ">= 6.49, < 8" + version: ">= 6.9, < 8" diff --git a/modules/network-connectivity-center/outputs.tf b/modules/network-connectivity-center/outputs.tf index d90245b9d..4f6f1b3b5 100644 --- a/modules/network-connectivity-center/outputs.tf +++ b/modules/network-connectivity-center/outputs.tf @@ -60,3 +60,8 @@ output "spokes" { }, ]) } + +output "groups" { + description = "All group objects" + value = local.groups +} diff --git a/modules/network-connectivity-center/variables.tf b/modules/network-connectivity-center/variables.tf index cf860950f..73d1b7d39 100644 --- a/modules/network-connectivity-center/variables.tf +++ b/modules/network-connectivity-center/variables.tf @@ -35,6 +35,29 @@ variable "ncc_hub_labels" { default = {} } +variable "ncc_hub_preset_topology" { + description = "The topology implemented in the hub. Type must be one of `STAR`, `MESH` or `HYBRID_INSPECTION`." + type = string + default = null +} + +variable "ncc_hub_policy_mode" { + description = "The policy mode of the hub. Type must be one of `PRESET` or `CUSTOM`." + type = string + default = "PRESET" +} + +variable "ncc_groups" { + description = "Groups for Hubs using the star topolgy" + type = map(object({ + name = string + labels = optional(map(string)) + description = optional(string) + auto_accept_projects = optional(list(string), []) + })) + default = {} +} + variable "export_psc" { description = "Whether Private Service Connect transitivity is enabled for the hub" type = bool @@ -49,6 +72,7 @@ variable "vpc_spokes" { include_export_ranges = optional(set(string), []) description = optional(string) labels = optional(map(string)) + group = optional(string) link_producer_vpc_network = optional(object({ network_name = string @@ -57,6 +81,7 @@ variable "vpc_spokes" { exclude_export_ranges = optional(list(string)) description = optional(string) labels = optional(map(string)) + group = optional(string) })) })) default = {} @@ -83,6 +108,7 @@ variable "hybrid_spokes" { description = optional(string) labels = optional(map(string)) include_import_ranges = optional(list(string), []) + group = optional(string) })) default = {} } @@ -99,6 +125,7 @@ variable "router_appliance_spokes" { description = optional(string) labels = optional(map(string)) include_import_ranges = optional(list(string), []) + group = optional(string) })) default = {} } diff --git a/modules/network-connectivity-center/versions.tf b/modules/network-connectivity-center/versions.tf index 963008250..e2f8d9fb0 100644 --- a/modules/network-connectivity-center/versions.tf +++ b/modules/network-connectivity-center/versions.tf @@ -20,7 +20,7 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 6.49, < 8" + version = ">= 7.8, < 8" } } diff --git a/test/integration/network_connectivity_center/network_connectivity_center_test.go b/test/integration/network_connectivity_center/network_connectivity_center_test.go index 30318346d..52bc5fe4a 100644 --- a/test/integration/network_connectivity_center/network_connectivity_center_test.go +++ b/test/integration/network_connectivity_center/network_connectivity_center_test.go @@ -31,11 +31,24 @@ func TestNetworkConnectivityCenter(t *testing.T) { // net.DefaultVerify(assert) Disable due to bug in provider. Reenable it after the bug is fixed projectID := net.GetStringOutput("project_id") nccHubName := net.GetStringOutput("ncc_hub_name") + nccHubStarName := net.GetStringOutput("ncc_hub_name_star") op := gcloud.Run(t, "network-connectivity hubs describe ", gcloud.WithCommonArgs([]string{nccHubName, "--project", projectID, "--format", "json"})) + meshPresetTopology := op.Get("presetTopology").String() + assert.Equal("MESH", meshPresetTopology, "should have mesh topology") nccSpokeStateCount := op.Get("spokeSummary.spokeStateCounts").Array() assert.Equal(1, len(nccSpokeStateCount), "should have spokes in one State") assert.Equal("ACTIVE", nccSpokeStateCount[0].Get("state").String(), "should have only active spokes") + + starHub := gcloud.Run(t, "network-connectivity hubs describe ", gcloud.WithCommonArgs([]string{nccHubStarName, "--project", projectID, "--format", "json"})) + starPresetTopology := starHub.Get("presetTopology").String() + assert.Equal("STAR", starPresetTopology, "should have star topology") + + groups := gcloud.Run(t, "network-connectivity hubs groups list ", gcloud.WithCommonArgs([]string{"--hub", nccHubStarName, "--project", projectID, "--format", "json"})).Array() + assert.Equal(2, len(groups), "should have two groups") + for _, group := range groups { + assert.Equal("ACTIVE", group.Get("state").String(), "should have active group") + } }) net.Test() }