@spoke1-vm:~$ping 192.168.2.2
+```
+
+## Reference
+
+### Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.3, < 2.0 |
+
+### Providers
+
+| Name | Version |
+|------|---------|
+| [google](#provider\_google) | n/a |
+
+### Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [autoscale](#module\_autoscale) | ../../modules/autoscale/ | n/a |
+| [iam\_service\_account](#module\_iam\_service\_account) | ../../modules/iam_service_account | n/a |
+| [lb\_external](#module\_lb\_external) | ../../modules/lb_external | n/a |
+| [lb\_internal](#module\_lb\_internal) | ../../modules/lb_internal | n/a |
+| [vpc](#module\_vpc) | ../../modules/vpc | n/a |
+| [vpc\_peering](#module\_vpc\_peering) | ../../modules/vpc-peering | n/a |
+
+### Resources
+
+| Name | Type |
+|------|------|
+| [google_compute_instance.linux_vm](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance) | resource |
+| [google_compute_route.this](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_route) | resource |
+| [google_compute_image.my_image](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/compute_image) | data source |
+
+### Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [autoscale](#input\_autoscale) | A map containing each vmseries autoscale setting.
Zonal or regional managed instance group type is controolled from the `autoscale_regional_mig` variable for all autoscale instances.
Example of variable deployment :autoscale = {
fw-autoscale-common = {
name = "fw-autoscale-common"
zones = {
zone1 = "us-east4-b"
zone2 = "us-east4-c"
}
named_ports = [
{
name = "http"
port = 80
},
{
name = "https"
port = 443
}
]
service_account_key = "sa-vmseries-01"
min_vmseries_replicas = 2
max_vmseries_replicas = 4
create_pubsub_topic = true
autoscaler_metrics = {
"custom.googleapis.com/VMSeries/panSessionUtilization" = {
target = 70
}
"custom.googleapis.com/VMSeries/panSessionThroughputKbps" = {
target = 700000
}
}
bootstrap_options = {
type = "dhcp-client"
dhcp-send-hostname = "yes"
dhcp-send-client-id = "yes"
dhcp-accept-server-hostname = "yes"
dhcp-accept-server-domain = "yes"
mgmt-interface-swap = "enable"
panorama-server = "1.1.1.1"
ssh-keys = "admin:" # Replace this value with client data
}
network_interfaces = [
{
vpc_network_key = "fw-untrust-vpc"
subnetwork_key = "fw-untrust-sub"
create_public_ip = true
},
{
vpc_network_key = "fw-mgmt-vpc"
subnetwork_key = "fw-mgmt-sub"
create_public_ip = true
},
{
vpc_network_key = "fw-trust-vpc"
subnetwork_key = "fw-trust-sub"
}
]
}
}
| `any` | `{}` | no |
+| [autoscale\_common](#input\_autoscale\_common) | A map containing common vmseries autoscale setting.
Bootstrap options can be moved between vmseries autoscale individual instances variable (`autoscale`) and this common vmseries autoscale variable (`autoscale_common`).
Example of variable deployment :autoscale_common = {
image = "vmseries-flex-byol-1110"
machine_type = "n2-standard-4"
min_cpu_platform = "Intel Cascade Lake"
disk_type = "pd-ssd"
scopes = [
"https://www.googleapis.com/auth/compute.readonly",
"https://www.googleapis.com/auth/cloud.useraccounts.readonly",
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring.write",
]
tags = ["vmseries-autoscale"]
update_policy_type = "OPPORTUNISTIC"
cooldown_period = 480
bootstrap_options = [
panorama_server = "1.1.1.1"
]
}
| `any` | `{}` | no |
+| [autoscale\_regional\_mig](#input\_autoscale\_regional\_mig) | Sets the managed instance group type to either a regional (if `true`) or a zonal (if `false`).
For more information please see [About regional MIGs](https://cloud.google.com/compute/docs/instance-groups/regional-migs#why_choose_regional_managed_instance_groups). | `bool` | `true` | no |
+| [lbs\_external](#input\_lbs\_external) | A map containing each external loadbalancer setting.
Example of variable deployment :lbs_external = {
"external-lb" = {
name = "external-lb"
backends = ["fw-vmseries-01", "fw-vmseries-02"]
rules = {
"all-ports" = {
ip_protocol = "L3_DEFAULT"
}
}
http_health_check_port = "80"
http_health_check_request_path = "/php/login.php"
}
}
For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/lb_external#inputs)
Multiple keys can be added and will be deployed by the code. | `map(any)` | `{}` | no |
+| [lbs\_internal](#input\_lbs\_internal) | A map containing each internal loadbalancer setting.
Note : private IP reservation is not by default within the example as it may overlap with autoscale IP allocation.
Example of variable deployment :lbs_internal = {
"internal-lb" = {
name = "internal-lb"
health_check_port = "80"
backends = ["fw-vmseries-01", "fw-vmseries-02"]
subnetwork_key = "fw-trust-sub"
vpc_network_key = "fw-trust-vpc"
}
}
For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/lb_internal#inputs)
Multiple keys can be added and will be deployed by the code. | `map(any)` | `{}` | no |
+| [linux\_vms](#input\_linux\_vms) | A map containing each Linux VM configuration that will be placed in SPOKE VPCs for testing purposes.
Example of varaible deployment:linux_vms = {
spoke1-vm = {
linux_machine_type = "n2-standard-4"
zone = "us-east1-b"
linux_disk_size = "50" # Modify this value as per deployment requirements
vpc_network_key = "fw-spoke1-vpc"
subnetwork_key = "fw-spoke1-sub"
private_ip = "192.168.1.2"
scopes = [
"https://www.googleapis.com/auth/compute.readonly",
"https://www.googleapis.com/auth/cloud.useraccounts.readonly",
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring.write",
]
service_account_key = "sa-linux-01"
}
}
| `map(any)` | `{}` | no |
+| [name\_prefix](#input\_name\_prefix) | A string to prefix resource namings. | `string` | `"example-"` | no |
+| [networks](#input\_networks) | A map containing each network setting.
Example of variable deployment :networks = {
fw-mgmt-vpc = {
vpc_name = "fw-mgmt-vpc"
create_network = true
delete_default_routes_on_create = false
mtu = "1460"
routing_mode = "REGIONAL"
subnetworks = {
fw-mgmt-sub = {
name = "fw-mgmt-sub"
create_subnetwork = true
ip_cidr_range = "10.10.10.0/28"
region = "us-east1"
}
}
firewall_rules = {
allow-mgmt-ingress = {
name = "allow-mgmt-vpc"
source_ranges = ["10.10.10.0/24", "1.1.1.1/32"] # Replace 1.1.1.1/32 with your own souurce IP address for management purposes.
priority = "1000"
allowed_protocol = "all"
allowed_ports = []
}
}
}
}
For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/vpc#input_networks)
Multiple keys can be added and will be deployed by the code. | `any` | `{}` | no |
+| [project](#input\_project) | The project name to deploy the infrastructure in to. | `string` | `null` | no |
+| [region](#input\_region) | The region into which to deploy the infrastructure in to. | `string` | `"us-central1"` | no |
+| [routes](#input\_routes) | A map containing each route setting. Note that you can only add routes using a next-hop type of internal load-balance rule.
Example of variable deployment :routes = {
"default-route-trust" = {
name = "fw-default-trust"
destination_range = "0.0.0.0/0"
vpc_network_key = "fw-trust-vpc"
lb_internal_name = "internal-lb"
}
}
Multiple keys can be added and will be deployed by the code. | `map(any)` | `{}` | no |
+| [service\_accounts](#input\_service\_accounts) | A map containing each service account setting.
Example of variable deployment :service_accounts = {
"sa-vmseries-01" = {
service_account_id = "sa-vmseries-01"
display_name = "VM-Series SA"
roles = [
"roles/compute.networkViewer",
"roles/logging.logWriter",
"roles/monitoring.metricWriter",
"roles/monitoring.viewer",
"roles/viewer"
]
}
}
For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/iam_service_account#Inputs)
Multiple keys can be added and will be deployed by the code. | `map(any)` | `{}` | no |
+| [vpc\_peerings](#input\_vpc\_peerings) | A map containing each VPC peering setting.
Example of variable deployment :vpc_peerings = {
"trust-to-spoke1" = {
local_network_key = "fw-trust-vpc"
peer_network_key = "fw-spoke1-vpc"
local_export_custom_routes = true
local_import_custom_routes = true
local_export_subnet_routes_with_public_ip = true
local_import_subnet_routes_with_public_ip = true
peer_export_custom_routes = true
peer_import_custom_routes = true
peer_export_subnet_routes_with_public_ip = true
peer_import_subnet_routes_with_public_ip = true
}
}
For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/vpc-peering#inputs)
Multiple keys can be added and will be deployed by the code. | `map(any)` | `{}` | no |
+
+### Outputs
+
+| Name | Description |
+|------|-------------|
+| [lbs\_external\_ips](#output\_lbs\_external\_ips) | Public IP addresses of external network loadbalancers. |
+| [lbs\_internal\_ips](#output\_lbs\_internal\_ips) | Private IP addresses of internal network loadbalancers. |
+| [linux\_vm\_ips](#output\_linux\_vm\_ips) | Private IP addresses of Linux VMs. |
+| [pubsub\_subscription\_id](#output\_pubsub\_subscription\_id) | The resource ID of the Pub/Sub Subscription. |
+| [pubsub\_topic\_id](#output\_pubsub\_topic\_id) | The resource ID of the Pub/Sub Topic. |
+
diff --git a/examples/vpc_peering_common_with_autoscale/example.tfvars b/examples/vpc_peering_common_with_autoscale/example.tfvars
new file mode 100644
index 00000000..2573804c
--- /dev/null
+++ b/examples/vpc_peering_common_with_autoscale/example.tfvars
@@ -0,0 +1,340 @@
+# General
+project = ""
+region = "us-east4"
+name_prefix = ""
+
+# Service accounts
+
+service_accounts = {
+ sa-vmseries-01 = {
+ service_account_id = "sa-vmseries-01"
+ display_name = "VM-Series SA"
+ roles = [
+ "roles/compute.networkViewer",
+ "roles/logging.logWriter",
+ "roles/monitoring.metricWriter",
+ "roles/monitoring.viewer",
+ "roles/viewer"
+ ]
+ },
+ sa-linux-01 = {
+ service_account_id = "sa-linux-01"
+ display_name = "Linux VMs SA"
+ roles = [
+ "roles/compute.networkViewer",
+ "roles/logging.logWriter",
+ "roles/monitoring.metricWriter",
+ "roles/monitoring.viewer",
+ "roles/viewer"
+ ]
+ }
+}
+
+# VPC
+
+networks = {
+ fw-mgmt-vpc = {
+ vpc_name = "fw-mgmt-vpc"
+ create_network = true
+ delete_default_routes_on_create = false
+ mtu = "1460"
+ routing_mode = "REGIONAL"
+ subnetworks = {
+ fw-mgmt-sub = {
+ name = "fw-mgmt-sub"
+ create_subnetwork = true
+ ip_cidr_range = "10.10.10.0/28"
+ region = "us-east4"
+ }
+ }
+ firewall_rules = {
+ allow-mgmt-ingress = {
+ name = "allow-mgmt-vpc"
+ source_ranges = ["1.1.1.1/32"] # Replace 1.1.1.1/32 with your own souurce IP address for management purposes.
+ priority = "1000"
+ allowed_protocol = "all"
+ allowed_ports = []
+ }
+ }
+ },
+ fw-untrust-vpc = {
+ vpc_name = "fw-untrust-vpc"
+ create_network = true
+ delete_default_routes_on_create = false
+ mtu = "1460"
+ routing_mode = "REGIONAL"
+ subnetworks = {
+ fw-untrust-sub = {
+ name = "fw-untrust-sub"
+ create_subnetwork = true
+ ip_cidr_range = "10.10.11.0/28"
+ region = "us-east4"
+ }
+ }
+ firewall_rules = {
+ allow-untrust-ingress = {
+ name = "allow-untrust-vpc"
+ source_ranges = ["35.191.0.0/16", "209.85.152.0/22", "209.85.204.0/22", "1.1.1.1/32"] # Replace 1.1.1.1/32 with your own souurce IP address for management purposes.
+ priority = "1000"
+ allowed_protocol = "all"
+ allowed_ports = []
+ }
+ }
+ },
+ fw-trust-vpc = {
+ vpc_name = "fw-trust-vpc"
+ create_network = true
+ delete_default_routes_on_create = true
+ mtu = "1460"
+ routing_mode = "REGIONAL"
+ subnetworks = {
+ fw-trust-sub = {
+ name = "fw-trust-sub"
+ create_subnetwork = true
+ ip_cidr_range = "10.10.12.0/28"
+ region = "us-east4"
+ }
+ }
+ firewall_rules = {
+ allow-trust-ingress = {
+ name = "allow-trust-vpc"
+ source_ranges = ["192.168.0.0/16", "35.191.0.0/16", "130.211.0.0/22"]
+ priority = "1000"
+ allowed_protocol = "all"
+ allowed_ports = []
+ }
+ }
+ },
+ fw-spoke1-vpc = {
+ vpc_name = "fw-spoke1-vpc"
+ create_network = true
+ delete_default_routes_on_create = true
+ mtu = "1460"
+ routing_mode = "REGIONAL"
+ subnetworks = {
+ fw-spoke1-sub = {
+ name = "fw-spoke1-sub"
+ create_subnetwork = true
+ ip_cidr_range = "192.168.1.0/28"
+ region = "us-east4"
+ }
+ }
+ firewall_rules = {
+ allow-spoke1-ingress = {
+ name = "allow-spoke1-vpc"
+ source_ranges = ["192.168.0.0/16", "35.235.240.0/20", "10.10.12.0/28"]
+ priority = "1000"
+ allowed_protocol = "all"
+ allowed_ports = []
+ }
+ }
+ },
+ fw-spoke2-vpc = {
+ vpc_name = "fw-spoke2-vpc"
+ create_network = true
+ delete_default_routes_on_create = true
+ mtu = "1460"
+ routing_mode = "REGIONAL"
+ subnetworks = {
+ fw-spoke2-sub = {
+ name = "fw-spoke2-sub"
+ create_subnetwork = true
+ ip_cidr_range = "192.168.2.0/28"
+ region = "us-east4"
+ }
+ }
+ firewall_rules = {
+ allow-spoke2-ingress = {
+ name = "allow-spoke2-vpc"
+ source_ranges = ["192.168.0.0/16", "35.235.240.0/20", "10.10.12.0/28"]
+ priority = "1000"
+ allowed_protocol = "all"
+ allowed_ports = []
+ }
+ }
+ }
+}
+
+# VPC Peerings
+
+vpc_peerings = {
+ trust-to-spoke1 = {
+ local_network_key = "fw-trust-vpc"
+ peer_network_key = "fw-spoke1-vpc"
+
+ local_export_custom_routes = true
+ local_import_custom_routes = true
+ local_export_subnet_routes_with_public_ip = true
+ local_import_subnet_routes_with_public_ip = true
+
+ peer_export_custom_routes = true
+ peer_import_custom_routes = true
+ peer_export_subnet_routes_with_public_ip = true
+ peer_import_subnet_routes_with_public_ip = true
+ },
+ trust-to-spoke2 = {
+ local_network_key = "fw-trust-vpc"
+ peer_network_key = "fw-spoke2-vpc"
+
+ local_export_custom_routes = true
+ local_import_custom_routes = true
+ local_export_subnet_routes_with_public_ip = true
+ local_import_subnet_routes_with_public_ip = true
+
+ peer_export_custom_routes = true
+ peer_import_custom_routes = true
+ peer_export_subnet_routes_with_public_ip = true
+ peer_import_subnet_routes_with_public_ip = true
+ }
+}
+
+# Static routes
+routes = {
+ fw-default-trust = {
+ name = "fw-default-trust"
+ destination_range = "0.0.0.0/0"
+ vpc_network_key = "fw-trust-vpc"
+ lb_internal_key = "internal-lb"
+ }
+}
+
+# Autoscale
+autoscale_regional_mig = true
+
+autoscale_common = {
+ image = "vmseries-flex-byol-1110"
+ machine_type = "n2-standard-4"
+ min_cpu_platform = "Intel Cascade Lake"
+ disk_type = "pd-ssd"
+ scopes = [
+ "https://www.googleapis.com/auth/compute.readonly",
+ "https://www.googleapis.com/auth/cloud.useraccounts.readonly",
+ "https://www.googleapis.com/auth/devstorage.read_only",
+ "https://www.googleapis.com/auth/logging.write",
+ "https://www.googleapis.com/auth/monitoring.write",
+ ]
+ tags = ["vmseries-autoscale"]
+ update_policy_type = "OPPORTUNISTIC"
+ cooldown_period = 480
+}
+
+autoscale = {
+ fw-autoscale-common = {
+ name = "fw-autoscale-common"
+ zones = {
+ zone1 = "us-east4-b"
+ zone2 = "us-east4-c"
+ }
+ named_ports = [
+ {
+ name = "http"
+ port = 80
+ },
+ {
+ name = "https"
+ port = 443
+ }
+ ]
+ service_account_key = "sa-vmseries-01"
+ min_vmseries_replicas = 2
+ max_vmseries_replicas = 4
+ create_pubsub_topic = true
+ autoscaler_metrics = {
+ "custom.googleapis.com/VMSeries/panSessionUtilization" = {
+ target = 70
+ }
+ "custom.googleapis.com/VMSeries/panSessionThroughputKbps" = {
+ target = 700000
+ }
+ }
+ bootstrap_options = {
+ type = "dhcp-client"
+ dhcp-send-hostname = "yes"
+ dhcp-send-client-id = "yes"
+ dhcp-accept-server-hostname = "yes"
+ dhcp-accept-server-domain = "yes"
+ mgmt-interface-swap = "enable"
+ panorama-server = "1.1.1.1"
+ ssh-keys = "admin:" # Replace this value with client data
+ }
+ network_interfaces = [
+ {
+ vpc_network_key = "fw-untrust-vpc"
+ subnetwork_key = "fw-untrust-sub"
+ create_public_ip = true
+ },
+ {
+ vpc_network_key = "fw-mgmt-vpc"
+ subnetwork_key = "fw-mgmt-sub"
+ create_public_ip = true
+ },
+ {
+ vpc_network_key = "fw-trust-vpc"
+ subnetwork_key = "fw-trust-sub"
+ }
+ ]
+ }
+}
+
+# Spoke Linux VMs
+linux_vms = {
+ spoke1-vm = {
+ linux_machine_type = "n2-standard-4"
+ zone = "us-east4-b"
+ linux_disk_size = "50"
+ vpc_network_key = "fw-spoke1-vpc"
+ subnetwork_key = "fw-spoke1-sub"
+ private_ip = "192.168.1.2"
+ scopes = [
+ "https://www.googleapis.com/auth/compute.readonly",
+ "https://www.googleapis.com/auth/cloud.useraccounts.readonly",
+ "https://www.googleapis.com/auth/devstorage.read_only",
+ "https://www.googleapis.com/auth/logging.write",
+ "https://www.googleapis.com/auth/monitoring.write",
+ ]
+ service_account_key = "sa-linux-01"
+ },
+ spoke2-vm = {
+ linux_machine_type = "n2-standard-4"
+ zone = "us-east4-b"
+ linux_disk_size = "50"
+ vpc_network_key = "fw-spoke2-vpc"
+ subnetwork_key = "fw-spoke2-sub"
+ private_ip = "192.168.2.2"
+ scopes = [
+ "https://www.googleapis.com/auth/compute.readonly",
+ "https://www.googleapis.com/auth/cloud.useraccounts.readonly",
+ "https://www.googleapis.com/auth/devstorage.read_only",
+ "https://www.googleapis.com/auth/logging.write",
+ "https://www.googleapis.com/auth/monitoring.write",
+ ]
+ service_account_key = "sa-linux-01"
+ }
+}
+
+# Internal Network Loadbalancer
+lbs_internal = {
+ internal-lb = {
+ name = "internal-lb"
+ health_check_port = "80"
+ backends = ["fw-autoscale-common"]
+ subnetwork = "fw-trust-sub"
+ vpc_network_key = "fw-trust-vpc"
+ subnetwork_key = "fw-trust-sub"
+ }
+}
+
+# External Network Loadbalancer
+lbs_external = {
+ external-lb = {
+ name = "external-lb"
+ backends = ["fw-autoscale-common"]
+ rules = {
+ all-ports = {
+ ip_protocol = "L3_DEFAULT"
+ }
+ }
+ http_health_check_port = "80"
+ http_health_check_request_path = "/php/login.php"
+ }
+}
\ No newline at end of file
diff --git a/examples/vpc_peering_common_with_autoscale/main.tf b/examples/vpc_peering_common_with_autoscale/main.tf
new file mode 100644
index 00000000..1309eec1
--- /dev/null
+++ b/examples/vpc_peering_common_with_autoscale/main.tf
@@ -0,0 +1,183 @@
+module "iam_service_account" {
+ source = "../../modules/iam_service_account"
+
+ for_each = var.service_accounts
+
+ service_account_id = "${var.name_prefix}${each.value.service_account_id}"
+ display_name = "${var.name_prefix}${each.value.display_name}"
+ roles = each.value.roles
+ project_id = var.project
+}
+
+module "vpc" {
+ source = "../../modules/vpc"
+
+ for_each = var.networks
+
+ project_id = var.project
+ name = "${var.name_prefix}${each.value.vpc_name}"
+ create_network = each.value.create_network
+ delete_default_routes_on_create = each.value.delete_default_routes_on_create
+ mtu = each.value.mtu
+ routing_mode = each.value.routing_mode
+ subnetworks = { for k, v in each.value.subnetworks : k => merge(v, {
+ name = "${var.name_prefix}${v.name}"
+ })
+ }
+ firewall_rules = try({ for k, v in each.value.firewall_rules : k => merge(v, {
+ name = "${var.name_prefix}${v.name}"
+ })
+ }, {})
+}
+
+resource "google_compute_route" "this" {
+
+ for_each = var.routes
+
+ name = "${var.name_prefix}${each.value.name}"
+ dest_range = each.value.destination_range
+ network = module.vpc[each.value.vpc_network_key].network.self_link
+ next_hop_ilb = module.lb_internal[each.value.lb_internal_key].forwarding_rule
+ priority = 100
+}
+
+module "vpc_peering" {
+ source = "../../modules/vpc-peering"
+
+ for_each = var.vpc_peerings
+
+ local_network = module.vpc[each.value.local_network_key].network.id
+ peer_network = module.vpc[each.value.peer_network_key].network.id
+
+ local_export_custom_routes = each.value.local_export_custom_routes
+ local_import_custom_routes = each.value.local_import_custom_routes
+ local_export_subnet_routes_with_public_ip = each.value.local_export_subnet_routes_with_public_ip
+ local_import_subnet_routes_with_public_ip = each.value.local_import_subnet_routes_with_public_ip
+
+ peer_export_custom_routes = each.value.peer_export_custom_routes
+ peer_import_custom_routes = each.value.peer_import_custom_routes
+ peer_export_subnet_routes_with_public_ip = each.value.peer_export_subnet_routes_with_public_ip
+ peer_import_subnet_routes_with_public_ip = each.value.peer_import_subnet_routes_with_public_ip
+}
+
+module "autoscale" {
+ source = "../../modules/autoscale/"
+
+ for_each = var.autoscale
+
+ name = "${var.name_prefix}${each.value.name}"
+ region = var.region
+ project_id = var.project
+ regional_mig = try(var.autoscale_regional_mig, true)
+ zones = try(each.value.zones, {})
+ image = "https://www.googleapis.com/compute/v1/projects/paloaltonetworksgcp-public/global/images/${try(each.value.image, var.autoscale_common.image)}"
+ named_ports = try(each.value.named_ports, var.autoscale_common.named_ports)
+ machine_type = try(each.value.machine_type, var.autoscale_common.machine_type)
+ min_cpu_platform = try(each.value.min_cpu_platform, var.autoscale_common.min_cpu_platform, "Intel Cascade Lake")
+ disk_type = try(each.value.disk_type, var.autoscale_common.disk_type, "pd-ssd")
+ service_account_email = try(module.iam_service_account[each.value.service_account_key].email, module.iam_service_account[var.autoscale_common.service_account_key].email)
+ scopes = try(each.value.scopes, var.autoscale_common.scopes, [])
+ tags = try(each.value.tags, var.autoscale_common.tags, [])
+ update_policy_type = try(each.value.update_policy_type, var.autoscale_common.update_policy_type, "OPPORTUNISTIC")
+ min_vmseries_replicas = try(each.value.min_vmseries_replicas, var.autoscale_common.min_vmseries_replicas)
+ max_vmseries_replicas = try(each.value.max_vmseries_replicas, var.autoscale_common.max_vmseries_replicas)
+ cooldown_period = try(each.value.cooldown_period, var.autoscale_common.cooldown_period, 480)
+ scale_in_control_time_window_sec = try(each.value.scale_in_control_time_window_sec, var.autoscale_common.scale_in_control_time_window_sec, 1800)
+ scale_in_control_replicas_fixed = try(each.value.scale_in_control_replicas_fixed, var.autoscale_common.scale_in_control_replicas_fixed, 1)
+ create_pubsub_topic = try(each.value.create_pubsub_topic, var.autoscale_common.create_pubsub_topic)
+ autoscaler_metrics = try(each.value.autoscaler_metrics, var.autoscale_common.autoscaler_metrics,
+ {
+ "custom.googleapis.com/VMSeries/panSessionUtilization" = {
+ target = 70
+ }
+ "custom.googleapis.com/VMSeries/panSessionThroughputKbps" = {
+ target = 700000
+ }
+ })
+
+ network_interfaces = [for v in each.value.network_interfaces :
+ {
+ subnetwork = module.vpc[v.vpc_network_key].subnetworks[v.subnetwork_key].self_link
+ create_public_ip = try(v.create_public_ip, false)
+ }]
+ metadata = merge(
+ try(each.value.bootstrap_options, {}),
+ try(var.autoscale_common.bootstrap_options, {})
+ )
+}
+
+data "google_compute_image" "my_image" {
+ family = "ubuntu-pro-2204-lts"
+ project = "ubuntu-os-pro-cloud"
+}
+
+resource "google_compute_instance" "linux_vm" {
+ for_each = var.linux_vms
+
+ name = "${var.name_prefix}${each.key}"
+ machine_type = each.value.linux_machine_type
+ zone = each.value.zone
+
+ boot_disk {
+ initialize_params {
+ image = data.google_compute_image.my_image.id
+ size = each.value.linux_disk_size
+ }
+ }
+
+ network_interface {
+ subnetwork = module.vpc[each.value.vpc_network_key].subnetworks[each.value.subnetwork_key].self_link
+ network_ip = each.value.private_ip
+ }
+
+ metadata = {
+ enable-oslogin = true
+ }
+
+
+ service_account {
+ email = module.iam_service_account[each.value.service_account_key].email
+ scopes = each.value.scopes
+ }
+}
+
+module "lb_internal" {
+ source = "../../modules/lb_internal"
+
+ for_each = var.lbs_internal
+
+ name = "${var.name_prefix}${each.value.name}"
+ region = var.region
+ health_check_port = try(each.value.health_check_port, "80")
+ backends = var.autoscale_regional_mig ? { for v in each.value.backends : v => module.autoscale[v].regional_instance_group_id } : merge([
+ for v in each.value.backends :
+ {
+ for z_k, z_v in var.autoscale[v].zones :
+ "${v}_${z_k}" => module.autoscale[v].zonal_instance_group_ids[z_k]
+ }
+ ]...)
+ subnetwork = module.vpc[each.value.vpc_network_key].subnetworks[each.value.subnetwork_key].self_link
+ network = module.vpc[each.value.vpc_network_key].network.self_link
+ all_ports = true
+}
+
+module "lb_external" {
+ source = "../../modules/lb_external"
+
+ for_each = var.lbs_external
+
+ project = var.project
+
+ name = "${var.name_prefix}${each.value.name}"
+ backend_instance_groups = var.autoscale_regional_mig ? { for v in each.value.backends : v => module.autoscale[v].regional_instance_group_id } : merge([
+ for v in each.value.backends :
+ {
+ for z_k, z_v in var.autoscale[v].zones :
+ "${v}_${z_k}" => module.autoscale[v].zonal_instance_group_ids[z_k]
+ }
+ ]...)
+ rules = each.value.rules
+
+ health_check_http_port = each.value.http_health_check_port
+ health_check_http_request_path = try(each.value.http_health_check_request_path, "/php/login.php")
+}
\ No newline at end of file
diff --git a/examples/autoscale/main_test.go b/examples/vpc_peering_common_with_autoscale/main_test.go
similarity index 95%
rename from examples/autoscale/main_test.go
rename to examples/vpc_peering_common_with_autoscale/main_test.go
index 9e129279..9e6dbfa3 100644
--- a/examples/autoscale/main_test.go
+++ b/examples/vpc_peering_common_with_autoscale/main_test.go
@@ -1,4 +1,4 @@
-package autoscale
+package vpc_peering_common_with_autoscale
import (
"testing"
@@ -22,7 +22,7 @@ func CreateTerraformOptions(t *testing.T) *terraform.Options {
VarFiles: []string{"example.tfvars"},
Vars: map[string]interface{}{
"name_prefix": varsInfo.NamePrefix,
- "project_id": varsInfo.GoogleProjectId,
+ "project": varsInfo.GoogleProjectId,
},
Logger: logger.Default,
Lock: true,
@@ -62,4 +62,4 @@ func TestIdempotence(t *testing.T) {
assertList := []testskeleton.AssertExpression{}
// deploy test infrastructure and verify outputs and check if there are no planned changes after deployment
testskeleton.DeployInfraCheckOutputsVerifyChanges(t, terraformOptions, assertList)
-}
\ No newline at end of file
+}
diff --git a/examples/vpc_peering_common_with_autoscale/outputs.tf b/examples/vpc_peering_common_with_autoscale/outputs.tf
new file mode 100644
index 00000000..eec4859c
--- /dev/null
+++ b/examples/vpc_peering_common_with_autoscale/outputs.tf
@@ -0,0 +1,24 @@
+output "pubsub_topic_id" {
+ description = "The resource ID of the Pub/Sub Topic."
+ value = try({ for k, v in module.autoscale : k => v.pubsub_topic_id }, null)
+}
+
+output "pubsub_subscription_id" {
+ description = "The resource ID of the Pub/Sub Subscription."
+ value = try({ for k, v in module.autoscale : k => v.pubsub_subscription_id }, null)
+}
+
+output "lbs_internal_ips" {
+ description = "Private IP addresses of internal network loadbalancers."
+ value = { for k, v in module.lb_internal : k => v.address }
+}
+
+output "lbs_external_ips" {
+ description = "Public IP addresses of external network loadbalancers."
+ value = { for k, v in module.lb_external : k => v.ip_addresses }
+}
+
+output "linux_vm_ips" {
+ description = "Private IP addresses of Linux VMs."
+ value = { for k, v in resource.google_compute_instance.linux_vm : k => v.network_interface[0].network_ip }
+}
\ No newline at end of file
diff --git a/examples/vpc_peering_common_with_autoscale/variables.tf b/examples/vpc_peering_common_with_autoscale/variables.tf
new file mode 100644
index 00000000..d3089ea8
--- /dev/null
+++ b/examples/vpc_peering_common_with_autoscale/variables.tf
@@ -0,0 +1,349 @@
+# General
+variable "project" {
+ description = "The project name to deploy the infrastructure in to."
+ type = string
+ default = null
+}
+variable "region" {
+ description = "The region into which to deploy the infrastructure in to."
+ type = string
+ default = "us-central1"
+}
+variable "name_prefix" {
+ description = "A string to prefix resource namings."
+ type = string
+ default = "example-"
+}
+
+#Service Account
+
+variable "service_accounts" {
+ description = <<-EOF
+ A map containing each service account setting.
+
+ Example of variable deployment :
+ ```
+ service_accounts = {
+ "sa-vmseries-01" = {
+ service_account_id = "sa-vmseries-01"
+ display_name = "VM-Series SA"
+ roles = [
+ "roles/compute.networkViewer",
+ "roles/logging.logWriter",
+ "roles/monitoring.metricWriter",
+ "roles/monitoring.viewer",
+ "roles/viewer"
+ ]
+ }
+ }
+ ```
+ For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/iam_service_account#Inputs)
+
+ Multiple keys can be added and will be deployed by the code.
+
+ EOF
+ type = map(any)
+ default = {}
+}
+
+#VPC
+
+variable "networks" {
+ description = <<-EOF
+ A map containing each network setting.
+
+ Example of variable deployment :
+
+ ```
+ networks = {
+ fw-mgmt-vpc = {
+ vpc_name = "fw-mgmt-vpc"
+ create_network = true
+ delete_default_routes_on_create = false
+ mtu = "1460"
+ routing_mode = "REGIONAL"
+ subnetworks = {
+ fw-mgmt-sub = {
+ name = "fw-mgmt-sub"
+ create_subnetwork = true
+ ip_cidr_range = "10.10.10.0/28"
+ region = "us-east1"
+ }
+ }
+ firewall_rules = {
+ allow-mgmt-ingress = {
+ name = "allow-mgmt-vpc"
+ source_ranges = ["10.10.10.0/24", "1.1.1.1/32"] # Replace 1.1.1.1/32 with your own souurce IP address for management purposes.
+ priority = "1000"
+ allowed_protocol = "all"
+ allowed_ports = []
+ }
+ }
+ }
+ }
+ ```
+
+ For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/vpc#input_networks)
+
+ Multiple keys can be added and will be deployed by the code.
+ EOF
+ type = any
+ default = {}
+}
+
+variable "vpc_peerings" {
+ description = <<-EOF
+ A map containing each VPC peering setting.
+
+ Example of variable deployment :
+
+ ```
+ vpc_peerings = {
+ "trust-to-spoke1" = {
+ local_network_key = "fw-trust-vpc"
+ peer_network_key = "fw-spoke1-vpc"
+
+ local_export_custom_routes = true
+ local_import_custom_routes = true
+ local_export_subnet_routes_with_public_ip = true
+ local_import_subnet_routes_with_public_ip = true
+
+ peer_export_custom_routes = true
+ peer_import_custom_routes = true
+ peer_export_subnet_routes_with_public_ip = true
+ peer_import_subnet_routes_with_public_ip = true
+ }
+ }
+ ```
+ For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/vpc-peering#inputs)
+
+ Multiple keys can be added and will be deployed by the code.
+ EOF
+ type = map(any)
+ default = {}
+}
+
+variable "routes" {
+ description = <<-EOF
+ A map containing each route setting. Note that you can only add routes using a next-hop type of internal load-balance rule.
+
+ Example of variable deployment :
+
+ ```
+ routes = {
+ "default-route-trust" = {
+ name = "fw-default-trust"
+ destination_range = "0.0.0.0/0"
+ vpc_network_key = "fw-trust-vpc"
+ lb_internal_name = "internal-lb"
+ }
+ }
+ ```
+
+ Multiple keys can be added and will be deployed by the code.
+ EOF
+ type = map(any)
+ default = {}
+}
+
+#Autoscale
+variable "autoscale_regional_mig" {
+ description = <<-EOF
+ Sets the managed instance group type to either a regional (if `true`) or a zonal (if `false`).
+ For more information please see [About regional MIGs](https://cloud.google.com/compute/docs/instance-groups/regional-migs#why_choose_regional_managed_instance_groups).
+ EOF
+ type = bool
+ default = true
+}
+variable "autoscale_common" {
+ description = <<-EOF
+ A map containing common vmseries autoscale setting.
+ Bootstrap options can be moved between vmseries autoscale individual instances variable (`autoscale`) and this common vmseries autoscale variable (`autoscale_common`).
+
+ Example of variable deployment :
+
+ ```
+ autoscale_common = {
+ image = "vmseries-flex-byol-1110"
+ machine_type = "n2-standard-4"
+ min_cpu_platform = "Intel Cascade Lake"
+ disk_type = "pd-ssd"
+ scopes = [
+ "https://www.googleapis.com/auth/compute.readonly",
+ "https://www.googleapis.com/auth/cloud.useraccounts.readonly",
+ "https://www.googleapis.com/auth/devstorage.read_only",
+ "https://www.googleapis.com/auth/logging.write",
+ "https://www.googleapis.com/auth/monitoring.write",
+ ]
+ tags = ["vmseries-autoscale"]
+ update_policy_type = "OPPORTUNISTIC"
+ cooldown_period = 480
+ bootstrap_options = [
+ panorama_server = "1.1.1.1"
+ ]
+ }
+ ```
+ EOF
+ type = any
+ default = {}
+}
+
+variable "autoscale" {
+ description = <<-EOF
+ A map containing each vmseries autoscale setting.
+ Zonal or regional managed instance group type is controolled from the `autoscale_regional_mig` variable for all autoscale instances.
+
+ Example of variable deployment :
+
+ ```
+ autoscale = {
+ fw-autoscale-common = {
+ name = "fw-autoscale-common"
+ zones = {
+ zone1 = "us-east4-b"
+ zone2 = "us-east4-c"
+ }
+ named_ports = [
+ {
+ name = "http"
+ port = 80
+ },
+ {
+ name = "https"
+ port = 443
+ }
+ ]
+ service_account_key = "sa-vmseries-01"
+ min_vmseries_replicas = 2
+ max_vmseries_replicas = 4
+ create_pubsub_topic = true
+ autoscaler_metrics = {
+ "custom.googleapis.com/VMSeries/panSessionUtilization" = {
+ target = 70
+ }
+ "custom.googleapis.com/VMSeries/panSessionThroughputKbps" = {
+ target = 700000
+ }
+ }
+ bootstrap_options = {
+ type = "dhcp-client"
+ dhcp-send-hostname = "yes"
+ dhcp-send-client-id = "yes"
+ dhcp-accept-server-hostname = "yes"
+ dhcp-accept-server-domain = "yes"
+ mgmt-interface-swap = "enable"
+ panorama-server = "1.1.1.1"
+ ssh-keys = "admin:" # Replace this value with client data
+ }
+ network_interfaces = [
+ {
+ vpc_network_key = "fw-untrust-vpc"
+ subnetwork_key = "fw-untrust-sub"
+ create_public_ip = true
+ },
+ {
+ vpc_network_key = "fw-mgmt-vpc"
+ subnetwork_key = "fw-mgmt-sub"
+ create_public_ip = true
+ },
+ {
+ vpc_network_key = "fw-trust-vpc"
+ subnetwork_key = "fw-trust-sub"
+ }
+ ]
+ }
+ }
+ ```
+ EOF
+ type = any
+ default = {}
+}
+
+#Load Balancers
+
+variable "lbs_internal" {
+ description = <<-EOF
+ A map containing each internal loadbalancer setting.
+ Note : private IP reservation is not by default within the example as it may overlap with autoscale IP allocation.
+
+ Example of variable deployment :
+
+ ```
+ lbs_internal = {
+ "internal-lb" = {
+ name = "internal-lb"
+ health_check_port = "80"
+ backends = ["fw-vmseries-01", "fw-vmseries-02"]
+ subnetwork_key = "fw-trust-sub"
+ vpc_network_key = "fw-trust-vpc"
+ }
+ }
+ ```
+ For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/lb_internal#inputs)
+
+ Multiple keys can be added and will be deployed by the code.
+ EOF
+ type = map(any)
+ default = {}
+}
+variable "lbs_external" {
+ description = <<-EOF
+ A map containing each external loadbalancer setting.
+
+ Example of variable deployment :
+
+ ```
+ lbs_external = {
+ "external-lb" = {
+ name = "external-lb"
+ backends = ["fw-vmseries-01", "fw-vmseries-02"]
+ rules = {
+ "all-ports" = {
+ ip_protocol = "L3_DEFAULT"
+ }
+ }
+ http_health_check_port = "80"
+ http_health_check_request_path = "/php/login.php"
+ }
+ }
+ ```
+ For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/lb_external#inputs)
+
+ Multiple keys can be added and will be deployed by the code.
+ EOF
+ type = map(any)
+ default = {}
+}
+
+#Spoke VPCs Linux VMs
+
+variable "linux_vms" {
+ description = <<-EOF
+ A map containing each Linux VM configuration that will be placed in SPOKE VPCs for testing purposes.
+
+ Example of varaible deployment:
+
+ ```
+ linux_vms = {
+ spoke1-vm = {
+ linux_machine_type = "n2-standard-4"
+ zone = "us-east1-b"
+ linux_disk_size = "50" # Modify this value as per deployment requirements
+ vpc_network_key = "fw-spoke1-vpc"
+ subnetwork_key = "fw-spoke1-sub"
+ private_ip = "192.168.1.2"
+ scopes = [
+ "https://www.googleapis.com/auth/compute.readonly",
+ "https://www.googleapis.com/auth/cloud.useraccounts.readonly",
+ "https://www.googleapis.com/auth/devstorage.read_only",
+ "https://www.googleapis.com/auth/logging.write",
+ "https://www.googleapis.com/auth/monitoring.write",
+ ]
+ service_account_key = "sa-linux-01"
+ }
+ }
+ ```
+ EOF
+ type = map(any)
+ default = {}
+}
diff --git a/examples/autoscale/versions.tf b/examples/vpc_peering_common_with_autoscale/versions.tf
similarity index 55%
rename from examples/autoscale/versions.tf
rename to examples/vpc_peering_common_with_autoscale/versions.tf
index b9f6089a..785e9269 100644
--- a/examples/autoscale/versions.tf
+++ b/examples/vpc_peering_common_with_autoscale/versions.tf
@@ -1,16 +1,13 @@
terraform {
required_version = ">= 1.3, < 2.0"
- required_providers {
- google = { version = "~> 4.58" }
- }
}
provider "google" {
- project = var.project_id
+ project = var.project
region = var.region
}
provider "google-beta" {
- project = var.project_id
+ project = var.project
region = var.region
}
diff --git a/examples/vpc_peering_dedicated_with_autoscale/README.md b/examples/vpc_peering_dedicated_with_autoscale/README.md
new file mode 100644
index 00000000..f2e0662f
--- /dev/null
+++ b/examples/vpc_peering_dedicated_with_autoscale/README.md
@@ -0,0 +1,219 @@
+---
+show_in_hub: false
+---
+# Reference Architecture with Terraform: VM-Series in GCP, Centralized Architecture, Dedicated inbound NGFW with autoscale Option
+
+Palo Alto Networks produces several [validated reference architecture design and deployment documentation guides](https://www.paloaltonetworks.com/resources/reference-architectures), which describe well-architected and tested deployments. When deploying VM-Series in a public cloud, the reference architectures guide users toward the best security outcomes, whilst reducing rollout time and avoiding common integration efforts.
+The Terraform code presented here will deploy Palo Alto Networks VM-Series firewalls in GCP based on a centralized design with dedicated inbound VM-Series and autoscaling capabilities for all traffic; for a discussion of other options, please see the design guide from [the reference architecture guides](https://www.paloaltonetworks.com/resources/reference-architectures).
+
+## Detailed Architecture and Design
+
+### Centralized Design
+
+This design uses a VPC Peering. Application functions are distributed across multiple projects that are connected in a logical hub-and-spoke topology. A security project acts as the hub, providing centralized connectivity and control for multiple application projects. You deploy all VM-Series firewalls within the security project. The spoke projects contain the workloads and necessary services to support the application deployment.
+This design model integrates multiple methods to interconnect and control your application project VPC networks with resources in the security project. VPC Peering enables the private VPC network in the security project to peer with, and share routing information to, each application project VPC network. Using Shared VPC, the security project administrators create and share VPC network resources from within the security project to the application projects. The application project administrators can select the network resources and deploy the application workloads.
+
+### Dedicated inbound Option with autoscaling
+
+The dedicated inbound firewall option with autoscaling leverages a single set autoscale group of VM-Series firewalls. Compared to the standard dedicated inbound firewall option - the autoscaling solved the issue of resource bottleneck given by a single set of firewalls, being able to scale horizontally based on configurable metrics.
+
+![VM-Series-Dedicated-Firewall-Option-With-Autoscaling](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/assets/43091730/41e95242-eaf1-4850-b563-df17d138bef9)
+
+
+The scope of this code is to deploy an example of the [VM-Series Dedicated Inbound Firewall Option](https://www.paloaltonetworks.com/apps/pan/public/downloadResource?pagePath=/content/pan/en_US/resources/guides/gcp-architecture-guide#Design%20Model) architecture within a GCP project, but using an autoscaling group of instances instead of a single pair of firewall.
+
+The example makes use of VM-Series basic [bootstrap process](https://docs.paloaltonetworks.com/vm-series/10-2/vm-series-deployment/bootstrap-the-vm-series-firewall/bootstrap-the-vm-series-firewall-on-google) using metadata information to pass bootstrap parameters to the autoscale instances.
+
+With default variable values the topology consists of :
+ - 5 VPC networks :
+ - Management VPC
+ - Untrust (outside) VPC
+ - Trust (inside/security) VPC
+ - Spoke-1 VPC
+ - Spoke-2 VPC
+ - 2 Autoscaling Group
+ - 2 Linux Ubuntu VMs (inside Spoke VPCs - for testing purposes)
+ - one internal network loadbalancer (for outbound/east-west traffic)
+ - one external regional network loadbalancer (for inbound traffic)
+
+## Prerequisites
+
+The following steps should be followed before deploying the Terraform code presented here.
+
+1. Prepare [VM-Series licenses](https://support.paloaltonetworks.com/)
+2. Configure the terraform [google provider](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference#authentication-configuration)
+
+## Usage
+
+1. Access Google Cloud Shell or any other environment that has access to your GCP project
+
+2. Clone the repository:
+
+```
+git clone https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules
+cd terraform-google-vmseries-modules/examples/vpc_peering_dedicated_with_autoscale
+```
+
+3. Copy the `example.tfvars` to `terraform.tfvars`.
+
+`project`, `ssh_keys` and management network `source_ranges` firewall rule should be modified for successful deployment and access to the instance.
+
+There are also a few variables that have some default values but which should also be changed as per deployment requirements
+
+ - `region`
+ - `autoscale_common.bootstrap_options`
+ - `autoscale..bootstrap_options`
+ - `linux_vms..linux_disk_size`
+
+1. Apply the terraform code:
+
+```
+terraform init
+terraform apply
+```
+
+4. Check the output plan and confirm the apply.
+
+5. Check the successful application and outputs of the resulting infrastructure:
+
+```
+Apply complete! Resources: 55 added, 0 changed, 0 destroyed.
+
+Outputs:
+
+lbs_external_ips = {
+ "external-lb" = {
+ "all-portsss" = ""
+ }
+}
+lbs_internal_ips = {
+ "internal-lb" = "10.10.12.4"
+}
+linux_vm_ips = {
+ "spoke1-vm" = "192.168.1.2"
+ "spoke2-vm" = "192.168.2.2"
+}
+pubsub_subscription_id = {
+ "fw-autoscale-inbound" = "projects/gcp-gcs-pso/subscriptions/hgu-asi-ref-fw-autoscale-inbound-mig"
+ "fw-autoscale-obew" = "projects/gcp-gcs-pso/subscriptions/hgu-asi-ref-fw-autoscale-obew-mig"
+}
+pubsub_topic_id = {
+ "fw-autoscale-inbound" = "projects/gcp-gcs-pso/topics/hgu-asi-ref-fw-autoscale-inbound-mig"
+ "fw-autoscale-obew" = "projects/gcp-gcs-pso/topics/hgu-asi-ref-fw-autoscale-obew-mig"
+}
+
+
+```
+
+
+## Post build
+
+Usually autoscale groups are managed by Panorama - but they can also be accessed directly via the public/private IP address like any other VM within GCP.
+
+Connect to the VM-Series instance(s) via SSH using your associated private key and set a password :
+
+```
+ssh admin@x.x.x.x -i /PATH/TO/YOUR/KEY/id_rsa
+Welcome admin.
+
+admin@PA-VM> configure
+Entering configuration mode
+[edit]
+admin@PA-VM# set mgt-config users admin password
+Enter password :
+Confirm password :
+
+[edit]
+admin@PA-VM# commit
+Configuration committed successfully
+```
+
+## Check access via web UI
+
+Use a web browser to access `https://` (these can be obtained via the GCP console/API) and login with admin and your previously configured password.
+
+## Change the public Loopback public IP Address
+
+For the VM-Series that are backend instance group members of the public-facing loadbalancer - go to Network -> Interfaces -> Loopback and change the value of `1.1.1.1` with the value from the `EXTERNAL_LB_PUBLIC_IP` from the terraform outputs.
+
+## Check traffic from spoke VMs
+
+After you do some basic configuration on the autoscaling group vmseries - you can try to check connectivity via the spoke VMs (the following tests presume that the autoscale group has been configured to process east - west traffic).
+
+SSH to one of the spoke VMs using GCP IAP and gcloud command and test connectivity :
+
+
+```
+$ gcloud compute ssh spoke1-vm
+No zone specified. Using zone [us-east1-b] for instance: [spoke1-vm].
+External IP address was not found; defaulting to using IAP tunneling.
+WARNING:
+
+To increase the performance of the tunnel, consider installing NumPy. For instructions,
+please see https://cloud.google.com/iap/docs/using-tcp-forwarding#increasing_the_tcp_upload_bandwidth
+
+@spoke1-vm:~$ping 8.8.8.8
+@spoke1-vm:~$ping 192.168.2.2
+```
+
+## Reference
+
+### Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.3, < 2.0 |
+
+### Providers
+
+| Name | Version |
+|------|---------|
+| [google](#provider\_google) | n/a |
+
+### Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [autoscale](#module\_autoscale) | ../../modules/autoscale/ | n/a |
+| [iam\_service\_account](#module\_iam\_service\_account) | ../../modules/iam_service_account | n/a |
+| [lb\_external](#module\_lb\_external) | ../../modules/lb_external | n/a |
+| [lb\_internal](#module\_lb\_internal) | ../../modules/lb_internal | n/a |
+| [vpc](#module\_vpc) | ../../modules/vpc | n/a |
+| [vpc\_peering](#module\_vpc\_peering) | ../../modules/vpc-peering | n/a |
+
+### Resources
+
+| Name | Type |
+|------|------|
+| [google_compute_instance.linux_vm](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance) | resource |
+| [google_compute_route.this](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_route) | resource |
+| [google_compute_image.my_image](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/compute_image) | data source |
+
+### Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [autoscale](#input\_autoscale) | A map containing each vmseries autoscale setting.
Zonal or regional managed instance group type is controolled from the `autoscale_regional_mig` variable for all autoscale instances.
Example of variable deployment :autoscale = {
fw-autoscale-common = {
name = "fw-autoscale-common"
zones = {
zone1 = "us-east4-b"
zone2 = "us-east4-c"
}
named_ports = [
{
name = "http"
port = 80
},
{
name = "https"
port = 443
}
]
service_account_key = "sa-vmseries-01"
min_vmseries_replicas = 2
max_vmseries_replicas = 4
create_pubsub_topic = true
autoscaler_metrics = {
"custom.googleapis.com/VMSeries/panSessionUtilization" = {
target = 70
}
"custom.googleapis.com/VMSeries/panSessionThroughputKbps" = {
target = 700000
}
}
bootstrap_options = {
type = "dhcp-client"
dhcp-send-hostname = "yes"
dhcp-send-client-id = "yes"
dhcp-accept-server-hostname = "yes"
dhcp-accept-server-domain = "yes"
mgmt-interface-swap = "enable"
panorama-server = "1.1.1.1"
ssh-keys = "admin:" # Replace this value with client data
}
network_interfaces = [
{
vpc_network_key = "fw-untrust-vpc"
subnetwork_key = "fw-untrust-sub"
create_public_ip = true
},
{
vpc_network_key = "fw-mgmt-vpc"
subnetwork_key = "fw-mgmt-sub"
create_public_ip = true
},
{
vpc_network_key = "fw-trust-vpc"
subnetwork_key = "fw-trust-sub"
}
]
}
}
| `any` | `{}` | no |
+| [autoscale\_common](#input\_autoscale\_common) | A map containing common vmseries autoscale setting.
Bootstrap options can be moved between vmseries autoscale individual instances variable (`autoscale`) and this common vmseries autoscale variable (`autoscale_common`).
Example of variable deployment :autoscale_common = {
image = "vmseries-flex-byol-1110"
machine_type = "n2-standard-4"
min_cpu_platform = "Intel Cascade Lake"
disk_type = "pd-ssd"
scopes = [
"https://www.googleapis.com/auth/compute.readonly",
"https://www.googleapis.com/auth/cloud.useraccounts.readonly",
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring.write",
]
tags = ["vmseries-autoscale"]
update_policy_type = "OPPORTUNISTIC"
cooldown_period = 480
bootstrap_options = [
panorama_server = "1.1.1.1"
]
}
| `any` | `{}` | no |
+| [autoscale\_regional\_mig](#input\_autoscale\_regional\_mig) | Sets the managed instance group type to either a regional (if `true`) or a zonal (if `false`).
For more information please see [About regional MIGs](https://cloud.google.com/compute/docs/instance-groups/regional-migs#why_choose_regional_managed_instance_groups). | `bool` | `true` | no |
+| [lbs\_external](#input\_lbs\_external) | A map containing each external loadbalancer setting.
Example of variable deployment :lbs_external = {
"external-lb" = {
name = "external-lb"
backends = ["fw-vmseries-01", "fw-vmseries-02"]
rules = {
"all-ports" = {
ip_protocol = "L3_DEFAULT"
}
}
http_health_check_port = "80"
http_health_check_request_path = "/php/login.php"
}
}
For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/lb_external#inputs)
Multiple keys can be added and will be deployed by the code. | `map(any)` | `{}` | no |
+| [lbs\_internal](#input\_lbs\_internal) | A map containing each internal loadbalancer setting.
Note : private IP reservation is not by default within the example as it may overlap with autoscale IP allocation.
Example of variable deployment :lbs_internal = {
"internal-lb" = {
name = "internal-lb"
health_check_port = "80"
backends = ["fw-vmseries-01", "fw-vmseries-02"]
subnetwork_key = "fw-trust-sub"
vpc_network_key = "fw-trust-vpc"
}
}
For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/lb_internal#inputs)
Multiple keys can be added and will be deployed by the code. | `map(any)` | `{}` | no |
+| [linux\_vms](#input\_linux\_vms) | A map containing each Linux VM configuration that will be placed in SPOKE VPCs for testing purposes.
Example of varaible deployment:linux_vms = {
spoke1-vm = {
linux_machine_type = "n2-standard-4"
zone = "us-east1-b"
linux_disk_size = "50" # Modify this value as per deployment requirements
vpc_network_key = "fw-spoke1-vpc"
subnetwork_key = "fw-spoke1-sub"
private_ip = "192.168.1.2"
scopes = [
"https://www.googleapis.com/auth/compute.readonly",
"https://www.googleapis.com/auth/cloud.useraccounts.readonly",
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring.write",
]
service_account_key = "sa-linux-01"
}
}
| `map(any)` | `{}` | no |
+| [name\_prefix](#input\_name\_prefix) | A string to prefix resource namings. | `string` | `"example-"` | no |
+| [networks](#input\_networks) | A map containing each network setting.
Example of variable deployment :networks = {
fw-mgmt-vpc = {
vpc_name = "fw-mgmt-vpc"
create_network = true
delete_default_routes_on_create = false
mtu = "1460"
routing_mode = "REGIONAL"
subnetworks = {
fw-mgmt-sub = {
name = "fw-mgmt-sub"
create_subnetwork = true
ip_cidr_range = "10.10.10.0/28"
region = "us-east1"
}
}
firewall_rules = {
allow-mgmt-ingress = {
name = "allow-mgmt-vpc"
source_ranges = ["10.10.10.0/24", "1.1.1.1/32"] # Replace 1.1.1.1/32 with your own souurce IP address for management purposes.
priority = "1000"
allowed_protocol = "all"
allowed_ports = []
}
}
}
}
For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/vpc#input_networks)
Multiple keys can be added and will be deployed by the code. | `any` | `{}` | no |
+| [project](#input\_project) | The project name to deploy the infrastructure in to. | `string` | `null` | no |
+| [region](#input\_region) | The region into which to deploy the infrastructure in to. | `string` | `"us-central1"` | no |
+| [routes](#input\_routes) | A map containing each route setting. Note that you can only add routes using a next-hop type of internal load-balance rule.
Example of variable deployment :routes = {
"default-route-trust" = {
name = "fw-default-trust"
destination_range = "0.0.0.0/0"
vpc_network_key = "fw-trust-vpc"
lb_internal_name = "internal-lb"
}
}
Multiple keys can be added and will be deployed by the code. | `map(any)` | `{}` | no |
+| [service\_accounts](#input\_service\_accounts) | A map containing each service account setting.
Example of variable deployment :service_accounts = {
"sa-vmseries-01" = {
service_account_id = "sa-vmseries-01"
display_name = "VM-Series SA"
roles = [
"roles/compute.networkViewer",
"roles/logging.logWriter",
"roles/monitoring.metricWriter",
"roles/monitoring.viewer",
"roles/viewer"
]
}
}
For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/iam_service_account#Inputs)
Multiple keys can be added and will be deployed by the code. | `map(any)` | `{}` | no |
+| [vpc\_peerings](#input\_vpc\_peerings) | A map containing each VPC peering setting.
Example of variable deployment :vpc_peerings = {
"trust-to-spoke1" = {
local_network_key = "fw-trust-vpc"
peer_network_key = "fw-spoke1-vpc"
local_export_custom_routes = true
local_import_custom_routes = true
local_export_subnet_routes_with_public_ip = true
local_import_subnet_routes_with_public_ip = true
peer_export_custom_routes = true
peer_import_custom_routes = true
peer_export_subnet_routes_with_public_ip = true
peer_import_subnet_routes_with_public_ip = true
}
}
For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/vpc-peering#inputs)
Multiple keys can be added and will be deployed by the code. | `map(any)` | `{}` | no |
+
+### Outputs
+
+| Name | Description |
+|------|-------------|
+| [lbs\_external\_ips](#output\_lbs\_external\_ips) | Public IP addresses of external network loadbalancers. |
+| [lbs\_internal\_ips](#output\_lbs\_internal\_ips) | Private IP addresses of internal network loadbalancers. |
+| [linux\_vm\_ips](#output\_linux\_vm\_ips) | Private IP addresses of Linux VMs. |
+| [pubsub\_subscription\_id](#output\_pubsub\_subscription\_id) | The resource ID of the Pub/Sub Subscription. |
+| [pubsub\_topic\_id](#output\_pubsub\_topic\_id) | The resource ID of the Pub/Sub Topic. |
+
diff --git a/examples/vpc_peering_dedicated_with_autoscale/example.tfvars b/examples/vpc_peering_dedicated_with_autoscale/example.tfvars
new file mode 100644
index 00000000..17708c02
--- /dev/null
+++ b/examples/vpc_peering_dedicated_with_autoscale/example.tfvars
@@ -0,0 +1,395 @@
+# General
+project = ""
+region = "us-east4"
+name_prefix = ""
+
+# Service accounts
+
+service_accounts = {
+ sa-vmseries-01 = {
+ service_account_id = "sa-vmseries-01"
+ display_name = "VM-Series SA"
+ roles = [
+ "roles/compute.networkViewer",
+ "roles/logging.logWriter",
+ "roles/monitoring.metricWriter",
+ "roles/monitoring.viewer",
+ "roles/viewer"
+ ]
+ },
+ sa-linux-01 = {
+ service_account_id = "sa-linux-01"
+ display_name = "Linux VMs SA"
+ roles = [
+ "roles/compute.networkViewer",
+ "roles/logging.logWriter",
+ "roles/monitoring.metricWriter",
+ "roles/monitoring.viewer",
+ "roles/viewer"
+ ]
+ }
+}
+
+# VPC
+
+networks = {
+ fw-mgmt-vpc = {
+ vpc_name = "fw-mgmt-vpc"
+ create_network = true
+ delete_default_routes_on_create = false
+ mtu = "1460"
+ routing_mode = "REGIONAL"
+ subnetworks = {
+ fw-mgmt-sub = {
+ name = "fw-mgmt-sub"
+ create_subnetwork = true
+ ip_cidr_range = "10.10.10.0/28"
+ region = "us-east4"
+ }
+ }
+ firewall_rules = {
+ allow-mgmt-ingress = {
+ name = "allow-mgmt-vpc"
+ source_ranges = ["1.1.1.1/32"] # Replace 1.1.1.1/32 with your own souurce IP address for management purposes.
+ priority = "1000"
+ allowed_protocol = "all"
+ allowed_ports = []
+ }
+ }
+ },
+ fw-untrust-vpc = {
+ vpc_name = "fw-untrust-vpc"
+ create_network = true
+ delete_default_routes_on_create = false
+ mtu = "1460"
+ routing_mode = "REGIONAL"
+ subnetworks = {
+ fw-untrust-sub = {
+ name = "fw-untrust-sub"
+ create_subnetwork = true
+ ip_cidr_range = "10.10.11.0/28"
+ region = "us-east4"
+ }
+ }
+ firewall_rules = {
+ allow-untrust-ingress = {
+ name = "allow-untrust-vpc"
+ source_ranges = ["35.191.0.0/16", "209.85.152.0/22", "209.85.204.0/22", "1.1.1.1/32"] # Replace 1.1.1.1/32 with your own souurce IP address for management purposes.
+ priority = "1000"
+ allowed_protocol = "all"
+ allowed_ports = []
+ }
+ }
+ },
+ fw-trust-vpc = {
+ vpc_name = "fw-trust-vpc"
+ create_network = true
+ delete_default_routes_on_create = true
+ mtu = "1460"
+ routing_mode = "REGIONAL"
+ subnetworks = {
+ fw-trust-sub = {
+ name = "fw-trust-sub"
+ create_subnetwork = true
+ ip_cidr_range = "10.10.12.0/28"
+ region = "us-east4"
+ }
+ }
+ firewall_rules = {
+ allow-trust-ingress = {
+ name = "allow-trust-vpc"
+ source_ranges = ["192.168.0.0/16", "35.191.0.0/16", "130.211.0.0/22"]
+ priority = "1000"
+ allowed_protocol = "all"
+ allowed_ports = []
+ }
+ }
+ },
+ fw-spoke1-vpc = {
+ vpc_name = "fw-spoke1-vpc"
+ create_network = true
+ delete_default_routes_on_create = true
+ mtu = "1460"
+ routing_mode = "REGIONAL"
+ subnetworks = {
+ fw-spoke1-sub = {
+ name = "fw-spoke1-sub"
+ create_subnetwork = true
+ ip_cidr_range = "192.168.1.0/28"
+ region = "us-east4"
+ }
+ }
+ firewall_rules = {
+ allow-spoke1-ingress = {
+ name = "allow-spoke1-vpc"
+ source_ranges = ["192.168.0.0/16", "35.235.240.0/20", "10.10.12.0/28"]
+ priority = "1000"
+ allowed_protocol = "all"
+ allowed_ports = []
+ }
+ }
+ },
+ fw-spoke2-vpc = {
+ vpc_name = "fw-spoke2-vpc"
+ create_network = true
+ delete_default_routes_on_create = true
+ mtu = "1460"
+ routing_mode = "REGIONAL"
+ subnetworks = {
+ fw-spoke2-sub = {
+ name = "fw-spoke2-sub"
+ create_subnetwork = true
+ ip_cidr_range = "192.168.2.0/28"
+ region = "us-east4"
+ }
+ }
+ firewall_rules = {
+ allow-spoke2-ingress = {
+ name = "allow-spoke2-vpc"
+ source_ranges = ["192.168.0.0/16", "35.235.240.0/20", "10.10.12.0/28"]
+ priority = "1000"
+ allowed_protocol = "all"
+ allowed_ports = []
+ }
+ }
+ }
+}
+
+# VPC Peerings
+
+vpc_peerings = {
+ trust-to-spoke1 = {
+ local_network_key = "fw-trust-vpc"
+ peer_network_key = "fw-spoke1-vpc"
+
+ local_export_custom_routes = true
+ local_import_custom_routes = true
+ local_export_subnet_routes_with_public_ip = true
+ local_import_subnet_routes_with_public_ip = true
+
+ peer_export_custom_routes = true
+ peer_import_custom_routes = true
+ peer_export_subnet_routes_with_public_ip = true
+ peer_import_subnet_routes_with_public_ip = true
+ },
+ trust-to-spoke2 = {
+ local_network_key = "fw-trust-vpc"
+ peer_network_key = "fw-spoke2-vpc"
+
+ local_export_custom_routes = true
+ local_import_custom_routes = true
+ local_export_subnet_routes_with_public_ip = true
+ local_import_subnet_routes_with_public_ip = true
+
+ peer_export_custom_routes = true
+ peer_import_custom_routes = true
+ peer_export_subnet_routes_with_public_ip = true
+ peer_import_subnet_routes_with_public_ip = true
+ }
+}
+
+# Static routes
+routes = {
+ fw-default-trust = {
+ name = "fw-default-trust"
+ destination_range = "0.0.0.0/0"
+ vpc_network_key = "fw-trust-vpc"
+ lb_internal_key = "internal-lb"
+ }
+}
+
+# Autoscale
+autoscale_regional_mig = true
+
+autoscale_common = {
+ image = "vmseries-flex-byol-1110"
+ machine_type = "n2-standard-4"
+ min_cpu_platform = "Intel Cascade Lake"
+ disk_type = "pd-ssd"
+ scopes = [
+ "https://www.googleapis.com/auth/compute.readonly",
+ "https://www.googleapis.com/auth/cloud.useraccounts.readonly",
+ "https://www.googleapis.com/auth/devstorage.read_only",
+ "https://www.googleapis.com/auth/logging.write",
+ "https://www.googleapis.com/auth/monitoring.write",
+ ]
+ tags = ["vmseries-autoscale"]
+ update_policy_type = "OPPORTUNISTIC"
+ cooldown_period = 480
+}
+
+autoscale = {
+ fw-autoscale-obew = {
+ name = "fw-autoscale-obew"
+ zones = {
+ zone1 = "us-east4-b"
+ zone2 = "us-east4-c"
+ }
+ named_ports = [
+ {
+ name = "http"
+ port = 80
+ },
+ {
+ name = "https"
+ port = 443
+ }
+ ]
+ service_account_key = "sa-vmseries-01"
+ min_vmseries_replicas = 2
+ max_vmseries_replicas = 4
+ create_pubsub_topic = true
+ autoscaler_metrics = {
+ "custom.googleapis.com/VMSeries/panSessionUtilization" = {
+ target = 70
+ }
+ "custom.googleapis.com/VMSeries/panSessionThroughputKbps" = {
+ target = 700000
+ }
+ }
+ bootstrap_options = {
+ type = "dhcp-client"
+ dhcp-send-hostname = "yes"
+ dhcp-send-client-id = "yes"
+ dhcp-accept-server-hostname = "yes"
+ dhcp-accept-server-domain = "yes"
+ mgmt-interface-swap = "enable"
+ panorama-server = "1.1.1.1"
+ ssh-keys = "admin:" # Replace this value with client data
+ }
+ network_interfaces = [
+ {
+ vpc_network_key = "fw-untrust-vpc"
+ subnetwork_key = "fw-untrust-sub"
+ create_public_ip = true
+ },
+ {
+ vpc_network_key = "fw-mgmt-vpc"
+ subnetwork_key = "fw-mgmt-sub"
+ create_public_ip = true
+ },
+ {
+ vpc_network_key = "fw-trust-vpc"
+ subnetwork_key = "fw-trust-sub"
+ }
+ ]
+ },
+ fw-autoscale-inbound = {
+ name = "fw-autoscale-inbound"
+ zones = {
+ zone1 = "us-east4-b"
+ zone2 = "us-east4-c"
+ }
+ named_ports = [
+ {
+ name = "http"
+ port = 80
+ },
+ {
+ name = "https"
+ port = 443
+ }
+ ]
+ service_account_key = "sa-vmseries-01"
+ min_vmseries_replicas = 2
+ max_vmseries_replicas = 4
+ create_pubsub_topic = true
+ autoscaler_metrics = {
+ "custom.googleapis.com/VMSeries/panSessionUtilization" = {
+ target = 70
+ }
+ "custom.googleapis.com/VMSeries/panSessionThroughputKbps" = {
+ target = 700000
+ }
+ }
+ bootstrap_options = {
+ type = "dhcp-client"
+ dhcp-send-hostname = "yes"
+ dhcp-send-client-id = "yes"
+ dhcp-accept-server-hostname = "yes"
+ dhcp-accept-server-domain = "yes"
+ mgmt-interface-swap = "enable"
+ panorama-server = "1.1.1.1"
+ ssh-keys = "admin:" # Replace this value with client data
+ }
+ network_interfaces = [
+ {
+ vpc_network_key = "fw-untrust-vpc"
+ subnetwork_key = "fw-untrust-sub"
+ create_public_ip = true
+ },
+ {
+ vpc_network_key = "fw-mgmt-vpc"
+ subnetwork_key = "fw-mgmt-sub"
+ create_public_ip = true
+ },
+ {
+ vpc_network_key = "fw-trust-vpc"
+ subnetwork_key = "fw-trust-sub"
+ }
+ ]
+ }
+}
+
+# Spoke Linux VMs
+linux_vms = {
+ spoke1-vm = {
+ linux_machine_type = "n2-standard-4"
+ zone = "us-east4-b"
+ linux_disk_size = "50"
+ vpc_network_key = "fw-spoke1-vpc"
+ subnetwork_key = "fw-spoke1-sub"
+ private_ip = "192.168.1.2"
+ scopes = [
+ "https://www.googleapis.com/auth/compute.readonly",
+ "https://www.googleapis.com/auth/cloud.useraccounts.readonly",
+ "https://www.googleapis.com/auth/devstorage.read_only",
+ "https://www.googleapis.com/auth/logging.write",
+ "https://www.googleapis.com/auth/monitoring.write",
+ ]
+ service_account_key = "sa-linux-01"
+ },
+ spoke2-vm = {
+ linux_machine_type = "n2-standard-4"
+ zone = "us-east4-b"
+ linux_disk_size = "50"
+ vpc_network_key = "fw-spoke2-vpc"
+ subnetwork_key = "fw-spoke2-sub"
+ private_ip = "192.168.2.2"
+ scopes = [
+ "https://www.googleapis.com/auth/compute.readonly",
+ "https://www.googleapis.com/auth/cloud.useraccounts.readonly",
+ "https://www.googleapis.com/auth/devstorage.read_only",
+ "https://www.googleapis.com/auth/logging.write",
+ "https://www.googleapis.com/auth/monitoring.write",
+ ]
+ service_account_key = "sa-linux-01"
+ }
+}
+
+# Internal Network Loadbalancer
+lbs_internal = {
+ internal-lb = {
+ name = "internal-lb"
+ health_check_port = "80"
+ backends = ["fw-autoscale-obew"]
+ subnetwork = "fw-trust-sub"
+ vpc_network_key = "fw-trust-vpc"
+ subnetwork_key = "fw-trust-sub"
+ }
+}
+
+# External Network Loadbalancer
+lbs_external = {
+ external-lb = {
+ name = "external-lb"
+ backends = ["fw-autoscale-inbound"]
+ rules = {
+ all-ports = {
+ ip_protocol = "L3_DEFAULT"
+ }
+ }
+ http_health_check_port = "80"
+ http_health_check_request_path = "/php/login.php"
+ }
+}
\ No newline at end of file
diff --git a/examples/vpc_peering_dedicated_with_autoscale/main.tf b/examples/vpc_peering_dedicated_with_autoscale/main.tf
new file mode 100644
index 00000000..1309eec1
--- /dev/null
+++ b/examples/vpc_peering_dedicated_with_autoscale/main.tf
@@ -0,0 +1,183 @@
+module "iam_service_account" {
+ source = "../../modules/iam_service_account"
+
+ for_each = var.service_accounts
+
+ service_account_id = "${var.name_prefix}${each.value.service_account_id}"
+ display_name = "${var.name_prefix}${each.value.display_name}"
+ roles = each.value.roles
+ project_id = var.project
+}
+
+module "vpc" {
+ source = "../../modules/vpc"
+
+ for_each = var.networks
+
+ project_id = var.project
+ name = "${var.name_prefix}${each.value.vpc_name}"
+ create_network = each.value.create_network
+ delete_default_routes_on_create = each.value.delete_default_routes_on_create
+ mtu = each.value.mtu
+ routing_mode = each.value.routing_mode
+ subnetworks = { for k, v in each.value.subnetworks : k => merge(v, {
+ name = "${var.name_prefix}${v.name}"
+ })
+ }
+ firewall_rules = try({ for k, v in each.value.firewall_rules : k => merge(v, {
+ name = "${var.name_prefix}${v.name}"
+ })
+ }, {})
+}
+
+resource "google_compute_route" "this" {
+
+ for_each = var.routes
+
+ name = "${var.name_prefix}${each.value.name}"
+ dest_range = each.value.destination_range
+ network = module.vpc[each.value.vpc_network_key].network.self_link
+ next_hop_ilb = module.lb_internal[each.value.lb_internal_key].forwarding_rule
+ priority = 100
+}
+
+module "vpc_peering" {
+ source = "../../modules/vpc-peering"
+
+ for_each = var.vpc_peerings
+
+ local_network = module.vpc[each.value.local_network_key].network.id
+ peer_network = module.vpc[each.value.peer_network_key].network.id
+
+ local_export_custom_routes = each.value.local_export_custom_routes
+ local_import_custom_routes = each.value.local_import_custom_routes
+ local_export_subnet_routes_with_public_ip = each.value.local_export_subnet_routes_with_public_ip
+ local_import_subnet_routes_with_public_ip = each.value.local_import_subnet_routes_with_public_ip
+
+ peer_export_custom_routes = each.value.peer_export_custom_routes
+ peer_import_custom_routes = each.value.peer_import_custom_routes
+ peer_export_subnet_routes_with_public_ip = each.value.peer_export_subnet_routes_with_public_ip
+ peer_import_subnet_routes_with_public_ip = each.value.peer_import_subnet_routes_with_public_ip
+}
+
+module "autoscale" {
+ source = "../../modules/autoscale/"
+
+ for_each = var.autoscale
+
+ name = "${var.name_prefix}${each.value.name}"
+ region = var.region
+ project_id = var.project
+ regional_mig = try(var.autoscale_regional_mig, true)
+ zones = try(each.value.zones, {})
+ image = "https://www.googleapis.com/compute/v1/projects/paloaltonetworksgcp-public/global/images/${try(each.value.image, var.autoscale_common.image)}"
+ named_ports = try(each.value.named_ports, var.autoscale_common.named_ports)
+ machine_type = try(each.value.machine_type, var.autoscale_common.machine_type)
+ min_cpu_platform = try(each.value.min_cpu_platform, var.autoscale_common.min_cpu_platform, "Intel Cascade Lake")
+ disk_type = try(each.value.disk_type, var.autoscale_common.disk_type, "pd-ssd")
+ service_account_email = try(module.iam_service_account[each.value.service_account_key].email, module.iam_service_account[var.autoscale_common.service_account_key].email)
+ scopes = try(each.value.scopes, var.autoscale_common.scopes, [])
+ tags = try(each.value.tags, var.autoscale_common.tags, [])
+ update_policy_type = try(each.value.update_policy_type, var.autoscale_common.update_policy_type, "OPPORTUNISTIC")
+ min_vmseries_replicas = try(each.value.min_vmseries_replicas, var.autoscale_common.min_vmseries_replicas)
+ max_vmseries_replicas = try(each.value.max_vmseries_replicas, var.autoscale_common.max_vmseries_replicas)
+ cooldown_period = try(each.value.cooldown_period, var.autoscale_common.cooldown_period, 480)
+ scale_in_control_time_window_sec = try(each.value.scale_in_control_time_window_sec, var.autoscale_common.scale_in_control_time_window_sec, 1800)
+ scale_in_control_replicas_fixed = try(each.value.scale_in_control_replicas_fixed, var.autoscale_common.scale_in_control_replicas_fixed, 1)
+ create_pubsub_topic = try(each.value.create_pubsub_topic, var.autoscale_common.create_pubsub_topic)
+ autoscaler_metrics = try(each.value.autoscaler_metrics, var.autoscale_common.autoscaler_metrics,
+ {
+ "custom.googleapis.com/VMSeries/panSessionUtilization" = {
+ target = 70
+ }
+ "custom.googleapis.com/VMSeries/panSessionThroughputKbps" = {
+ target = 700000
+ }
+ })
+
+ network_interfaces = [for v in each.value.network_interfaces :
+ {
+ subnetwork = module.vpc[v.vpc_network_key].subnetworks[v.subnetwork_key].self_link
+ create_public_ip = try(v.create_public_ip, false)
+ }]
+ metadata = merge(
+ try(each.value.bootstrap_options, {}),
+ try(var.autoscale_common.bootstrap_options, {})
+ )
+}
+
+data "google_compute_image" "my_image" {
+ family = "ubuntu-pro-2204-lts"
+ project = "ubuntu-os-pro-cloud"
+}
+
+resource "google_compute_instance" "linux_vm" {
+ for_each = var.linux_vms
+
+ name = "${var.name_prefix}${each.key}"
+ machine_type = each.value.linux_machine_type
+ zone = each.value.zone
+
+ boot_disk {
+ initialize_params {
+ image = data.google_compute_image.my_image.id
+ size = each.value.linux_disk_size
+ }
+ }
+
+ network_interface {
+ subnetwork = module.vpc[each.value.vpc_network_key].subnetworks[each.value.subnetwork_key].self_link
+ network_ip = each.value.private_ip
+ }
+
+ metadata = {
+ enable-oslogin = true
+ }
+
+
+ service_account {
+ email = module.iam_service_account[each.value.service_account_key].email
+ scopes = each.value.scopes
+ }
+}
+
+module "lb_internal" {
+ source = "../../modules/lb_internal"
+
+ for_each = var.lbs_internal
+
+ name = "${var.name_prefix}${each.value.name}"
+ region = var.region
+ health_check_port = try(each.value.health_check_port, "80")
+ backends = var.autoscale_regional_mig ? { for v in each.value.backends : v => module.autoscale[v].regional_instance_group_id } : merge([
+ for v in each.value.backends :
+ {
+ for z_k, z_v in var.autoscale[v].zones :
+ "${v}_${z_k}" => module.autoscale[v].zonal_instance_group_ids[z_k]
+ }
+ ]...)
+ subnetwork = module.vpc[each.value.vpc_network_key].subnetworks[each.value.subnetwork_key].self_link
+ network = module.vpc[each.value.vpc_network_key].network.self_link
+ all_ports = true
+}
+
+module "lb_external" {
+ source = "../../modules/lb_external"
+
+ for_each = var.lbs_external
+
+ project = var.project
+
+ name = "${var.name_prefix}${each.value.name}"
+ backend_instance_groups = var.autoscale_regional_mig ? { for v in each.value.backends : v => module.autoscale[v].regional_instance_group_id } : merge([
+ for v in each.value.backends :
+ {
+ for z_k, z_v in var.autoscale[v].zones :
+ "${v}_${z_k}" => module.autoscale[v].zonal_instance_group_ids[z_k]
+ }
+ ]...)
+ rules = each.value.rules
+
+ health_check_http_port = each.value.http_health_check_port
+ health_check_http_request_path = try(each.value.http_health_check_request_path, "/php/login.php")
+}
\ No newline at end of file
diff --git a/examples/vpc_peering_dedicated_with_autoscale/main_test.go b/examples/vpc_peering_dedicated_with_autoscale/main_test.go
new file mode 100644
index 00000000..6986c898
--- /dev/null
+++ b/examples/vpc_peering_dedicated_with_autoscale/main_test.go
@@ -0,0 +1,65 @@
+package vpc_peering_dedicated_with_autoscale
+
+import (
+ "testing"
+ "log"
+
+ "github.com/PaloAltoNetworks/terraform-modules-vmseries-tests-skeleton/pkg/testskeleton"
+ "github.com/gruntwork-io/terratest/modules/logger"
+ "github.com/gruntwork-io/terratest/modules/terraform"
+)
+
+func CreateTerraformOptions(t *testing.T) *terraform.Options {
+ varsInfo, err := testskeleton.GenerateTerraformVarsInfo("gcp")
+ if err != nil {
+ // Handle the error
+ log.Fatalf("Error generating terraform vars info: %v", err)
+ }
+
+ // define options for Terraform
+ terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
+ TerraformDir: ".",
+ VarFiles: []string{"example.tfvars"},
+ Vars: map[string]interface{}{
+ "name_prefix": varsInfo.NamePrefix,
+ "project": varsInfo.GoogleProjectId,
+ },
+ Logger: logger.Default,
+ Lock: true,
+ Upgrade: true,
+ SetVarsAfterVarFiles: true,
+ })
+
+ return terraformOptions
+}
+
+func TestValidate(t *testing.T) {
+ testskeleton.ValidateCode(t, nil)
+}
+
+func TestPlan(t *testing.T) {
+ // define options for Terraform
+ terraformOptions := CreateTerraformOptions(t)
+ // prepare list of items to check
+ assertList := []testskeleton.AssertExpression{}
+ // plan test infrastructure and verify outputs
+ testskeleton.PlanInfraCheckErrors(t, terraformOptions, assertList, "No errors are expected")
+}
+
+func TestApply(t *testing.T) {
+ // define options for Terraform
+ terraformOptions := CreateTerraformOptions(t)
+ // prepare list of items to check
+ assertList := []testskeleton.AssertExpression{}
+ // deploy test infrastructure and verify outputs and check if there are no planned changes after deployment
+ testskeleton.DeployInfraCheckOutputs(t, terraformOptions, assertList)
+}
+
+func TestIdempotence(t *testing.T) {
+ // define options for Terraform
+ terraformOptions := CreateTerraformOptions(t)
+ // prepare list of items to check
+ assertList := []testskeleton.AssertExpression{}
+ // deploy test infrastructure and verify outputs and check if there are no planned changes after deployment
+ testskeleton.DeployInfraCheckOutputsVerifyChanges(t, terraformOptions, assertList)
+}
diff --git a/examples/vpc_peering_dedicated_with_autoscale/outputs.tf b/examples/vpc_peering_dedicated_with_autoscale/outputs.tf
new file mode 100644
index 00000000..eec4859c
--- /dev/null
+++ b/examples/vpc_peering_dedicated_with_autoscale/outputs.tf
@@ -0,0 +1,24 @@
+output "pubsub_topic_id" {
+ description = "The resource ID of the Pub/Sub Topic."
+ value = try({ for k, v in module.autoscale : k => v.pubsub_topic_id }, null)
+}
+
+output "pubsub_subscription_id" {
+ description = "The resource ID of the Pub/Sub Subscription."
+ value = try({ for k, v in module.autoscale : k => v.pubsub_subscription_id }, null)
+}
+
+output "lbs_internal_ips" {
+ description = "Private IP addresses of internal network loadbalancers."
+ value = { for k, v in module.lb_internal : k => v.address }
+}
+
+output "lbs_external_ips" {
+ description = "Public IP addresses of external network loadbalancers."
+ value = { for k, v in module.lb_external : k => v.ip_addresses }
+}
+
+output "linux_vm_ips" {
+ description = "Private IP addresses of Linux VMs."
+ value = { for k, v in resource.google_compute_instance.linux_vm : k => v.network_interface[0].network_ip }
+}
\ No newline at end of file
diff --git a/examples/vpc_peering_dedicated_with_autoscale/variables.tf b/examples/vpc_peering_dedicated_with_autoscale/variables.tf
new file mode 100644
index 00000000..d3089ea8
--- /dev/null
+++ b/examples/vpc_peering_dedicated_with_autoscale/variables.tf
@@ -0,0 +1,349 @@
+# General
+variable "project" {
+ description = "The project name to deploy the infrastructure in to."
+ type = string
+ default = null
+}
+variable "region" {
+ description = "The region into which to deploy the infrastructure in to."
+ type = string
+ default = "us-central1"
+}
+variable "name_prefix" {
+ description = "A string to prefix resource namings."
+ type = string
+ default = "example-"
+}
+
+#Service Account
+
+variable "service_accounts" {
+ description = <<-EOF
+ A map containing each service account setting.
+
+ Example of variable deployment :
+ ```
+ service_accounts = {
+ "sa-vmseries-01" = {
+ service_account_id = "sa-vmseries-01"
+ display_name = "VM-Series SA"
+ roles = [
+ "roles/compute.networkViewer",
+ "roles/logging.logWriter",
+ "roles/monitoring.metricWriter",
+ "roles/monitoring.viewer",
+ "roles/viewer"
+ ]
+ }
+ }
+ ```
+ For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/iam_service_account#Inputs)
+
+ Multiple keys can be added and will be deployed by the code.
+
+ EOF
+ type = map(any)
+ default = {}
+}
+
+#VPC
+
+variable "networks" {
+ description = <<-EOF
+ A map containing each network setting.
+
+ Example of variable deployment :
+
+ ```
+ networks = {
+ fw-mgmt-vpc = {
+ vpc_name = "fw-mgmt-vpc"
+ create_network = true
+ delete_default_routes_on_create = false
+ mtu = "1460"
+ routing_mode = "REGIONAL"
+ subnetworks = {
+ fw-mgmt-sub = {
+ name = "fw-mgmt-sub"
+ create_subnetwork = true
+ ip_cidr_range = "10.10.10.0/28"
+ region = "us-east1"
+ }
+ }
+ firewall_rules = {
+ allow-mgmt-ingress = {
+ name = "allow-mgmt-vpc"
+ source_ranges = ["10.10.10.0/24", "1.1.1.1/32"] # Replace 1.1.1.1/32 with your own souurce IP address for management purposes.
+ priority = "1000"
+ allowed_protocol = "all"
+ allowed_ports = []
+ }
+ }
+ }
+ }
+ ```
+
+ For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/vpc#input_networks)
+
+ Multiple keys can be added and will be deployed by the code.
+ EOF
+ type = any
+ default = {}
+}
+
+variable "vpc_peerings" {
+ description = <<-EOF
+ A map containing each VPC peering setting.
+
+ Example of variable deployment :
+
+ ```
+ vpc_peerings = {
+ "trust-to-spoke1" = {
+ local_network_key = "fw-trust-vpc"
+ peer_network_key = "fw-spoke1-vpc"
+
+ local_export_custom_routes = true
+ local_import_custom_routes = true
+ local_export_subnet_routes_with_public_ip = true
+ local_import_subnet_routes_with_public_ip = true
+
+ peer_export_custom_routes = true
+ peer_import_custom_routes = true
+ peer_export_subnet_routes_with_public_ip = true
+ peer_import_subnet_routes_with_public_ip = true
+ }
+ }
+ ```
+ For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/vpc-peering#inputs)
+
+ Multiple keys can be added and will be deployed by the code.
+ EOF
+ type = map(any)
+ default = {}
+}
+
+variable "routes" {
+ description = <<-EOF
+ A map containing each route setting. Note that you can only add routes using a next-hop type of internal load-balance rule.
+
+ Example of variable deployment :
+
+ ```
+ routes = {
+ "default-route-trust" = {
+ name = "fw-default-trust"
+ destination_range = "0.0.0.0/0"
+ vpc_network_key = "fw-trust-vpc"
+ lb_internal_name = "internal-lb"
+ }
+ }
+ ```
+
+ Multiple keys can be added and will be deployed by the code.
+ EOF
+ type = map(any)
+ default = {}
+}
+
+#Autoscale
+variable "autoscale_regional_mig" {
+ description = <<-EOF
+ Sets the managed instance group type to either a regional (if `true`) or a zonal (if `false`).
+ For more information please see [About regional MIGs](https://cloud.google.com/compute/docs/instance-groups/regional-migs#why_choose_regional_managed_instance_groups).
+ EOF
+ type = bool
+ default = true
+}
+variable "autoscale_common" {
+ description = <<-EOF
+ A map containing common vmseries autoscale setting.
+ Bootstrap options can be moved between vmseries autoscale individual instances variable (`autoscale`) and this common vmseries autoscale variable (`autoscale_common`).
+
+ Example of variable deployment :
+
+ ```
+ autoscale_common = {
+ image = "vmseries-flex-byol-1110"
+ machine_type = "n2-standard-4"
+ min_cpu_platform = "Intel Cascade Lake"
+ disk_type = "pd-ssd"
+ scopes = [
+ "https://www.googleapis.com/auth/compute.readonly",
+ "https://www.googleapis.com/auth/cloud.useraccounts.readonly",
+ "https://www.googleapis.com/auth/devstorage.read_only",
+ "https://www.googleapis.com/auth/logging.write",
+ "https://www.googleapis.com/auth/monitoring.write",
+ ]
+ tags = ["vmseries-autoscale"]
+ update_policy_type = "OPPORTUNISTIC"
+ cooldown_period = 480
+ bootstrap_options = [
+ panorama_server = "1.1.1.1"
+ ]
+ }
+ ```
+ EOF
+ type = any
+ default = {}
+}
+
+variable "autoscale" {
+ description = <<-EOF
+ A map containing each vmseries autoscale setting.
+ Zonal or regional managed instance group type is controolled from the `autoscale_regional_mig` variable for all autoscale instances.
+
+ Example of variable deployment :
+
+ ```
+ autoscale = {
+ fw-autoscale-common = {
+ name = "fw-autoscale-common"
+ zones = {
+ zone1 = "us-east4-b"
+ zone2 = "us-east4-c"
+ }
+ named_ports = [
+ {
+ name = "http"
+ port = 80
+ },
+ {
+ name = "https"
+ port = 443
+ }
+ ]
+ service_account_key = "sa-vmseries-01"
+ min_vmseries_replicas = 2
+ max_vmseries_replicas = 4
+ create_pubsub_topic = true
+ autoscaler_metrics = {
+ "custom.googleapis.com/VMSeries/panSessionUtilization" = {
+ target = 70
+ }
+ "custom.googleapis.com/VMSeries/panSessionThroughputKbps" = {
+ target = 700000
+ }
+ }
+ bootstrap_options = {
+ type = "dhcp-client"
+ dhcp-send-hostname = "yes"
+ dhcp-send-client-id = "yes"
+ dhcp-accept-server-hostname = "yes"
+ dhcp-accept-server-domain = "yes"
+ mgmt-interface-swap = "enable"
+ panorama-server = "1.1.1.1"
+ ssh-keys = "admin:" # Replace this value with client data
+ }
+ network_interfaces = [
+ {
+ vpc_network_key = "fw-untrust-vpc"
+ subnetwork_key = "fw-untrust-sub"
+ create_public_ip = true
+ },
+ {
+ vpc_network_key = "fw-mgmt-vpc"
+ subnetwork_key = "fw-mgmt-sub"
+ create_public_ip = true
+ },
+ {
+ vpc_network_key = "fw-trust-vpc"
+ subnetwork_key = "fw-trust-sub"
+ }
+ ]
+ }
+ }
+ ```
+ EOF
+ type = any
+ default = {}
+}
+
+#Load Balancers
+
+variable "lbs_internal" {
+ description = <<-EOF
+ A map containing each internal loadbalancer setting.
+ Note : private IP reservation is not by default within the example as it may overlap with autoscale IP allocation.
+
+ Example of variable deployment :
+
+ ```
+ lbs_internal = {
+ "internal-lb" = {
+ name = "internal-lb"
+ health_check_port = "80"
+ backends = ["fw-vmseries-01", "fw-vmseries-02"]
+ subnetwork_key = "fw-trust-sub"
+ vpc_network_key = "fw-trust-vpc"
+ }
+ }
+ ```
+ For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/lb_internal#inputs)
+
+ Multiple keys can be added and will be deployed by the code.
+ EOF
+ type = map(any)
+ default = {}
+}
+variable "lbs_external" {
+ description = <<-EOF
+ A map containing each external loadbalancer setting.
+
+ Example of variable deployment :
+
+ ```
+ lbs_external = {
+ "external-lb" = {
+ name = "external-lb"
+ backends = ["fw-vmseries-01", "fw-vmseries-02"]
+ rules = {
+ "all-ports" = {
+ ip_protocol = "L3_DEFAULT"
+ }
+ }
+ http_health_check_port = "80"
+ http_health_check_request_path = "/php/login.php"
+ }
+ }
+ ```
+ For a full list of available configuration items - please refer to [module documentation](https://github.com/PaloAltoNetworks/terraform-google-vmseries-modules/tree/main/modules/lb_external#inputs)
+
+ Multiple keys can be added and will be deployed by the code.
+ EOF
+ type = map(any)
+ default = {}
+}
+
+#Spoke VPCs Linux VMs
+
+variable "linux_vms" {
+ description = <<-EOF
+ A map containing each Linux VM configuration that will be placed in SPOKE VPCs for testing purposes.
+
+ Example of varaible deployment:
+
+ ```
+ linux_vms = {
+ spoke1-vm = {
+ linux_machine_type = "n2-standard-4"
+ zone = "us-east1-b"
+ linux_disk_size = "50" # Modify this value as per deployment requirements
+ vpc_network_key = "fw-spoke1-vpc"
+ subnetwork_key = "fw-spoke1-sub"
+ private_ip = "192.168.1.2"
+ scopes = [
+ "https://www.googleapis.com/auth/compute.readonly",
+ "https://www.googleapis.com/auth/cloud.useraccounts.readonly",
+ "https://www.googleapis.com/auth/devstorage.read_only",
+ "https://www.googleapis.com/auth/logging.write",
+ "https://www.googleapis.com/auth/monitoring.write",
+ ]
+ service_account_key = "sa-linux-01"
+ }
+ }
+ ```
+ EOF
+ type = map(any)
+ default = {}
+}
diff --git a/examples/vpc_peering_dedicated_with_autoscale/versions.tf b/examples/vpc_peering_dedicated_with_autoscale/versions.tf
new file mode 100644
index 00000000..785e9269
--- /dev/null
+++ b/examples/vpc_peering_dedicated_with_autoscale/versions.tf
@@ -0,0 +1,13 @@
+terraform {
+ required_version = ">= 1.3, < 2.0"
+}
+
+provider "google" {
+ project = var.project
+ region = var.region
+}
+
+provider "google-beta" {
+ project = var.project
+ region = var.region
+}