# Copyright 2020 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 { vm-instances = concat( module.vm-spoke-1.instances, module.vm-spoke-2.instances ) vm-startup-script = join("\n", [ "#! /bin/bash", "apt-get update && apt-get install -y bash-completion dnsutils kubectl" ]) } ################################################################################ # Hub networking # ################################################################################ module "vpc-hub" { source = "../../modules/net-vpc" project_id = var.project_id name = "hub" subnets = { default = { ip_cidr_range = var.ip_ranges.hub name = null region = var.region secondary_ip_range = {} } } } module "vpc-hub-firewall" { source = "../../modules/net-vpc-firewall" project_id = var.project_id network = module.vpc-hub.name admin_ranges_enabled = true admin_ranges = values(var.ip_ranges) } ################################################################################ # Spoke 1 networking # ################################################################################ module "vpc-spoke-1" { source = "../../modules/net-vpc" project_id = var.project_id name = "spoke-1" subnets = { default = { ip_cidr_range = var.ip_ranges.spoke-1 name = null region = var.region secondary_ip_range = {} } } } module "vpc-spoke-1-firewall" { source = "../../modules/net-vpc-firewall" project_id = var.project_id network = module.vpc-spoke-1.name admin_ranges_enabled = true admin_ranges = values(var.ip_ranges) } module "nat-spoke-1" { source = "../../modules/net-cloudnat" project_id = var.project_id region = module.vpc-spoke-1.subnet_regions.default name = "spoke-1" router_name = "spoke-1" router_network = module.vpc-spoke-1.self_link } module "hub-to-spoke-1-peering" { source = "../../modules/net-vpc-peering" local_network = module.vpc-hub.self_link peer_network = module.vpc-spoke-1.self_link export_local_custom_routes = true export_peer_custom_routes = false } ################################################################################ # Spoke 2 networking # ################################################################################ module "vpc-spoke-2" { source = "../../modules/net-vpc" project_id = var.project_id name = "spoke-2" subnets = { default = { ip_cidr_range = var.ip_ranges.spoke-2 name = null region = var.region secondary_ip_range = { pods = var.ip_secondary_ranges.spoke-2-pods services = var.ip_secondary_ranges.spoke-2-services } } } } module "vpc-spoke-2-firewall" { source = "../../modules/net-vpc-firewall" project_id = var.project_id network = module.vpc-spoke-2.name admin_ranges_enabled = true admin_ranges = values(var.ip_ranges) } module "nat-spoke-2" { source = "../../modules/net-cloudnat" project_id = var.project_id region = module.vpc-spoke-2.subnet_regions.default name = "spoke-2" router_name = "spoke-2" router_network = module.vpc-spoke-2.self_link } module "hub-to-spoke-2-peering" { source = "../../modules/net-vpc-peering" local_network = module.vpc-hub.self_link peer_network = module.vpc-spoke-2.self_link export_local_custom_routes = true export_peer_custom_routes = false module_depends_on = [module.hub-to-spoke-1-peering.complete] } ################################################################################ # Test VMs # ################################################################################ module "vm-spoke-1" { source = "../../modules/compute-vm" project_id = var.project_id region = module.vpc-spoke-1.subnet_regions.default zone = "${module.vpc-spoke-1.subnet_regions.default}-b" name = "spoke-1-test" network_interfaces = [{ network = module.vpc-spoke-1.self_link, subnetwork = module.vpc-spoke-1.subnet_self_links.default, nat = false, addresses = null }] metadata = { startup-script = local.vm-startup-script } service_account = module.service-account-gce.email service_account_scopes = ["https://www.googleapis.com/auth/cloud-platform"] tags = ["ssh"] } module "vm-spoke-2" { source = "../../modules/compute-vm" project_id = var.project_id region = module.vpc-spoke-2.subnet_regions.default zone = "${module.vpc-spoke-2.subnet_regions.default}-b" name = "spoke-2-test" network_interfaces = [{ network = module.vpc-spoke-2.self_link, subnetwork = module.vpc-spoke-2.subnet_self_links.default, nat = false, addresses = null }] metadata = { startup-script = local.vm-startup-script } service_account = module.service-account-gce.email service_account_scopes = ["https://www.googleapis.com/auth/cloud-platform"] tags = ["ssh"] } module "service-account-gce" { source = "../../modules/iam-service-accounts" project_id = var.project_id names = ["gce-test"] iam_project_roles = { (var.project_id) = [ "roles/container.developer", "roles/logging.logWriter", "roles/monitoring.metricWriter", ] } } ################################################################################ # GKE # ################################################################################ module "cluster-1" { source = "../../modules/gke-cluster" name = "cluster-1" project_id = var.project_id location = "${module.vpc-spoke-2.subnet_regions.default}-b" network = module.vpc-spoke-2.self_link subnetwork = module.vpc-spoke-2.subnet_self_links.default secondary_range_pods = "pods" secondary_range_services = "services" default_max_pods_per_node = 32 labels = { environment = "test" } master_authorized_ranges = { for name, range in var.ip_ranges : name => range } private_cluster_config = { enable_private_nodes = true enable_private_endpoint = true master_ipv4_cidr_block = var.private_service_ranges.spoke-2-cluster-1 } } module "cluster-1-nodepool-1" { source = "../../modules/gke-nodepool" name = "nodepool-1" project_id = var.project_id location = module.cluster-1.location cluster_name = module.cluster-1.name node_config_service_account = module.service-account-gke-node.email } # roles assigned via this module use non-authoritative IAM bindings at the # project level, with no risk of conflicts with pre-existing roles module "service-account-gke-node" { source = "../../modules/iam-service-accounts" project_id = var.project_id names = ["gke-node"] iam_project_roles = { (var.project_id) = [ "roles/logging.logWriter", "roles/monitoring.metricWriter", ] } } ################################################################################ # GKE peering VPN # ################################################################################ module "vpn-hub" { source = "../../modules/net-vpn-static" project_id = var.project_id region = var.region network = module.vpc-hub.name name = "hub" remote_ranges = values(var.private_service_ranges) tunnels = { spoke-2 = { ike_version = 2 peer_ip = module.vpn-spoke-2.address shared_secret = "" traffic_selectors = { local = ["0.0.0.0/0"], remote = null } } } } module "vpn-spoke-2" { source = "../../modules/net-vpn-static" project_id = var.project_id region = var.region network = module.vpc-spoke-2.name name = "spoke-2" # use an aggregate of the remote ranges, so as to be less specific than the # routes exchanged via peering remote_ranges = ["10.0.0.0/8"] tunnels = { spoke-2 = { ike_version = 2 peer_ip = module.vpn-hub.address shared_secret = module.vpn-hub.random_secret traffic_selectors = { local = ["0.0.0.0/0"], remote = null } } } }