cloud-foundation-fabric/modules/net-vpc
Wiktor Niesiobędzki 1a657b31d3 Bump beta provider to 4.48
This is the first version that supports `gateway_api_config` block
2023-01-29 15:50:24 +01:00
..
README.md Fix linting 2023-01-19 18:35:00 +01:00
main.tf Fix typo in net-vpc DNS policies 2023-01-19 17:47:14 +01:00
outputs.tf Deprecate subnets_l7ilb variable, add support for proxy_only and psc subnets. 2022-04-13 16:38:47 +02:00
psa.tf Refactor net-vpc module for Terraform 1.3 (#880) 2022-10-14 11:02:33 +02:00
routes.tf fix psa peering routes, split files (#586) 2022-03-17 16:39:37 +01:00
subnets.tf fix backwards compatibility for vpc subnet descriptions (#926) 2022-10-28 08:13:04 +02:00
variables.tf fix backwards compatibility for vpc subnet descriptions (#926) 2022-10-28 08:13:04 +02:00
versions.tf Bump beta provider to 4.48 2023-01-29 15:50:24 +01:00

README.md

Minimalistic VPC module

This module allows creation and management of VPC networks including subnetworks and subnetwork IAM bindings, Shared VPC activation and service project registration, and one-to-one peering.

Examples

The module allows for several different VPC configurations, some of the most common are shown below.

Simple VPC

module "vpc" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "my-network"
  subnets = [
    {
      ip_cidr_range = "10.0.0.0/24"
      name          = "production"
      region        = "europe-west1"
      secondary_ip_ranges = {
        pods     = "172.16.0.0/20"
        services = "192.168.0.0/24"
      }
    },
    {
      ip_cidr_range = "10.0.16.0/24"
      name          = "production"
      region        = "europe-west2"
    }
  ]
}
# tftest modules=1 resources=3 inventory=simple.yaml

Subnet Options

module "vpc" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "my-network"
  subnets = [
    # simple subnet
    {
      name          = "simple"
      region        = "europe-west1"
      ip_cidr_range = "10.0.0.0/24"
    },
    # custom description and PGA disabled
    {
      name                  = "no-pga"
      region                = "europe-west1"
      ip_cidr_range         = "10.0.1.0/24",
      description           = "Subnet b"
      enable_private_access = false
    },
    # secondary ranges
    {
      name          = "with-secondary-ranges"
      region        = "europe-west1"
      ip_cidr_range = "10.0.2.0/24"
      secondary_ip_ranges = {
        a = "192.168.0.0/24"
        b = "192.168.1.0/24"
      }
    },
    # enable flow logs
    {
      name          = "with-flow-logs"
      region        = "europe-west1"
      ip_cidr_range = "10.0.3.0/24"
      flow_logs_config = {
        flow_sampling        = 0.5
        aggregation_interval = "INTERVAL_10_MIN"
      }
    }
  ]
}
# tftest modules=1 resources=5 inventory=subnet-options.yaml

Subnet IAM

module "vpc" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "my-network"
  subnets = [
    {
      name          = "subnet-1"
      region        = "europe-west1"
      ip_cidr_range = "10.0.1.0/24"
    },
    {
      name          = "subnet-2"
      region        = "europe-west1"
      ip_cidr_range = "10.0.1.0/24"
    }
  ]
  subnet_iam = {
    "europe-west1/subnet-1" = {
      "roles/compute.networkUser" = [
        "user:user1@example.com", "group:group1@example.com"
      ]
    }
    "europe-west1/subnet-2" = {
      "roles/compute.networkUser" = [
        "user:user2@example.com", "group:group2@example.com"
      ]
    }
  }
}
# tftest modules=1 resources=5 inventory=subnet-iam.yaml

Peering

A single peering can be configured for the VPC, so as to allow management of simple scenarios, and more complex configurations like hub and spoke by defining the peering configuration on the spoke VPCs. Care must be taken so as a single peering is created/changed/destroyed at a time, due to the specific behaviour of the peering API calls.

If you only want to create the "local" side of the peering, use peering_create_remote_end to false. This is useful if you don't have permissions on the remote project/VPC to create peerings.

module "vpc-hub" {
  source     = "./fabric/modules/net-vpc"
  project_id = "hub"
  name       = "vpc-hub"
  subnets = [{
    ip_cidr_range = "10.0.0.0/24"
    name          = "subnet-1"
    region        = "europe-west1"
  }]
}

module "vpc-spoke-1" {
  source     = "./fabric/modules/net-vpc"
  project_id = "spoke1"
  name       = "vpc-spoke1"
  subnets = [{
    ip_cidr_range = "10.0.1.0/24"
    name          = "subnet-2"
    region        = "europe-west1"
  }]
  peering_config = {
    peer_vpc_self_link = module.vpc-hub.self_link
    import_routes      = true
  }
}
# tftest modules=2 resources=6 inventory=peering.yaml

Shared VPC

Shared VPC is a project-level functionality which enables a project to share its VPCs with other projects. The shared_vpc_host variable is here to help with rapid prototyping, we recommend leveraging the project module for production usage.

locals {
  service_project_1 = {
    project_id                     = "project1"
    gke_service_account            = "serviceAccount:gke"
    cloud_services_service_account = "serviceAccount:cloudsvc"
  }
  service_project_2 = {
    project_id = "project2"
  }
}

module "vpc-host" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "my-host-network"
  subnets = [
    {
      ip_cidr_range = "10.0.0.0/24"
      name          = "subnet-1"
      region        = "europe-west1"
      secondary_ip_range = {
        pods     = "172.16.0.0/20"
        services = "192.168.0.0/24"
      }
    }
  ]
  shared_vpc_host = true
  shared_vpc_service_projects = [
    local.service_project_1.project_id,
    local.service_project_2.project_id
  ]
  subnet_iam = {
    "europe-west1/subnet-1" = {
      "roles/compute.networkUser" = [
        local.service_project_1.cloud_services_service_account,
        local.service_project_1.gke_service_account
      ]
      "roles/compute.securityAdmin" = [
        local.service_project_1.gke_service_account
      ]
    }
  }
}
# tftest modules=1 resources=7 inventory=shared-vpc.yaml

