terraform { required_providers { google = { source = "hashicorp/google" version = "6.27.0" } } } provider "google" { # Configuration options project = "network-getting-started" region = "europe-central2" zone = "europe-central2-b" } # Networks resource "google_compute_network" "vpc_hub" { name = "dom-lab-hub" auto_create_subnetworks = false } resource "google_compute_subnetwork" "net_hub" { name = "hub" region = "europe-central2" ip_cidr_range = var.hub_cidr network = google_compute_network.vpc_hub.id } resource "google_compute_network" "vpc_spoke" { name = "dom-lab-spoke" auto_create_subnetworks = false project = "spoke-network" } resource "google_compute_subnetwork" "net_spoke" { name = "spoke" region = "europe-central2" ip_cidr_range = var.spoke_cidr network = google_compute_network.vpc_spoke.id project = "spoke-network" } # Peering resource "google_compute_network_peering" "hub_to_spoke" { name = "hub-to-spoke" network = google_compute_network.vpc_hub.id peer_network = google_compute_network.vpc_spoke.id export_custom_routes = true import_custom_routes = false } resource "google_compute_network_peering" "spoke_to_hub" { name = "spoke-to-hub" network = google_compute_network.vpc_spoke.id peer_network = google_compute_network.vpc_hub.id export_custom_routes = false import_custom_routes = true } # Cloud NAT resource "google_compute_router" "hub_cloud_router" { name = "hub-cr" network = google_compute_network.vpc_hub.id region = "europe-central2" } resource "google_compute_router_nat" "hub_nat" { name = "hub-nat" region = "europe-central2" router = google_compute_router.hub_cloud_router.name nat_ip_allocate_option = "AUTO_ONLY" source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES" } resource "google_compute_router" "spoke_cloud_router" { name = "spoke-cr" network = google_compute_network.vpc_spoke.id region = "europe-central2" project = "spoke-network" } resource "google_compute_router_nat" "spoke_nat" { name = "spoke-nat" region = "europe-central2" router = google_compute_router.spoke_cloud_router.name nat_ip_allocate_option = "AUTO_ONLY" source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES" project = "spoke-network" } # Cloud VPN resource "google_compute_vpn_gateway" "gw" { name = "vpn-1" network = google_compute_network.vpc_hub.id } resource "google_compute_address" "gw_ip" { name = "vpn-1-ip" address_type = "EXTERNAL" } output "vpn_gw_ip" { value = google_compute_address.gw_ip.address } resource "google_compute_forwarding_rule" "gw_fw_esp" { name = "fwd-esp" ip_protocol = "ESP" ip_address = google_compute_address.gw_ip.address target = google_compute_vpn_gateway.gw.id } resource "google_compute_forwarding_rule" "gw_fw_udp_500" { name = "fwd-udp-500" ip_protocol = "UDP" ip_address = google_compute_address.gw_ip.address port_range = "500" target = google_compute_vpn_gateway.gw.id } resource "google_compute_forwarding_rule" "gw_fw_udp_4500" { name = "fwd-udp-4500" ip_protocol = "UDP" ip_address = google_compute_address.gw_ip.address port_range = "4500" target = google_compute_vpn_gateway.gw.id } resource "google_compute_vpn_tunnel" "to_lazurowa" { name = "to-lazurowa" target_vpn_gateway = google_compute_vpn_gateway.gw.id shared_secret = var.shared_secret peer_ip = var.peer_ip ike_version = 2 local_traffic_selector = [ var.hub_cidr, var.spoke_cidr, "35.199.192.0/19" ] remote_traffic_selector = var.on_prem_selectors depends_on = [ google_compute_forwarding_rule.gw_fw_esp, google_compute_forwarding_rule.gw_fw_udp_500, google_compute_forwarding_rule.gw_fw_udp_4500 ] } resource "google_compute_route" "rt_to_on_prem" { count = length(var.on_prem_selectors) name = "to-on-prem-${count.index + 1}" network = "dom-lab-hub" dest_range = var.on_prem_selectors[count.index] next_hop_vpn_tunnel = google_compute_vpn_tunnel.to_lazurowa.id } # DNS resource "google_dns_managed_zone" "koszewscy_internal" { name = "koszewscy-internal" dns_name = "koszewscy.internal." visibility = "private" private_visibility_config { networks { network_url = google_compute_network.vpc_hub.id } } } resource "google_dns_record_set" "vm_hub" { name = "vm-hub.koszewscy.internal." managed_zone = google_dns_managed_zone.koszewscy_internal.name type = "A" ttl = 60 rrdatas = [google_compute_instance.vm_hub.network_interface[0].network_ip] depends_on = [google_compute_instance.vm_hub] } resource "google_dns_record_set" "vm_spoke" { name = "vm-spoke.koszewscy.internal." managed_zone = google_dns_managed_zone.koszewscy_internal.name type = "A" ttl = 60 rrdatas = [google_compute_instance.vm_spoke.network_interface[0].network_ip] depends_on = [google_compute_instance.vm_spoke] } resource "google_dns_managed_zone" "koszewscy_external" { name = "koszewscy-external" dns_name = "koszewscy.waw.pl." visibility = "private" private_visibility_config { networks { network_url = google_compute_network.vpc_hub.id } } forwarding_config { target_name_servers { ipv4_address = "192.168.2.5" } } } resource "google_dns_managed_zone" "koszewscy_internal_spoke" { name = "koszewscy-internal" dns_name = "koszewscy.internal." project = "spoke-network" visibility = "private" private_visibility_config { networks { network_url = google_compute_network.vpc_spoke.id } } peering_config { target_network { network_url = google_compute_network.vpc_hub.id } } depends_on = [ google_dns_managed_zone.koszewscy_internal ] } resource "google_dns_managed_zone" "koszewscy_external_spoke" { name = "koszewscy-external" dns_name = "koszewscy.waw.pl." project = "spoke-network" visibility = "private" private_visibility_config { networks { network_url = google_compute_network.vpc_spoke.id } } peering_config { target_network { network_url = google_compute_network.vpc_hub.id } } depends_on = [ google_dns_managed_zone.koszewscy_external ] } # Virtual Machines resource "google_compute_instance" "vm_hub" { name = "vm-hub" machine_type = "e2-micro" can_ip_forward = false description = "A VM in the hub network" boot_disk { initialize_params { image = "debian-cloud/debian-12" } } network_interface { network = "dom-lab-hub" subnetwork = "hub" } metadata = { ssh-keys = "${var.ssh[0].public_key} ${var.ssh[0].ssh_user}" } depends_on = [google_compute_subnetwork.net_hub] } output "vm_hub_ip" { value = google_compute_instance.vm_hub.network_interface[0].network_ip } resource "google_compute_instance" "vm_spoke" { name = "vm-spoke" machine_type = "e2-micro" can_ip_forward = false description = "A VM in the spoke network" project = "spoke-network" boot_disk { initialize_params { image = "debian-cloud/debian-12" } } network_interface { network = "dom-lab-spoke" subnetwork = "spoke" subnetwork_project = "spoke-network" } metadata = { ssh-keys = "${var.ssh[0].public_key} ${var.ssh[0].ssh_user}" } depends_on = [google_compute_subnetwork.net_spoke] } output "vm_spoke_ip" { value = google_compute_instance.vm_spoke.network_interface[0].network_ip }