cloud-foundation-fabric/modules/net-ncc
Julio Diez 1b4ba11dcd Make IPs for the CR interfaces optional 2023-03-08 20:00:55 +01:00
..
images Add image for load-balanced router appliances example 2023-03-07 11:10:19 +01:00
README.md Generated variable table via tfdoc 2023-03-07 13:04:15 +01:00
main.tf Reimplement the module to manage only one spoke 2023-03-08 20:00:55 +01:00
variables.tf Make IPs for the CR interfaces optional 2023-03-08 20:00:55 +01:00

README.md

Network Connectivity Center Module

This module allows the creation and management of an NCC-based hub-and-spoke architecture. It focuses in site-to-cloud connectivity with network virtual appliances (NVAs) as the backing resource for spokes. This allows to connect an external network to Google Cloud by using a SD-WAN router or another appliance with BGP capabilities. It does not handle site-to-site data transfer which is not available in all regions, in particular in EMEA.

The module can manage a hub, multiple spokes, and corresponding Cloud Routers and BGP sessions to network virtual appliances. The NVAs themselves, VPCs, and other Google Cloud resources should be managed externally.

Examples

Connect a site to a VPC network

In this example a router appliance connects with a peer router in an on-premises network, and also peers with a Cloud Router.

module "vpc" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "network-a"
  subnets = [
    {
      name          = "subnet-a"
      ip_cidr_range = "10.1.3.0/24"
      region        = "us-central1"
    }
  ]
}

module "nva1" {
  source     = "./fabric/modules/compute-vm"
  project_id = "my-project"
  zone       = "us-central1-a"
  name       = "router-app-a"
  network_interfaces = [{
    network    = module.vpc.self_link
    subnetwork = module.vpc.subnet_self_links["us-central1/subnet-a"]
    addresses  = { external = null, internal = "10.1.3.8" }
  }]
  can_ip_forward = true
}

module "ncc" {
  source     = "./fabric/modules/net-ncc"
  asn        = 65000
  name       = "ncc-hub"
  project_id = "my-project"
  spokes = {
    spoke-a = {
      vpc        = module.vpc.name
      region     = "us-central1"
      subnetwork = module.vpc.subnet_self_links["us-central1/subnet-a"]
      nvas = [
        {
          vm = module.nva1.self_link
          ip = module.nva1.internal_ip
        }
      ]
      router = {
        ip1      = "10.1.3.14"
        ip2      = "10.1.3.15"
        peer_asn = 65001
      }
    }
  }
}
# tftest modules=3 resources=10

Connect a site to two VPC networks

In the following topology, a router appliance instance has interfaces in two VPC networks. Each interface has been used to create a Router appliance spoke.

module "vpc-a" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "network-a"
  subnets = [
    {
      name          = "subnet-a"
      ip_cidr_range = "10.1.3.0/24"
      region        = "us-central1"
    }
  ]
}

module "vpc-b" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "network-b"
  subnets = [
    {
      name          = "subnet-b"
      ip_cidr_range = "192.168.10.0/24"
      region        = "us-central1"
    }
  ]
}

module "nva1" {
  source     = "./fabric/modules/compute-vm"
  project_id = "my-project"
  zone       = "us-central1-a"
  name       = "router-app-a"
  network_interfaces = [
    {
      network    = module.vpc-a.self_link
      subnetwork = module.vpc-a.subnet_self_links["us-central1/subnet-a"]
      addresses  = { external = null, internal = "10.1.3.8" }
    },
    {
      network    = module.vpc-b.self_link
      subnetwork = module.vpc-b.subnet_self_links["us-central1/subnet-b"]
      addresses  = { external = null, internal = "192.168.10.3" }
    }
  ]
  can_ip_forward = true
}

module "ncc" {
  source     = "./fabric/modules/net-ncc"
  asn        = 65000
  name       = "ncc-hub"
  project_id = "my-project"
  spokes = {
    spoke-a = {
      vpc        = module.vpc-a.name
      region     = "us-central1"
      subnetwork = module.vpc-a.subnet_self_links["us-central1/subnet-a"]
      nvas = [
        {
          vm = module.nva1.self_link
          ip = module.nva1.internal_ips[0]
        }
      ]
      router = {
        ip1      = "10.1.3.14"
        ip2      = "10.1.3.15"
        peer_asn = 65001
      }
    },
    spoke-b = {
      vpc        = module.vpc-b.name
      region     = "us-central1"
      subnetwork = module.vpc-b.subnet_self_links["us-central1/subnet-b"]
      nvas = [
        {
          vm = module.nva1.self_link
          ip = module.nva1.internal_ips[1]
        }
      ]
      router = {
        ip1      = "192.168.10.14"
        ip2      = "192.168.10.15"
        peer_asn = 65001
      }
    }
  }
}
# tftest modules=4 resources=18