Private Service Networking

module "vpc" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "my-network"
  subnets = [
    {
      ip_cidr_range = "10.0.0.0/24"
      name          = "production"
      region        = "europe-west1"
    }
  ]
  psa_config = {
    ranges = { myrange = "10.0.1.0/24" }
  }
}
# tftest modules=1 resources=5 inventory=psc.yaml

Private Service Networking with peering routes

Custom routes can be optionally exported/imported through the peering formed with the Google managed PSA VPC.

module "vpc" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "my-network"
  subnets = [
    {
      ip_cidr_range = "10.0.0.0/24"
      name          = "production"
      region        = "europe-west1"
    }
  ]
  psa_config = {
    ranges        = { myrange = "10.0.1.0/24" }
    export_routes = true
    import_routes = true
  }
}
# tftest modules=1 resources=5 inventory=psc-routes.yaml

Subnets for Private Service Connect, Proxy-only subnets

Along with common private subnets module supports creation more service specific subnets for the following purposes:

module "vpc" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "my-network"

  subnets_proxy_only = [
    {
      ip_cidr_range = "10.0.1.0/24"
      name          = "regional-proxy"
      region        = "europe-west1"
      active        = true
    }
  ]
  subnets_psc = [
    {
      ip_cidr_range = "10.0.3.0/24"
      name          = "psc"
      region        = "europe-west1"
    }
  ]
}
# tftest modules=1 resources=3 inventory=proxy-only-subnets.yaml

DNS Policies

module "vpc" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "my-network"
  dns_policy = {
    inbound = true
    outbound = {
      private_ns = ["10.0.0.1"]
      public_ns  = ["8.8.8.8"]
    }
  }
  subnets = [
    {
      ip_cidr_range = "10.0.0.0/24"
      name          = "production"
      region        = "europe-west1"
    }
  ]
}
# tftest modules=1 resources=3 inventory=dns-policies.yaml

Subnet Factory

The net-vpc module includes a subnet factory (see Resource Factories) for the massive creation of subnets leveraging one configuration file per subnet.

