Merge pull request #14 from terraform-google-modules/averbuks-net-hub-and-spoke

Initial Hub and Spoke (VPNs) example (does not include tests, diagram and readme atm).
This commit is contained in:
Aleksandr Averbukh
2019-10-30 17:11:53 +01:00
committed by GitHub
9 changed files with 807 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
# Hub and Spoke VPNs
This sample creates a simple **Hub and Spoke VPNs** architecture, where network connects every location (VPC Network) through a single intermediary location called a hub via IPsec VPNs.
> **NOTE**: This example is not desined to provide HA, please refer to the [documentation](https://cloud.google.com/vpn/docs/concepts/advanced#ha-options) for information on Cloud VPNs and HA.
The benefits of this topology include:
- Network/Security Admin manages Central Services Project (Hub).
- Central services and tools deployed in Central Services Project (Hub) for use by all Service Projects (Spokes).
- Network/Security Admin hands over spoke Projects to respective team who then have full autonomy.
- Network/Security Admin monitors spoke projects for organization security posture compliance using tools like [Forseti](https://forsetisecurity.org/), [CSCC](https://cloud.google.com/security-command-center/) etc deployed in Central Services Project (Hub).
- Spokes communicate with on-prem via VPN to transit hub and then over Interconnect or VPN to on-premises.
- (Optional) Spokes communicate in a full-mesh to each other via VPN transit routing in Central Services Project (Hub).
- This is a decentralized architecture where each spoke project has autonomy to manage all their GCP compute and network resources.
The purpose of this sample is showing how to wire different [Cloud Foundation Fabric](https://github.com/search?q=topic%3Acft-fabric+org%3Aterraform-google-modules&type=Repositories) modules to create **Hub and Spoke VPNs** network architectures, and as such it is meant to be used for prototyping, or to experiment with networking configurations. Additional best practices and security considerations need to be taken into account for real world usage (eg removal of default service accounts, disabling of external IPs, firewall design, etc).
![High-level diagram](diagram.png "High-level diagram")
## Managed resources and services
This sample creates several distinct groups of resources:
- three VPC Networks (hub network and two ppoke networks)
- VPC-level resources (VPC, subnets, firewall rules, etc.)
- one Cloud DNS Private zone in the hub project
- one Cloud DNS Forwarding zone in the hub project
- four Cloud DNS Peering zones (two per each spoke project)
- one Cloud DNS Policy for inbound forwarding
- four Cloud Routers (two in hub project and one per each spoke project)
- four Cloud VPNs (two in hub project and one per each spoke project)
## Test resources
A set of test resources are included for convenience, as they facilitate experimenting with different networking configurations (firewall rules, external connectivity via VPN, etc.). They are encapsulated in the `test-resources.tf` file, and can be safely removed as a single unit.
- two virtual machine instances in hub project (one per each region)
- two virtual machine instances in spoke1 project (one per each region)
- two virtual machine instances in spoke2 project (one per each region)
SSH access to instances is configured via [OS Login](https://cloud.google.com/compute/docs/oslogin/). External access is allowed via the default SSH rule created by the firewall module, and corresponding `ssh` tags on the instances.
## Known issues
- It is not possible to get inbound DNS forwarding IPs in the terraform output.
- Please refer to the [bug](https://github.com/terraform-providers/terraform-provider-google/issues/3753) for more details.
- Please refer to the [documentation](https://cloud.google.com/dns/zones/#creating_a_dns_policy_that_enables_inbound_dns_forwarding) on how to get the IPs with `gcloud`.
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| forwarding\_dns\_zone\_domain | Forwarding DNS Zone Domain. | string | `"on-prem.local."` | no |
| forwarding\_dns\_zone\_name | Forwarding DNS Zone Name. | string | `"on-prem-local"` | no |
| forwarding\_zone\_server\_addresses | Forwarding DNS Zone Server Addresses | list | `<list>` | no |
| hub\_bgp\_asn | Hub BGP ASN. | string | `"64515"` | no |
| hub\_project\_id | Hub Project id. | string | n/a | yes |
| hub\_subnets | Hub VPC subnets configuration. | list | `<list>` | no |
| private\_dns\_zone\_domain | Private DNS Zone Domain. | string | `"gcp.local."` | no |
| private\_dns\_zone\_name | Private DNS Zone Name. | string | `"gcp-local"` | no |
| spoke\_1\_bgp\_asn | Spoke 1 BGP ASN. | string | `"64516"` | no |
| spoke\_1\_project\_id | Spoke 1 Project id. | string | n/a | yes |
| spoke\_1\_subnets | Spoke 1 VPC subnets configuration. | list | `<list>` | no |
| spoke\_2\_bgp\_asn | Spoke 2 BGP ASN. | string | `"64517"` | no |
| spoke\_2\_project\_id | Spoke 2 Project id. | string | n/a | yes |
| spoke\_2\_subnets | Spoke 2 VPC subnets configuration. | list | `<list>` | no |
| spoke\_to\_spoke\_route\_advertisement | Use custom route advertisement in hub routers to advertise all spoke subnets. | string | `"true"` | no |
## Outputs
| Name | Description |
|------|-------------|
| hub | Hub network resources. |
| spoke-1 | Spoke1 network resources. |
| spoke-2 | Spoke2 network resources. |
| test-instances | Test instance attributes. |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

View File

@@ -0,0 +1,20 @@
# Copyright 2019 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
#
# https://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 {
backend "gcs" {
bucket = ""
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

View File

@@ -0,0 +1,344 @@
# Copyright 2019 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
#
# https://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 {
hub_subnet_regions = [for subnet in var.hub_subnets : subnet["subnet_region"]]
spoke_1_subnet_regions = [for subnet in var.spoke_1_subnets : subnet["subnet_region"]]
spoke_2_subnet_regions = [for subnet in var.spoke_2_subnets : subnet["subnet_region"]]
hub_subnet_cidr_ranges = [for subnet in var.hub_subnets : subnet["subnet_ip"]]
spoke_1_subnet_cidr_ranges = [for subnet in var.spoke_1_subnets : subnet["subnet_ip"]]
spoke_2_subnet_cidr_ranges = [for subnet in var.spoke_2_subnets : subnet["subnet_ip"]]
all_subnet_cidrs = concat(local.hub_subnet_cidr_ranges, local.spoke_1_subnet_cidr_ranges, local.spoke_2_subnet_cidr_ranges)
hub_to_spoke_1_router = var.spoke_to_spoke_route_advertisement ? element(concat(google_compute_router.hub-to-spoke-1-custom.*.name, list("")), 0) : element(concat(google_compute_router.hub-to-spoke-1-default.*.name, list("")), 0)
hub_to_spoke_2_router = var.spoke_to_spoke_route_advertisement ? element(concat(google_compute_router.hub-to-spoke-2-custom.*.name, list("")), 0) : element(concat(google_compute_router.hub-to-spoke-2-default.*.name, list("")), 0)
}
##############################################################
# VPCs #
##############################################################
module "vpc-hub" {
source = "terraform-google-modules/network/google"
version = "~> 1.2"
project_id = var.hub_project_id
network_name = "hub-network"
subnets = var.hub_subnets
routing_mode = "GLOBAL"
}
module "vpc-spoke-1" {
source = "terraform-google-modules/network/google"
version = "~> 1.2"
project_id = var.spoke_1_project_id
network_name = "spoke-1-network"
subnets = var.spoke_1_subnets
routing_mode = "GLOBAL"
}
module "vpc-spoke-2" {
source = "terraform-google-modules/network/google"
version = "~> 1.2"
project_id = var.spoke_2_project_id
network_name = "spoke-2-network"
subnets = var.spoke_2_subnets
routing_mode = "GLOBAL"
}
##############################################################
# Firewalls #
##############################################################
module "firewall-hub" {
source = "terraform-google-modules/network/google//modules/fabric-net-firewall"
version = "~> 1.2"
project_id = var.hub_project_id
network = module.vpc-hub.network_name
admin_ranges_enabled = true
admin_ranges = local.all_subnet_cidrs
}
module "firewall-spoke-1" {
source = "terraform-google-modules/network/google//modules/fabric-net-firewall"
version = "~> 1.2"
project_id = var.spoke_1_project_id
network = module.vpc-spoke-1.network_name
admin_ranges_enabled = true
admin_ranges = local.all_subnet_cidrs
}
module "firewall-spoke-2" {
source = "terraform-google-modules/network/google//modules/fabric-net-firewall"
version = "~> 1.2"
project_id = var.spoke_2_project_id
network = module.vpc-spoke-2.network_name
admin_ranges_enabled = true
admin_ranges = local.all_subnet_cidrs
}
##############################################################
# Cloud Routers #
##############################################################
resource "google_compute_router" "hub-to-spoke-1-custom" {
count = var.spoke_to_spoke_route_advertisement ? 1 : 0
name = "hub-to-spoke-1-custom"
region = element(local.hub_subnet_regions, 0)
network = module.vpc-hub.network_name
project = var.hub_project_id
bgp {
asn = var.hub_bgp_asn
advertise_mode = "CUSTOM"
advertised_groups = ["ALL_SUBNETS"]
dynamic "advertised_ip_ranges" {
for_each = toset(local.spoke_2_subnet_cidr_ranges)
content {
range = advertised_ip_ranges.value
}
}
}
}
resource "google_compute_router" "hub-to-spoke-2-custom" {
count = var.spoke_to_spoke_route_advertisement ? 1 : 0
name = "hub-to-spoke-2-custom"
region = element(local.hub_subnet_regions, 1)
network = module.vpc-hub.network_name
project = var.hub_project_id
bgp {
asn = var.hub_bgp_asn
advertise_mode = "CUSTOM"
advertised_groups = ["ALL_SUBNETS"]
dynamic "advertised_ip_ranges" {
for_each = toset(local.spoke_1_subnet_cidr_ranges)
content {
range = advertised_ip_ranges.value
}
}
}
}
resource "google_compute_router" "hub-to-spoke-1-default" {
count = var.spoke_to_spoke_route_advertisement ? 0 : 1
name = "hub-to-spoke-1-default"
region = element(local.hub_subnet_regions, 0)
network = module.vpc-hub.network_name
project = var.hub_project_id
bgp {
asn = var.hub_bgp_asn
}
}
resource "google_compute_router" "hub-to-spoke-2-default" {
count = var.spoke_to_spoke_route_advertisement ? 0 : 1
name = "hub-to-spoke-2-default"
region = element(local.hub_subnet_regions, 1)
network = module.vpc-hub.network_name
project = var.hub_project_id
bgp {
asn = var.hub_bgp_asn
}
}
resource "google_compute_router" "spoke-1" {
name = "spoke-1"
region = element(local.spoke_1_subnet_regions, 0)
network = module.vpc-spoke-1.network_name
project = var.spoke_1_project_id
bgp {
asn = var.spoke_1_bgp_asn
}
}
resource "google_compute_router" "spoke-2" {
name = "spoke-2"
region = element(local.spoke_2_subnet_regions, 1)
network = module.vpc-spoke-2.network_name
project = var.spoke_2_project_id
bgp {
asn = var.spoke_2_bgp_asn
}
}
##############################################################
# VPNs #
##############################################################
module "vpn-hub-to-spoke-1" {
source = "terraform-google-modules/vpn/google"
version = "~> 1.1"
project_id = var.hub_project_id
network = module.vpc-hub.network_name
region = element(local.hub_subnet_regions, 0)
gateway_name = "hub-to-spoke-1-gtw"
tunnel_name_prefix = "hub-to-spoke-1"
peer_ips = [module.vpn-spoke-1-to-hub.gateway_ip]
bgp_cr_session_range = ["169.254.0.1/30"]
bgp_remote_session_range = ["169.254.0.2"]
peer_asn = [var.spoke_1_bgp_asn]
cr_name = local.hub_to_spoke_1_router
}
module "vpn-hub-to-spoke-2" {
source = "terraform-google-modules/vpn/google"
version = "~> 1.1"
project_id = var.hub_project_id
network = module.vpc-hub.network_name
region = element(local.hub_subnet_regions, 1)
gateway_name = "hub-to-spoke-2-gtw"
tunnel_name_prefix = "hub-to-spoke-2"
peer_ips = [module.vpn-spoke-2-to-hub.gateway_ip]
bgp_cr_session_range = ["169.254.1.1/30"]
bgp_remote_session_range = ["169.254.1.2"]
peer_asn = [var.spoke_2_bgp_asn]
cr_name = local.hub_to_spoke_2_router
}
module "vpn-spoke-1-to-hub" {
source = "terraform-google-modules/vpn/google"
version = "~> 1.1"
project_id = var.spoke_1_project_id
network = module.vpc-spoke-1.network_name
region = element(local.spoke_1_subnet_regions, 0)
gateway_name = "spoke-1-to-hub-gtw"
tunnel_name_prefix = "spoke-1-to-hub"
shared_secret = module.vpn-hub-to-spoke-1.ipsec_secret-dynamic[0]
peer_ips = [module.vpn-hub-to-spoke-1.gateway_ip]
bgp_cr_session_range = ["169.254.0.2/30"]
bgp_remote_session_range = ["169.254.0.1"]
peer_asn = [var.hub_bgp_asn]
cr_name = google_compute_router.spoke-1.name
}
module "vpn-spoke-2-to-hub" {
source = "terraform-google-modules/vpn/google"
version = "~> 1.1"
project_id = var.spoke_2_project_id
network = module.vpc-spoke-2.network_name
region = element(local.spoke_2_subnet_regions, 1)
gateway_name = "spoke-2-to-hub-gtw"
tunnel_name_prefix = "spoke-2-to-hub"
shared_secret = module.vpn-hub-to-spoke-2.ipsec_secret-dynamic[0]
peer_ips = [module.vpn-hub-to-spoke-2.gateway_ip]
bgp_cr_session_range = ["169.254.1.2/30"]
bgp_remote_session_range = ["169.254.1.1"]
peer_asn = [var.hub_bgp_asn]
cr_name = google_compute_router.spoke-2.name
}
##############################################################
# DNS Zones #
##############################################################
module "hub-private-zone" {
source = "terraform-google-modules/cloud-dns/google"
version = "~> 2.0"
project_id = var.hub_project_id
type = "private"
name = "${var.private_dns_zone_name}-hub-private"
domain = var.private_dns_zone_domain
private_visibility_config_networks = [module.vpc-hub.network_self_link]
}
module "hub-forwarding-zone" {
source = "terraform-google-modules/cloud-dns/google"
version = "~> 2.0"
project_id = var.hub_project_id
type = "forwarding"
name = "${var.forwarding_dns_zone_name}-hub-forwarding"
domain = var.forwarding_dns_zone_domain
private_visibility_config_networks = [module.vpc-hub.network_self_link]
target_name_server_addresses = var.forwarding_zone_server_addresses
}
module "spoke-1-peering-zone-to-hub-private-zone" {
source = "terraform-google-modules/cloud-dns/google"
version = "~> 2.0"
project_id = var.spoke_1_project_id
type = "peering"
name = "${var.private_dns_zone_name}-spoke-1-peering-to-hub-private"
domain = var.private_dns_zone_domain
private_visibility_config_networks = [module.vpc-spoke-1.network_self_link]
target_network = module.vpc-hub.network_self_link
}
module "spoke-2-peering-zone-to-hub-private-zone" {
source = "terraform-google-modules/cloud-dns/google"
version = "~> 2.0"
project_id = var.spoke_2_project_id
type = "peering"
name = "${var.private_dns_zone_name}-spoke-2-peering-to-hub-private"
domain = var.private_dns_zone_domain
private_visibility_config_networks = [module.vpc-spoke-2.network_self_link]
target_network = module.vpc-hub.network_self_link
}
module "spoke-1-peering-zone-to-hub-forwarding-zone" {
source = "terraform-google-modules/cloud-dns/google"
version = "~> 2.0"
project_id = var.spoke_1_project_id
type = "peering"
name = "${var.private_dns_zone_name}-spoke-1-peering-to-hub-forwarding"
domain = var.forwarding_dns_zone_domain
private_visibility_config_networks = [module.vpc-spoke-1.network_self_link]
target_network = module.vpc-hub.network_self_link
}
module "spoke-2-peering-zone-to-hub-forwarding-zone" {
source = "terraform-google-modules/cloud-dns/google"
version = "~> 2.0"
project_id = var.spoke_2_project_id
type = "peering"
name = "${var.private_dns_zone_name}-spoke-2-peering-to-hub-forwarding"
domain = var.forwarding_dns_zone_domain
private_visibility_config_networks = [module.vpc-spoke-2.network_self_link]
target_network = module.vpc-hub.network_self_link
}
##############################################################
# Inbount DNS Forwarding #
##############################################################
# TODO Provide resolver addresses in the output once https://github.com/terraform-providers/terraform-provider-google/issues/3753 resolved.
# For now please refer to the documentation on how to get the compute addresses for the DNS Resolver https://cloud.google.com/dns/zones/#creating_a_dns_policy_that_enables_inbound_dns_forwarding
resource "google_dns_policy" "google_dns_policy" {
provider = "google-beta"
project = var.hub_project_id
name = "inbound-dns-forwarding-policy"
enable_inbound_forwarding = true
networks {
network_url = module.vpc-hub.network_self_link
}
}

View File

@@ -0,0 +1,82 @@
# Copyright 2019 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
#
# https://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.
output "hub" {
description = "Hub network resources."
value = {
network_name = module.vpc-hub.network_name
subnets_ips = zipmap(
module.vpc-hub.subnets_names,
module.vpc-hub.subnets_ips
)
subnets_regions = zipmap(
module.vpc-hub.subnets_names,
module.vpc-hub.subnets_regions
)
privte_dns_zone = {
name = module.hub-private-zone.name
domain = module.hub-private-zone.domain
}
forwarding_dns_zone = {
name = module.hub-forwarding-zone.name
domain = module.hub-forwarding-zone.domain
}
}
}
output "spoke-1" {
description = "Spoke1 network resources."
value = {
network_name = module.vpc-spoke-1.network_name
subnets_ips = zipmap(
module.vpc-spoke-1.subnets_names,
module.vpc-spoke-1.subnets_ips
)
subnets_regions = zipmap(
module.vpc-spoke-1.subnets_names,
module.vpc-spoke-1.subnets_regions
)
peering_to_hub_private_dns_zone = {
name = module.spoke-1-peering-zone-to-hub-private-zone.name
domain = module.spoke-1-peering-zone-to-hub-private-zone.domain
}
peering_to_hub_forwarding_dns_zone = {
name = module.spoke-1-peering-zone-to-hub-forwarding-zone.name
domain = module.spoke-1-peering-zone-to-hub-forwarding-zone.domain
}
}
}
output "spoke-2" {
description = "Spoke2 network resources."
value = {
network_name = module.vpc-spoke-2.network_name
subnets_ips = zipmap(
module.vpc-spoke-2.subnets_names,
module.vpc-spoke-2.subnets_ips
)
subnets_regions = zipmap(
module.vpc-spoke-2.subnets_names,
module.vpc-spoke-2.subnets_regions
)
peering_to_hub_private_dns_zone = {
name = module.spoke-2-peering-zone-to-hub-private-zone.name
domain = module.spoke-2-peering-zone-to-hub-private-zone.domain
}
peering_to_hub_forwarding_dns_zone = {
name = module.spoke-2-peering-zone-to-hub-forwarding-zone.name
domain = module.spoke-2-peering-zone-to-hub-forwarding-zone.domain
}
}
}

View File

@@ -0,0 +1,4 @@
provider "google" {
}
provider "google-beta" {
}

View File

@@ -0,0 +1,3 @@
hub_project_id = "automation-examples"
spoke_1_project_id = "automation-examples"
spoke_2_project_id = "automation-examples"

View File

@@ -0,0 +1,158 @@
# Copyright 2019 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
#
# https://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.
###############################################################################
# Hub test VMs and DNS records #
###############################################################################
resource "google_compute_instance" "hub" {
count = length(var.hub_subnets)
project = var.hub_project_id
name = "hub-${element(var.hub_subnets, count.index)["subnet_name"]}"
machine_type = "f1-micro"
zone = "${element(local.hub_subnet_regions, count.index)}-b"
tags = ["ssh"]
boot_disk {
initialize_params {
image = "debian-cloud/debian-9"
}
}
network_interface {
subnetwork = element(module.vpc-hub.subnets_self_links, count.index)
access_config {}
}
}
resource "google_dns_record_set" "hub" {
count = length(var.hub_subnets)
project = var.hub_project_id
name = "hub-${count.index}.${module.hub-private-zone.domain}"
type = "A"
ttl = 300
managed_zone = module.hub-private-zone.name
rrdatas = [google_compute_instance.hub[count.index].network_interface.0.network_ip]
}
###############################################################################
# Spoke 1 test VMs and DNS records #
###############################################################################
resource "google_compute_instance" "spoke-1" {
count = length(var.spoke_1_subnets)
project = var.spoke_1_project_id
name = "spoke-1-${element(var.spoke_1_subnets, count.index)["subnet_name"]}"
machine_type = "f1-micro"
zone = "${element(local.spoke_1_subnet_regions, count.index)}-b"
tags = ["ssh"]
boot_disk {
initialize_params {
image = "debian-cloud/debian-9"
}
}
network_interface {
subnetwork = element(module.vpc-spoke-1.subnets_self_links, count.index)
access_config {}
}
}
resource "google_dns_record_set" "spoke-1" {
count = length(var.spoke_1_subnets)
project = var.hub_project_id
name = "spoke-1-${count.index}.${module.hub-private-zone.domain}"
type = "A"
ttl = 300
managed_zone = module.hub-private-zone.name
rrdatas = [google_compute_instance.spoke-1[count.index].network_interface.0.network_ip]
}
###############################################################################
# Spoke 2 test VMs and DNS records #
###############################################################################
resource "google_compute_instance" "spoke-2" {
count = length(var.spoke_2_subnets)
project = var.spoke_2_project_id
name = "spoke-2-${element(var.spoke_2_subnets, count.index)["subnet_name"]}"
machine_type = "f1-micro"
zone = "${element(local.spoke_2_subnet_regions, count.index)}-b"
tags = ["ssh"]
boot_disk {
initialize_params {
image = "debian-cloud/debian-9"
}
}
network_interface {
subnetwork = element(module.vpc-spoke-2.subnets_self_links, count.index)
access_config {}
}
}
resource "google_dns_record_set" "spoke-2" {
count = length(var.spoke_2_subnets)
project = var.hub_project_id
name = "spoke-2-${count.index}.${module.hub-private-zone.domain}"
type = "A"
ttl = 300
managed_zone = module.hub-private-zone.name
rrdatas = [google_compute_instance.spoke-2[count.index].network_interface.0.network_ip]
}
###############################################################################
# test outputs #
###############################################################################
output "test-instances" {
description = "Test instance attributes."
value = {
hub = {
instance_zones = zipmap(
google_compute_instance.hub.*.name,
google_compute_instance.hub.*.zone
)
instances_dns_names = zipmap(
google_compute_instance.hub.*.name,
google_dns_record_set.hub.*.name
)
}
spoke-1 = {
instances_zones = zipmap(
google_compute_instance.spoke-1.*.name,
google_compute_instance.spoke-1.*.zone
)
instances_dns_names = zipmap(
google_compute_instance.spoke-1.*.name,
google_dns_record_set.spoke-1.*.name
)
}
spoke-2 = {
instances_zones = zipmap(
google_compute_instance.spoke-2.*.name,
google_compute_instance.spoke-2.*.zone
)
instances_dns_names = zipmap(
google_compute_instance.spoke-2.*.name,
google_dns_record_set.spoke-2.*.name
)
}
}
}

View File

@@ -0,0 +1,115 @@
# Copyright 2019 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
#
# https://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.
variable "hub_project_id" {
description = "Hub Project id."
}
variable "spoke_1_project_id" {
description = "Spoke 1 Project id."
}
variable "spoke_2_project_id" {
description = "Spoke 2 Project id."
}
variable "spoke_to_spoke_route_advertisement" {
description = "Use custom route advertisement in hub routers to advertise all spoke subnets."
default = true
}
variable "hub_bgp_asn" {
description = "Hub BGP ASN."
default = 64515
}
variable "spoke_1_bgp_asn" {
description = "Spoke 1 BGP ASN."
default = 64516
}
variable "spoke_2_bgp_asn" {
description = "Spoke 2 BGP ASN."
default = 64517
}
variable "hub_subnets" {
description = "Hub VPC subnets configuration."
default = [{
subnet_name = "subnet-a"
subnet_ip = "10.10.10.0/24"
subnet_region = "europe-west1"
},
{
subnet_name = "subnet-b"
subnet_ip = "10.10.20.0/24"
subnet_region = "europe-west2"
},
]
}
variable "spoke_1_subnets" {
description = "Spoke 1 VPC subnets configuration."
default = [{
subnet_name = "spoke-1-subnet-a"
subnet_ip = "10.20.10.0/24"
subnet_region = "europe-west1"
},
{
subnet_name = "spoke-1-subnet-b"
subnet_ip = "10.20.20.0/24"
subnet_region = "europe-west2"
},
]
}
variable "spoke_2_subnets" {
description = "Spoke 2 VPC subnets configuration."
default = [{
subnet_name = "spoke-2-subnet-a"
subnet_ip = "10.30.10.0/24"
subnet_region = "europe-west1"
},
{
subnet_name = "spoke-2-subnet-b"
subnet_ip = "10.30.20.0/24"
subnet_region = "europe-west2"
},
]
}
variable "private_dns_zone_name" {
description = "Private DNS Zone Name."
default = "gcp-local"
}
variable "private_dns_zone_domain" {
description = "Private DNS Zone Domain."
default = "gcp.local."
}
variable "forwarding_dns_zone_name" {
description = "Forwarding DNS Zone Name."
default = "on-prem-local"
}
variable "forwarding_dns_zone_domain" {
description = "Forwarding DNS Zone Domain."
default = "on-prem.local."
}
variable "forwarding_zone_server_addresses" {
description = "Forwarding DNS Zone Server Addresses"
default = ["8.8.8.8", "8.8.4.4"]
}