Using load-balanced router appliances

The following topology shows a site that uses load-balanced router appliance instances to connect to Google Cloud. Both router appliance instances are backing resources for the same spoke.

module "vpc" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "network-a"
  subnets = [
    {
      name          = "subnet-a-1"
      ip_cidr_range = "10.0.1.0/24"
      region        = "us-west1"
    }
  ]
}

module "nva1" {
  source     = "./fabric/modules/compute-vm"
  project_id = "my-project"
  zone       = "us-west1-a"
  name       = "router-app-a"
  network_interfaces = [{
    network    = module.vpc.self_link
    subnetwork = module.vpc.subnet_self_links["us-west1/subnet-a-1"]
    addresses  = { external = null, internal = "10.0.1.10" }
  }]
  can_ip_forward = true
}

module "nva2" {
  source     = "./fabric/modules/compute-vm"
  project_id = "my-project"
  zone       = "us-west1-b"
  name       = "router-app-b"
  network_interfaces = [{
    network    = module.vpc.self_link
    subnetwork = module.vpc.subnet_self_links["us-west1/subnet-a-1"]
    addresses  = { external = null, internal = "10.0.1.11" }
  }]
  can_ip_forward = true
}

module "ncc" {
  source     = "./fabric/modules/net-ncc"
  asn        = 65000
  name       = "ncc-hub"
  project_id = "my-project"
  spokes = {
    spoke-a = {
      vpc        = module.vpc.name
      region     = "us-west1"
      subnetwork = module.vpc.subnet_self_links["us-west1/subnet-a-1"]
      nvas = [
        {
          vm = module.nva1.self_link
          ip = module.nva1.internal_ip
        },
        {
          vm = module.nva2.self_link
          ip = module.nva2.internal_ip
        }
      ]
      router = {
        ip1      = "10.0.1.5"
        ip2      = "10.0.1.6"
        peer_asn = 65001
      }
    }
  }
}
# tftest modules=4 resources=13

It is possible to add custom route advertisements. For example, suppose the VPC network-a is peered to another VPC network-b using the CIDR range 10.10.0.0/24. If you want to reach this VPC network-b from the on-premises network you should advertise its range to the router appliances:

module "vpc" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "network-a"
  subnets = [
    {
      name          = "subnet-a-1"
      ip_cidr_range = "10.0.1.0/24"
      region        = "us-west1"
    }
  ]
}

module "nva1" {
  source     = "./fabric/modules/compute-vm"
  project_id = "my-project"
  zone       = "us-west1-a"
  name       = "router-app-a"
  network_interfaces = [{
    network    = module.vpc.self_link
    subnetwork = module.vpc.subnet_self_links["us-west1/subnet-a-1"]
    addresses  = { external = null, internal = "10.0.1.10" }
  }]
  can_ip_forward = true
}

module "nva2" {
  source     = "./fabric/modules/compute-vm"
  project_id = "my-project"
  zone       = "us-west1-b"
  name       = "router-app-b"
  network_interfaces = [{
    network    = module.vpc.self_link
    subnetwork = module.vpc.subnet_self_links["us-west1/subnet-a-1"]
    addresses  = { external = null, internal = "10.0.1.11" }
  }]
  can_ip_forward = true
}

module "ncc" {
  source     = "./fabric/modules/net-ncc"
  asn        = 65000
  name       = "ncc-hub"
  project_id = "my-project"
  spokes = {
    spoke-a = {
      vpc        = module.vpc.name
      region     = "us-west1"
      subnetwork = module.vpc.subnet_self_links["us-west1/subnet-a-1"]
      nvas = [
        {
          vm = module.nva1.self_link
          ip = module.nva1.internal_ip
        },
        {
          vm = module.nva2.self_link
          ip = module.nva2.internal_ip
        }
      ]
      router = {
        custom_advertise = {
          all_subnets = true
          ip_ranges = {
            "peered-vpc-b" = "10.10.0.0/24"
          }
        }
        ip1      = "10.0.1.5"
        ip2      = "10.0.1.6"
        peer_asn = 65001
      }
    }
  }
}
# tftest modules=4 resources=13

Variables

name description type required default
asn ASN for all CRs in the hub. number
name The name of the NCC hub being created. string
project_id The ID of the project where the NCC hub & spokes will be created. string
spokes List of NCC spokes. map(object({…}))
description An optional description of the NCC hub. string "Terraform-managed."