module "vpc" {
  source      = "./fabric/modules/net-vpc"
  project_id  = "my-project"
  name        = "my-network"
  data_folder = "config/subnets"
}
# tftest modules=1 resources=3 files=subnet-simple,subnet-detailed inventory=factory.yaml
# tftest-file id=subnet-simple path=config/subnets/subnet-simple.yaml
region: europe-west4
ip_cidr_range: 10.0.1.0/24
# tftest-file id=subnet-detailed path=config/subnets/subnet-detailed.yaml
region: europe-west1
description: Sample description
ip_cidr_range: 10.0.0.0/24
# optional attributes
enable_private_access: false   # defaults to true
iam_users: ["foobar@example.com"] # grant compute/networkUser to users
iam_groups: ["lorem@example.com"] # grant compute/networkUser to groups
iam_service_accounts: ["fbz@prj.iam.gserviceaccount.com"]
secondary_ip_ranges:              # map of secondary ip ranges
  secondary-range-a: 192.168.0.0/24
flow_logs:                        # enable, set to empty map to use defaults
  aggregation_interval: "INTERVAL_5_SEC"
  flow_sampling: 0.5
  metadata: "INCLUDE_ALL_METADATA"
  filter_expression: null

Custom Routes

VPC routes can be configured through the routes variable.

locals {
  route_types = {
    gateway    = "global/gateways/default-internet-gateway"
    instance   = "zones/europe-west1-b/test"
    ip         = "192.168.0.128"
    ilb        = "regions/europe-west1/forwardingRules/test"
    vpn_tunnel = "regions/europe-west1/vpnTunnels/foo"
  }
}
module "vpc" {
  source     = "./fabric/modules/net-vpc"
  for_each   = local.route_types
  project_id = "my-project"
  name       = "my-network-with-route-${replace(each.key, "_", "-")}"
  routes = {
    next-hop = {
      dest_range    = "192.168.128.0/24"
      tags          = null
      next_hop_type = each.key
      next_hop      = each.value
    }
    gateway = {
      dest_range    = "0.0.0.0/0",
      priority      = 100
      tags          = ["tag-a"]
      next_hop_type = "gateway",
      next_hop      = "global/gateways/default-internet-gateway"
    }
  }
}
# tftest modules=5 resources=15 inventory=routes.yaml

Variables

name description type required default
name The name of the network being created. string
project_id The ID of the project where this VPC will be created. string
auto_create_subnetworks Set to true to create an auto mode subnet, defaults to custom mode. bool false
data_folder An optional folder containing the subnet configurations in YaML format. string null
delete_default_routes_on_create Set to true to delete the default routes at creation time. bool false
description An optional description of this resource (triggers recreation on change). string "Terraform-managed."
dns_policy DNS policy setup for the VPC. object({…}) null
mtu Maximum Transmission Unit in bytes. The minimum value for this field is 1460 (the default) and the maximum value is 1500 bytes. number null
peering_config VPC peering configuration. object({…}) null
psa_config The Private Service Access configuration for Service Networking. object({…}) null
routes Network routes, keyed by name. map(object({…})) {}
routing_mode The network routing mode (default 'GLOBAL'). string "GLOBAL"
shared_vpc_host Enable shared VPC for this project. bool false
shared_vpc_service_projects Shared VPC service projects to register with this host. list(string) []
subnet_iam Subnet IAM bindings in {REGION/NAME => {ROLE => [MEMBERS]} format. map(map(list(string))) {}
subnets Subnet configuration. list(object({…})) []
subnets_proxy_only List of proxy-only subnets for Regional HTTPS or Internal HTTPS load balancers. Note: Only one proxy-only subnet for each VPC network in each region can be active. list(object({…})) []
subnets_psc List of subnets for Private Service Connect service producers. list(object({…})) []
vpc_create Create VPC. When set to false, uses a data source to reference existing VPC. bool true

Outputs

name description sensitive
bindings Subnet IAM bindings.
name The name of the VPC being created.
network Network resource.
project_id Project ID containing the network. Use this when you need to create resources after the VPC is fully set up (e.g. subnets created, shared VPC service projects attached, Private Service Networking configured).
self_link The URI of the VPC being created.
subnet_ips Map of subnet address ranges keyed by name.
subnet_regions Map of subnet regions keyed by name.
subnet_secondary_ranges Map of subnet secondary ranges keyed by name.
subnet_self_links Map of subnet self links keyed by name.
subnets Subnet resources.
subnets_proxy_only L7 ILB or L7 Regional LB subnet resources.
subnets_psc Private Service Connect subnet resources.

The key format is subnet_region/subnet_name. For example europe-west1/my_subnet.