diff --git a/gcp/ilbnh-mig/README.md b/gcp/ilbnh-mig/README.md new file mode 100644 index 00000000..e617ff44 --- /dev/null +++ b/gcp/ilbnh-mig/README.md @@ -0,0 +1,76 @@ +## MultiNic ILB Deployment +This is a Terraform version of the manual build described at: +https://cloud.google.com/load-balancing/docs/internal/setting-up-ilb-next-hop + +Terraform creates a VM-Series firewall that secures egress and east-west traffic for 2 internal VPCs. Egress traffic from the internal VPCs is routed via the Load Balancer as Next Hop to the VM-Series. The FW is deployed via a Managed Instance Group to allow for automatic failure detection/repacement. + +### Overview +* 4 x VPCs (testing,management,production, production2) +* 1 x VM-Series (BYOL / Bundle1 / Bundle2) in a Managed Instance Group +* 1 x Ubuntu VM in the testing VPC (install Apache during creation) +* 1 x Ubuntu VM in the production VPC (install Apache during creation) +* 1 x GCP Internal Load Balancer in the testing VPC +* 1 x GCP Internal Load Balancer in the production VPC +* 1 x GCP Storage Bucket for VM-Series bootstrapping (random string appended to bucket name for global uniqueness) +
+

+ +

+ + +### Prerequistes +1. Terraform +2. Access to GCP Console + +After deployment, the firewalls' username and password are: + * **Username:** paloalto + * **Password:** Pal0Alt0@123 + +### Deployment +1. Download the **ilbnh-mig** repo to the machine running the build +2. In an editor, open **terraform.tfvars** and set values for the following variables + +| Variable | Description | +| :------------- | :------------- | +| `project_id` | Project ID for the VM-Series, VM-Series VPCs, GCP storage bucket, & public load balancer. | +| `public_key_path` | Public key used to authenticate to the FW (username: admin) and the Ubuntu VMs (username:demo) | +| `fw_panos` | The species and version of the FW to deploy | +| `auth_file`| Authentication key file for deployment | + +3. Download project authenication key files to the main directory of the terraform build. +

+ +

+ +4. Execute Terraform +``` +$ terraform init +$ terraform plan +$ terraform apply +``` + +5. After the deployment finishes, navigate to the console and not the public IP address associated with one of the ubuntu servers. + +

+ +

+ +6. Connect to the server and issue the curl command to its peer. + +

+ +

+ +7. Login to the FW and note the traffic logs. +

+ +

+ +8. Destroy the envirnment when done. +``` +$ terraform destroy +``` + +## Support Policy +The guide in this directory and accompanied files are released under an as-is, best effort, support policy. These scripts should be seen as community supported and Palo Alto Networks will contribute our expertise as and when possible. We do not provide technical support or help in using or troubleshooting the components of the project through our normal support options such as Palo Alto Networks support teams, or ASC (Authorized Support Centers) partners and backline support options. The underlying product used (the VM-Series firewall) by the scripts or templates are still supported, but the support is only for the product functionality and not for help in deploying or using the template or script itself. +Unless explicitly tagged, all projects or work posted in our GitHub repository (at https://github.com/PaloAltoNetworks) or sites other than our official Downloads page on https://support.paloaltonetworks.com are provided under the best effort policy. diff --git a/gcp/ilbnh-mig/bootstrap_files/authcodes b/gcp/ilbnh-mig/bootstrap_files/authcodes new file mode 100644 index 00000000..0519ecba --- /dev/null +++ b/gcp/ilbnh-mig/bootstrap_files/authcodes @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gcp/ilbnh-mig/bootstrap_files/bootstrap.xml b/gcp/ilbnh-mig/bootstrap_files/bootstrap.xml new file mode 100644 index 00000000..a354ec4f --- /dev/null +++ b/gcp/ilbnh-mig/bootstrap_files/bootstrap.xml @@ -0,0 +1,1099 @@ + + + + + + + + yes + + + $1$swuuvbfr$TeXPJ5vj8FQP5E9NiByN40 + + + + + yes + + + $1$kpolrmjb$lJ5t7tCjS7Ghd8tachjOJ. + c3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFCQVFDblNZOFdJbktrdGhVZnExdjFoSnlWdHhCSEpTYlRWQnhTTFBwYXg3MGUwRW5sZVZkdGk0VURLUFplREpQMVVxWjNYWjZIblk0L1NzQnhocFFXeW1LenpNYURqVnZ3TWhtcm04ampXYndRYXlqdEk4UVl0SnZNa1RhcHYwT2hWZTBmUUM5VXdTTnFHZ2FTKzVnUGdJRWVPaTB0a01OeU10VjY2bmhCL05ubktqc3RLSnoxYmt5K3RPUnQyeWNvYmdZWVJMdytRdWVLYmpHTkxFSTcrWkp5ak5URm8rUFAyaFZ4Q3hJL2ZzTnpvcTFjNjgyOXVkcmhwOUZsODhqbGNPSFdsYTUrMnRXS0VNVVRrKzY5eXZ3TmhrL3lvZ2F5VUFZZTJROXpEOG9pb2RzVnZSV29VOTk3dmt6TFE3c3FHT0VTYzk5a0xJTzFWaGtGalZHTDExSnogc3R1ZGVudC0wMy0wYWQ5MTllODQ2NmJAcXdpa2xhYnMubmV0 + + + + + + + + + + + + + yes + 5 + + + yes + 5 + + + yes + 5 + + + yes + 10 + + + yes + 5 + + + + yes + + + + 10 + 10 + + 100 + 50 + + + + 10 + 10 + + 100 + 50 + + + + + + 100 + yes + + + + + + + + + + + + + + + + + + + + + no + + + + + no + + 1460 + + no + + + + + + + + + + no + + + + + no + + + no + + + no + + + + + + + + + no + + + + + no + + + no + + + no + + + + + + + + + no + + + + + hc-tcp-22 + + + + no + + + + + hc-tcp-22 + + + + no + + + + + hc-tcp-22 + + + + + + + + 3 + 5 + wait-recover + + + + + no + yes + + + + + + + + + + + + + aes-128-cbc + 3des + + + sha1 + + + group2 + + + 8 + + + + + aes-128-cbc + + + sha256 + + + group19 + + + 8 + + + + + aes-256-cbc + + + sha384 + + + group20 + + + 8 + + + + + + + + aes-128-cbc + 3des + + + sha1 + + + group2 + + 1 + + + + + + aes-128-gcm + + + none + + + group19 + + 1 + + + + + + aes-256-gcm + + + none + + + group20 + + 1 + + + + + + + aes-128-cbc + + + sha1 + + + + + + + + + + + real-time + + + high + + + high + + + medium + + + medium + + + low + + + low + + + low + + + + + + + + + + no + + + 1.25 + 0.5 + 900 + 300 + 900 + yes + + + + + yes + + + + + no + + + no + + + no + + + + ethernet1/1 + loopback.1 + + + + + + + + + + + + 10.30.1.1 + + + None + + + no + any + 2 + + ethernet1/1 + 10 + Health-Check-Probe1 + + + + + + + 10.30.1.1 + + + None + + + no + any + 2 + + ethernet1/1 + 10 + Health-Check-Probe2 + + + + + + + no + any + 2 + + + trust2 + + + None + + 10 + 10.50.1.0/24 + + + + + + + no + any + 2 + + + trust3 + + + None + + 10 + 10.40.1.0/24 + + + + + + + + + + + + + + + + + + + yes + + + no + + + no + + + no + + + no + + + + + + + + 10.50.1.1 + + + None + + + no + any + 2 + + ethernet1/2 + 10 + Health-Check-Probe1 + + + + + + + 10.50.1.1 + + + None + + + no + any + 2 + + ethernet1/2 + 10 + Health-Check-Probe2 + + + + + + + no + any + 2 + + + trust1 + + + None + + 10 + 10.30.1.0/24 + + + + + + + no + any + 2 + + + trust3 + + + None + + 10 + 10.40.1.0/24 + + + + + + + + + 120 + + + ethernet1/2 + loopback.2 + + + + + + + + + + + + + yes + + + no + + + no + + + no + + + no + + + + + + + + 10.40.1.1 + + + None + + + no + any + 2 + + ethernet1/3 + 10 + Health-Check-Probe1 + + + + + + + 10.40.1.1 + + + None + + + no + any + 2 + + ethernet1/3 + 10 + Health-Check-Probe2 + + + + + + + no + any + 2 + + + trust1 + + + None + + 10 + 10.30.1.0/24 + + + + + + + no + any + 2 + + + trust2 + + + None + + 10 + 10.50.1.0/24 + + + + + + + + + ethernet1/3 + loopback.3 + + + + + + + updates.paloaltonetworks.com + + + + + wednesday + 01:02 + download-only + + + + + US/Pacific + + yes + no + + Multi-Nic-ILB + + + yes + no + no + no + + + yes + + + + + yes + 1 + + + + + + yes + + + FQDN + + c3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFCQVFDblNZOFdJbktrdGhVZnExdjFoSnlWdHhCSEpTYlRWQnhTTFBwYXg3MGUwRW5sZVZkdGk0VURLUFplREpQMVVxWjNYWjZIblk0L1NzQnhocFFXeW1LenpNYURqVnZ3TWhtcm04ampXYndRYXlqdEk4UVl0SnZNa1RhcHYwT2hWZTBmUUM5VXdTTnFHZ2FTKzVnUGdJRWVPaTB0a01OeU10VjY2bmhCL05ubktqc3RLSnoxYmt5K3RPUnQyeWNvYmdZWVJMdytRdWVLYmpHTkxFSTcrWkp5ak5URm8rUFAyaFZ4Q3hJL2ZzTnpvcTFjNjgyOXVkcmhwOUZsODhqbGNPSFdsYTUrMnRXS0VNVVRrKzY5eXZ3TmhrL3lvZ2F5VUFZZTJROXpEOG9pb2RzVnZSV29VOTk3dmt6TFE3c3FHT0VTYzk5a0xJTzFWaGtGalZHTDExSnogc3R1ZGVudC0wMy0wYWQ5MTllODQ2NmJAcXdpa2xhYnMubmV0 + + + yes + no + no + no + + + multi-nic-ilb + mgmt-interface-swap + + + + + + + + + + + + + ethernet1/1 + loopback.1 + + + + + + + ethernet1/2 + loopback.2 + + + + + + + ethernet1/3 + loopback.3 + + + + + + + + + 22 + + + + + + + 221 + + + + + + + 222 + + + + + + + + + + + + any + + + Trust1 + Trust2 + + + Health-Check-Group + + + any + + + any + + + any + + + any + + + application-default + + + any + + allow + no + no + + + + any + + + any + + + any + + + any + + + any + + + any + + + any + + + application-default + + + any + + allow + yes + + + + + + + + + + ethernet1/1 + + + + + Trust1 + + + any + + + Testing Network + + + any + + any + no + + + + + + ethernet1/2 + + + + + Trust2 + + + any + + + Production Network + + + any + + any + no + + + + + + + deny + yes + yes + + + allow + yes + yes + + + + + + + + + + + any + + + any + + + critical + + any + client + any + disable + + + + + + + any + + + any + + + high + + any + client + any + disable + + + + + + + any + + + any + + + medium + + any + client + any + disable + + + + + + + any + + + any + + + critical + + any + server + any + disable + + + + + + + any + + + any + + + high + + any + server + any + disable + + + + + + + any + + + any + + + medium + + any + server + any + disable + + + + + + + + + + + + + WW's profile + + + + + +
+ + 35.191.0.0/16 + + + 130.211.0.0/22 + + + 10.50.1.0/24 + + + 10.30.1.0/24 + +
+ + + + ethernet1/1 + loopback.1 + ethernet1/2 + loopback.2 + ethernet1/3 + loopback.3 + + + + + + + Health-Check-Probe1 + Health-Check-Probe2 + + + +
+
+
+
+
diff --git a/gcp/ilbnh-mig/bootstrap_files/init-cfg.txt b/gcp/ilbnh-mig/bootstrap_files/init-cfg.txt new file mode 100644 index 00000000..5b9c168b --- /dev/null +++ b/gcp/ilbnh-mig/bootstrap_files/init-cfg.txt @@ -0,0 +1,10 @@ +type=dhcp-client +ip-address= +default-gateway= +netmask= +ipv6-address= +ipv6-default-gateway= +hostname=packet-mirroring +op-command-modes=mgmt-interface-swap +dns-primary= +dns-secondary= \ No newline at end of file diff --git a/gcp/ilbnh-mig/fw_common.tf b/gcp/ilbnh-mig/fw_common.tf new file mode 100644 index 00000000..aeaa685c --- /dev/null +++ b/gcp/ilbnh-mig/fw_common.tf @@ -0,0 +1,106 @@ +#----------------------------------------------------------------------------------------------- +# Create bootstrap bucket for firewalls +module "bootstrap_common" { + source = "./modules/gcp_bootstrap/" + bucket_name = "fw-bootstrap-common" + file_location = "bootstrap_files/" + config = ["init-cfg.txt", "bootstrap.xml"] +# config = ["init-cfg.txt"] + license = ["authcodes"] +} + +#----------------------------------------------------------------------------------------------- +# Create firewall template +#----------------------------------------------------------------------------------------------- +module "fw_common" { + source = "./modules/vmseries/" + base_name = var.fw_base_name + region = var.region + target_size = var.target_size + zones = [ + data.google_compute_zones.available.names[0], + data.google_compute_zones.available.names[1] + ] + networks = [ + module.vpc0.network_self_link, + module.vpc1.network_self_link, + module.vpc2.network_self_link, + module.vpc3.network_self_link + ] + subnetworks = [ + module.vpc0.subnetwork_self_link, + module.vpc1.subnetwork_self_link, + module.vpc2.subnetwork_self_link, + module.vpc3.subnetwork_self_link + ] + machine_type = var.fw_machine_type + bootstrap_bucket = module.bootstrap_common.bucket_name + mgmt_interface_swap = "enable" + ssh_key = fileexists(var.public_key_path) ? "admin:${file(var.public_key_path)}" : "" + image = "${var.fw_image}-${var.fw_panos}" + nic0_public_ip = false + nic1_public_ip = true + nic2_public_ip = false + nic3_public_ip = false + create_instance_group = true + + dependencies = [ + module.bootstrap_common.completion, + ] +} + +resource "google_compute_health_check" "hc_ssh_22" { + name = "hc-ssh-22" + + tcp_health_check { + port = var.health_check_port + } +} + +module "ilb1" { + source = "./modules/ilbnh/" + name = "ilb1" + project_id = var.project_id + all_ports = true + ports = [] + health_checks = [google_compute_health_check.hc_ssh_22.self_link] + region = var.region + network = module.vpc0.vpc_id + network_uri = module.vpc0.network_self_link + subnetwork = module.vpc0.subnetwork_self_link + ip_address = var.ilb1_ip + group = module.fw_common.vmseries_rigm +} + +module "ilb2" { + source = "./modules/ilbnh/" + name = "ilb2" + project_id = var.project_id + all_ports = true + ports = [] + health_checks = [google_compute_health_check.hc_ssh_22.self_link] + region = var.region + network = module.vpc2.vpc_id + network_uri = module.vpc2.network_self_link + subnetwork = module.vpc2.subnetwork_self_link + ip_address = var.ilb2_ip + group = module.fw_common.vmseries_rigm + } + +#----------------------------------------------------------------------------------------------- +# Create routes route to internal LBs. +resource "google_compute_route" "ilb_nhop_dest_10_30_1" { + name = "ilb-nhop-dest-10-30-1" + dest_range = "10.30.1.0/24" + network = module.vpc2.network_self_link + next_hop_ilb = module.ilb2.forwarding_rule + priority = 99 +} + +resource "google_compute_route" "ilb_nhop_dest_10_50_1" { + name = "ilb-nhop-dest-10-50-1" + dest_range = "10.50.1.0/24" + network = module.vpc0.network_self_link + next_hop_ilb = module.ilb1.forwarding_rule + priority = 99 +} \ No newline at end of file diff --git a/gcp/ilbnh-mig/fw_vpc.tf b/gcp/ilbnh-mig/fw_vpc.tf new file mode 100644 index 00000000..230a66c0 --- /dev/null +++ b/gcp/ilbnh-mig/fw_vpc.tf @@ -0,0 +1,40 @@ +#----------------------------------------------------------------------------------------------- +# Create firewall VPCs & subnets +module "vpc0" { + source = "./modules/vpc/" + vpc = var.vpc0 + subnet = var.vpc0_subnet + cidr = var.vpc0_cidr + region = var.region + allowed_sources = ["0.0.0.0/0"] +} + +module "vpc1" { + source = "./modules/vpc/" + vpc = var.vpc1 + subnet = var.vpc1_subnet + cidr = var.vpc1_cidr + region = var.region + allowed_sources = var.mgmt_sources + allowed_protocol = "TCP" + allowed_ports = ["443", "22"] +} + +module "vpc2" { + source = "./modules/vpc/" + vpc = var.vpc2 + subnet = var.vpc2_subnet + cidr = var.vpc2_cidr + region = var.region + allowed_sources = ["0.0.0.0/0"] +} + +module "vpc3" { + source = "./modules/vpc/" + vpc = var.vpc3 + subnet = var.vpc3_subnet + cidr = var.vpc3_cidr + region = var.region + allowed_sources = ["0.0.0.0/0"] + delete_default_route = true +} diff --git a/gcp/ilbnh-mig/images/curl.png b/gcp/ilbnh-mig/images/curl.png new file mode 100644 index 00000000..e17b875c Binary files /dev/null and b/gcp/ilbnh-mig/images/curl.png differ diff --git a/gcp/ilbnh-mig/images/deployment.png b/gcp/ilbnh-mig/images/deployment.png new file mode 100644 index 00000000..636f95d1 Binary files /dev/null and b/gcp/ilbnh-mig/images/deployment.png differ diff --git a/gcp/ilbnh-mig/images/diagram.svg b/gcp/ilbnh-mig/images/diagram.svg new file mode 100644 index 00000000..d68679f4 --- /dev/null +++ b/gcp/ilbnh-mig/images/diagram.svg @@ -0,0 +1,805 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Produced by OmniGraffle 7.9.4 + 2019-11-05 23:49:25 +0000 + + + ilb-as-next-hop + + Layer 1 + + + + + + + + + + Configuration + + + + + + Connectivity + + + + + + + + + + + + GCP Zone + + + + + Page-1 + + Shape + + + + Shape + + + + Shape + + + + Shape + + + Oval + + + + + GCP logo + + Fill-3 + + + + Fill-5 + + + + Fill-7 + + + + Fill-8 + + + + Fill-9 + + + + Fill-10 + + + + Fill-11 + + + + Fill-12 + + + + Fill-13 + + + + Fill-14 + + + + Fill-15 + + + + Fill-16 + + + + Fill-17 + + + + Fill-18 + + + + Fill-19 + + + + Fill-20 + + + + Fill-21 + + + + Fill-22 + + + + Fill-23 + + + + + + zone external - grey + + + Project + + + + zone internal - blue + + + + VPC network: testing + + + + + Fill-7 + + + + + Fill-10 + + + + + Fill-1 + + + + Fill-4 + + + + Fill-7 + + + + Fill-9 + + + + Fill-10 + + + + Fill-11 + + + + Fill-12 + + + + Fill-13 + + + + Fill-14 + + + + Fill-15 + + + + + zone internal - green + + + + Region: us-west1 + + + + zone internal - purple + + + + Subnet: 10.30.1.0/24 + + + + + + + + + + + + + - Destination: 10.50.1.0/24 + - Next-hop-ilb = fr-ilb + + + + + + Static routes + + + + Cloud Routes + + Fill-6 + + + + Fill-8 + + + + Fill-10 + + + + + + + + + + + + + + + + - Destination: 10.30.1.0/24 + - Next hop: virtual network + + + + + Subnet routes + + + + Cloud Routes + + Fill-6 + + + + Fill-8 + + + + Fill-10 + + + + + + + + + + + Shuffle + + + + + VPC Routing + + + + + + + + + + + + + + Forwarding rule name : fr-llb1 + IP address: 10.30.1.99 + + + + + Internal Forwarding Rule + + + + + + Fill-7 + + + + + Fill-10 + + + + + Fill-1 + + + + Fill-4 + + + + Fill-7 + + + + Fill-9 + + + + Fill-10 + + + + Fill-11 + + + + Fill-12 + + + + Fill-13 + + + + Fill-14 + + + + Fill-15 + + + + + zone internal - blue + + + + VPC network:production + + + + + Fill-7 + + + + + Fill-10 + + + + + Fill-1 + + + + Fill-4 + + + + Fill-7 + + + + Fill-9 + + + + Fill-10 + + + + Fill-11 + + + + Fill-12 + + + + Fill-13 + + + + Fill-14 + + + + Fill-15 + + + + + + + + + + + + + + - Destination: 10.50.1.0/24 + - Next hop: virtual network + + + + + + Subnet routes + + + + Cloud Routes + + Fill-6 + + + + Fill-8 + + + + Fill-10 + + + + + + + + + + + + Shuffle + + + + + VPC Routing + + + + + zone internal - green + + + + Region: us-west1 + + + + zone internal - purple + + + + Subnet: 10.50.1.0/24 + + + + zone internal - white + + + + Managed Instance Group + third-party-template + + + + + + + + + + Regional Internal + Backend Service + + + + + + + + + + + Source: 10.30.1.100 + Destination: 10.50.1.100 + + + + + + + + + + + Source address translated + Firewall VM performs SNAT + Source: 10.50.1.x + Destination: 10.50.1.100 + + + + + + nic0 + 10.30.1.x + + + + + nic1 + 10.50.1.x + + + + + + + + + + + + + 10.50.1.100 + + + + + production-vm + + + + Compute Engine + + Fill-1 + + + + Fill-4 + + + + Fill-7 + + + + Fill-9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Stroke-21 + + + + Stroke-22 + + + + + + + + + can_ip_forward: + True + + + + + Firewall + Instances + + + + Compute Engine + + Fill-1 + + + + Fill-4 + + + + Fill-7 + + + + Fill-9 + + + + + + + + + + + + + + + 10.30.1.100 + + + + + + testing-vm + + + + Compute Engine + + Fill-1 + + + + Fill-4 + + + + Fill-7 + + + + Fill-9 + + + + + + + + + + + + + + + diff --git a/gcp/ilbnh-mig/images/directory.png b/gcp/ilbnh-mig/images/directory.png new file mode 100644 index 00000000..8317ff94 Binary files /dev/null and b/gcp/ilbnh-mig/images/directory.png differ diff --git a/gcp/ilbnh-mig/images/fwlogs.png b/gcp/ilbnh-mig/images/fwlogs.png new file mode 100644 index 00000000..52ea690c Binary files /dev/null and b/gcp/ilbnh-mig/images/fwlogs.png differ diff --git a/gcp/ilbnh-mig/modules/gcp_bootstrap/main.tf b/gcp/ilbnh-mig/modules/gcp_bootstrap/main.tf new file mode 100644 index 00000000..a93e7956 --- /dev/null +++ b/gcp/ilbnh-mig/modules/gcp_bootstrap/main.tf @@ -0,0 +1,85 @@ +locals { + bucket_name = join("", [var.bucket_name, random_string.randomstring.result]) +} +resource "random_string" "randomstring" { + length = 25 + min_lower = 15 + min_numeric = 10 + special = false +} + +resource "google_storage_bucket" "bootstrap" { + name = local.bucket_name + force_destroy = true +} + +resource "google_storage_bucket_object" "config_full" { + count = length(var.config) > 0 ? length(var.config) : "0" + name = "config/${element(var.config, count.index)}" + source = "${var.file_location}${element(var.config, count.index)}" + bucket = google_storage_bucket.bootstrap.name +} + +resource "google_storage_bucket_object" "content_full" { + count = length(var.content) > 0 ? length(var.content) : "0" + name = "content/${element(var.content, count.index)}" + source = "${var.file_location}${element(var.content, count.index)}" + bucket = google_storage_bucket.bootstrap.name +} + +resource "google_storage_bucket_object" "license_full" { + count = length(var.license) > 0 ? length(var.license) : "0" + name = "license/${element(var.license, count.index)}" + source = "${var.file_location}${element(var.license, count.index)}" + bucket = google_storage_bucket.bootstrap.name +} + +resource "google_storage_bucket_object" "software_full" { + count = length(var.software) > 0 ? length(var.software) : "0" + name = "software/${element(var.software, count.index)}" + source = "${var.file_location}${element(var.software, count.index)}" + bucket = google_storage_bucket.bootstrap.name +} + +resource "google_storage_bucket_object" "config_empty" { + count = length(var.config) == 0 ? 1 : 0 + name = "config/" + content = "config/" + bucket = google_storage_bucket.bootstrap.name +} + +resource "google_storage_bucket_object" "content_empty" { + count = length(var.content) == 0 ? 1 : 0 + name = "content/" + content = "content/" + bucket = google_storage_bucket.bootstrap.name +} + +resource "google_storage_bucket_object" "license_empty" { + count = length(var.license) == 0 ? 1 : 0 + name = "license/" + content = "license/" + bucket = google_storage_bucket.bootstrap.name +} + +resource "google_storage_bucket_object" "software_empty" { + count = length(var.software) == 0 ? 1 : 0 + name = "software/" + content = "software/" + bucket = google_storage_bucket.bootstrap.name +} + +resource "null_resource" "dependency_setter" { + depends_on = [ + google_storage_bucket.bootstrap, + google_storage_bucket_object.config_full, + google_storage_bucket_object.content_full, + google_storage_bucket_object.license_full, + google_storage_bucket_object.software_full, + google_storage_bucket_object.config_empty, + google_storage_bucket_object.content_empty, + google_storage_bucket_object.license_empty, + google_storage_bucket_object.software_empty, + ] +} + diff --git a/gcp/ilbnh-mig/modules/gcp_bootstrap/outputs.tf b/gcp/ilbnh-mig/modules/gcp_bootstrap/outputs.tf new file mode 100644 index 00000000..ef7f162d --- /dev/null +++ b/gcp/ilbnh-mig/modules/gcp_bootstrap/outputs.tf @@ -0,0 +1,8 @@ +output completion { + value = null_resource.dependency_setter.id +} + +output bucket_name { + value = google_storage_bucket.bootstrap.name +} + diff --git a/gcp/ilbnh-mig/modules/gcp_bootstrap/variables.tf b/gcp/ilbnh-mig/modules/gcp_bootstrap/variables.tf new file mode 100644 index 00000000..0db2b8fd --- /dev/null +++ b/gcp/ilbnh-mig/modules/gcp_bootstrap/variables.tf @@ -0,0 +1,24 @@ +variable bucket_name { +} + +variable file_location { +} + +variable config { + type = list(string) + default = [] +} + +variable content { + type = list(string) + default = [] +} + +variable license { + type = list(string) + default = [] +} + +variable software { + default = [] +} diff --git a/gcp/ilbnh-mig/modules/ilbnh/main.tf b/gcp/ilbnh-mig/modules/ilbnh/main.tf new file mode 100644 index 00000000..e3491df0 --- /dev/null +++ b/gcp/ilbnh-mig/modules/ilbnh/main.tf @@ -0,0 +1,27 @@ +#----------------------------------------------------------------------------------------------- +# Create the internal load balancers, one for the testing network and one for the production network. +# This resource will destroy (potentially immediately) after null_resource.next +resource "google_compute_region_backend_service" "default" { + provider = "google-beta" + name = var.name + project = var.project_id + load_balancing_scheme = "INTERNAL" + health_checks = var.health_checks + region = var.region + network = var.network_uri + + backend { + group = var.group + } +} + +resource "google_compute_forwarding_rule" "default" { + name = "fr-${var.name}" + region = var.region + load_balancing_scheme = "INTERNAL" + backend_service = google_compute_region_backend_service.default.id + all_ports = var.all_ports + network = var.network + subnetwork = var.subnetwork + ip_address = var.ip_address +} \ No newline at end of file diff --git a/gcp/ilbnh-mig/modules/ilbnh/outputs.tf b/gcp/ilbnh-mig/modules/ilbnh/outputs.tf new file mode 100644 index 00000000..d99cc408 --- /dev/null +++ b/gcp/ilbnh-mig/modules/ilbnh/outputs.tf @@ -0,0 +1,3 @@ +output forwarding_rule { + value = google_compute_forwarding_rule.default.self_link +} \ No newline at end of file diff --git a/gcp/ilbnh-mig/modules/ilbnh/variables.tf b/gcp/ilbnh-mig/modules/ilbnh/variables.tf new file mode 100644 index 00000000..585f8276 --- /dev/null +++ b/gcp/ilbnh-mig/modules/ilbnh/variables.tf @@ -0,0 +1,41 @@ +variable project_id { +} + +variable region { +} + +variable name { +} + +variable health_checks { + type = list(string) + default = [] +} + +variable group { +} + +variable subnetwork { +} + +variable ip_address { + default = null +} + +variable ip_protocol { + default = "TCP" +} +variable all_ports { + type = bool +} +variable ports { + type = list(string) + default = [] +} + +variable network { + default = null +} + +variable network_uri { +} \ No newline at end of file diff --git a/gcp/ilbnh-mig/modules/vm/main.tf b/gcp/ilbnh-mig/modules/vm/main.tf new file mode 100644 index 00000000..fff23b2e --- /dev/null +++ b/gcp/ilbnh-mig/modules/vm/main.tf @@ -0,0 +1,34 @@ +resource "google_compute_instance" "default" { + count = length(var.names) + name = element(var.names, count.index) + machine_type = var.machine_type + zone = element(var.zones, count.index) + can_ip_forward = false + allow_stopping_for_update = true + metadata_startup_script = var.startup_script + + metadata = { + serial-port-enable = true + ssh-keys = var.ssh_key + } + + network_interface { + dynamic "access_config" { + for_each = var.server_public_ip ? [""] : [] + content {} + } + subnetwork = element(var.subnetworks, count.index) + network_ip = element(var.server_ips, count.index) + + } + + boot_disk { + initialize_params { + image = var.image + } + } + + service_account { + scopes = var.scopes + } +} \ No newline at end of file diff --git a/gcp/ilbnh-mig/modules/vm/outputs.tf b/gcp/ilbnh-mig/modules/vm/outputs.tf new file mode 100644 index 00000000..75856670 --- /dev/null +++ b/gcp/ilbnh-mig/modules/vm/outputs.tf @@ -0,0 +1,7 @@ +output vm_names { + value = google_compute_instance.default.*.name +} + +output vm_self_link { + value = google_compute_instance.default.*.self_link +} \ No newline at end of file diff --git a/gcp/ilbnh-mig/modules/vm/variables.tf b/gcp/ilbnh-mig/modules/vm/variables.tf new file mode 100644 index 00000000..76b51bf5 --- /dev/null +++ b/gcp/ilbnh-mig/modules/vm/variables.tf @@ -0,0 +1,44 @@ +variable names { + type = list(string) +} + +variable machine_type { +} + +variable zones { + type = list(string) +} +variable ssh_key { + default = "" +} +variable image { +} + +variable subnetworks { + type = list(string) +} + +variable server_ips { + type = list(string) +} + +variable scopes { + type = list(string) + + default = [ + "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", + ] +} + +variable startup_script { + default = "" +} + +variable server_public_ip { + type = bool + default = false +} + diff --git a/gcp/ilbnh-mig/modules/vmseries/main.tf b/gcp/ilbnh-mig/modules/vmseries/main.tf new file mode 100644 index 00000000..0b78dd00 --- /dev/null +++ b/gcp/ilbnh-mig/modules/vmseries/main.tf @@ -0,0 +1,84 @@ +resource "google_compute_instance_template" "vmseries" { + name = "vmseries-template" + description = "This template is used to create firewall instances." + instance_description = "VM-Series for ILBNH" + region = var.region + machine_type = var.machine_type + min_cpu_platform = var.cpu_platform + can_ip_forward = true + tags = var.tags + + scheduling { + automatic_restart = true + on_host_maintenance = "MIGRATE" + } + + metadata = { + mgmt-interface-swap = var.mgmt_interface_swap + vmseries-bootstrap-gce-storagebucket = var.bootstrap_bucket + serial-port-enable = true + ssh-keys = var.ssh_key + } + + service_account { + scopes = var.scopes + } + + network_interface { + + dynamic "access_config" { + for_each = var.nic0_public_ip ? [""] : [] + content {} + } + subnetwork = var.subnetworks[0] + } + + network_interface { + dynamic "access_config" { + for_each = var.nic1_public_ip ? [""] : [] + content {} + } + subnetwork = var.subnetworks[1] + } + + network_interface { + dynamic "access_config" { + for_each = var.nic2_public_ip ? [""] : [] + content {} + } + subnetwork = var.subnetworks[2] + } + + network_interface { + dynamic "access_config" { + for_each = var.nic3_public_ip ? [""] : [] + content {} + } + subnetwork = var.subnetworks[3] + } + + disk { + source_image = var.image + type = var.disk_type + } + + lifecycle { + create_before_destroy = "true" + } +} + +resource "google_compute_region_instance_group_manager" "vmseries_rigm" { + name = "vmseries-rigm" + base_instance_name = var.base_name + region = var.region + target_size = var.target_size + + version { + instance_template = google_compute_instance_template.vmseries.self_link + } + + named_port { + name = "http" + port = "80" + } +} \ No newline at end of file diff --git a/gcp/ilbnh-mig/modules/vmseries/outputs.tf b/gcp/ilbnh-mig/modules/vmseries/outputs.tf new file mode 100644 index 00000000..11bd3b53 --- /dev/null +++ b/gcp/ilbnh-mig/modules/vmseries/outputs.tf @@ -0,0 +1,3 @@ +output vmseries_rigm { + value = google_compute_region_instance_group_manager.vmseries_rigm.instance_group +} \ No newline at end of file diff --git a/gcp/ilbnh-mig/modules/vmseries/variables.tf b/gcp/ilbnh-mig/modules/vmseries/variables.tf new file mode 100644 index 00000000..271a7b55 --- /dev/null +++ b/gcp/ilbnh-mig/modules/vmseries/variables.tf @@ -0,0 +1,121 @@ +variable networks { + type = list(string) +} + +variable subnetworks { + type = list(string) +} + +variable base_name { +} + +variable machine_type { +} + +variable region { +} + +variable zones { + type = list(string) +} + +variable cpu_platform { + default = "Intel Broadwell" +} +variable disk_type { + default = "pd-ssd" +} +variable bootstrap_bucket { + default = "" +} + +variable ssh_key { + default = "" +} + +variable public_lb_create { + default = false +} + +variable target_size { + default = "1" +} + +variable scopes { + type = list(string) + + default = [ + "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", + ] +} + +variable image { +} + +variable tags { + type = list(string) + default = [] +} + +variable create_instance_group { + type = bool + default = false +} + +variable instance_group_names { + type = list(string) + default = ["vmseries-instance-group"] +} + +variable dependencies { + type = list(string) + default = [] +} + +variable mgmt_interface_swap { + default = "" +} + +variable nic0_ip { + type = list(string) + default = [""] +} + +variable nic1_ip { + type = list(string) + default = [""] +} + +variable nic2_ip { + type = list(string) + default = [""] +} + +variable nic3_ip { + type = list(string) + default = [""] +} + +variable nic0_public_ip { + type = bool + default = false +} + +variable nic1_public_ip { + type = bool + default = false +} + +variable nic2_public_ip { + type = bool + default = false +} + +variable nic3_public_ip { + type = bool + default = false +} \ No newline at end of file diff --git a/gcp/ilbnh-mig/modules/vpc/main.tf b/gcp/ilbnh-mig/modules/vpc/main.tf new file mode 100644 index 00000000..6c681d08 --- /dev/null +++ b/gcp/ilbnh-mig/modules/vpc/main.tf @@ -0,0 +1,25 @@ +resource "google_compute_network" "default" { + name = var.vpc + delete_default_routes_on_create = var.delete_default_route + auto_create_subnetworks = false +} + +resource "google_compute_subnetwork" "default" { + name = var.subnet + ip_cidr_range = var.cidr + region = var.region + network = google_compute_network.default.self_link +} + +resource "google_compute_firewall" "default" { + count = length(var.allowed_sources) != 0 ? 1 : 0 + name = "${google_compute_network.default.name}-ingress" + network = google_compute_network.default.self_link + direction = "INGRESS" + source_ranges = var.allowed_sources + + allow { + protocol = var.allowed_protocol + ports = var.allowed_ports + } +} \ No newline at end of file diff --git a/gcp/ilbnh-mig/modules/vpc/outputs.tf b/gcp/ilbnh-mig/modules/vpc/outputs.tf new file mode 100644 index 00000000..dbf7ed78 --- /dev/null +++ b/gcp/ilbnh-mig/modules/vpc/outputs.tf @@ -0,0 +1,29 @@ +output network_self_link { +# value = google_compute_network.default.*.self_link + value = google_compute_network.default.self_link +} + +output subnetwork_id { + value = google_compute_subnetwork.default.*.id +} + +output subnetwork_name { + value = google_compute_subnetwork.default.*.name +} + +output subnetwork_self_link { +# value = google_compute_subnetwork.default.*.self_link + value = google_compute_subnetwork.default.self_link +} + +output vpc_name { + value = google_compute_network.default.*.name +} + +output vpc_id { + value = google_compute_network.default.*.id[0] +} + +output vpc_self_link { + value = google_compute_network.default.*.self_link[0] +} \ No newline at end of file diff --git a/gcp/ilbnh-mig/modules/vpc/variables.tf b/gcp/ilbnh-mig/modules/vpc/variables.tf new file mode 100644 index 00000000..04407a0d --- /dev/null +++ b/gcp/ilbnh-mig/modules/vpc/variables.tf @@ -0,0 +1,29 @@ +variable vpc { +} + +variable subnet { +} + +variable cidr { +} + +variable region { +} + +variable allowed_sources { + type = list(string) + default = [] +} + +variable allowed_protocol { + default = "all" +} + +variable allowed_ports { + type = list(string) + default = [] +} + +variable delete_default_route { + default = "false" +} \ No newline at end of file diff --git a/gcp/ilbnh-mig/project.tf b/gcp/ilbnh-mig/project.tf new file mode 100644 index 00000000..a65b533f --- /dev/null +++ b/gcp/ilbnh-mig/project.tf @@ -0,0 +1,15 @@ +terraform { + required_version = ">= 0.12" +} + +provider "google" { + credentials = var.auth_file + project = var.project_id + region = var.region +} + +provider "google-beta" { + version = "> 2.50.0" +} + +data "google_compute_zones" "available" {} \ No newline at end of file diff --git a/gcp/ilbnh-mig/scripts/showheaders.php b/gcp/ilbnh-mig/scripts/showheaders.php new file mode 100644 index 00000000..19c37318 --- /dev/null +++ b/gcp/ilbnh-mig/scripts/showheaders.php @@ -0,0 +1,62 @@ + + SOURCE & DESTINATION ADDRESSES +
'; +echo ''. "INTERVAL" .': '. $time .'
'; +$localIPAddress = getHostByName(getHostName()); +$sourceIPAddress = getRealIpAddr(); +echo ''. "SOURCE IP" .': '. $sourceIPAddress .'
'; +echo ''. "LOCAL IP" .': '. $localIPAddress .'
'; + +$vm_name = gethostname(); +echo ''. "VM NAME" .': '. $vm_name .'
'; +echo ''. '
'; +echo ' + HEADER INFORMATION +
'; +/* All $_SERVER variables prefixed with HTTP_ are the HTTP headers */ +foreach ($_SERVER as $header => $value) { + if (substr($header, 0, 5) == 'HTTP_') { + /* Strip the HTTP_ prefix from the $_SERVER variable, what remains is the header */ + $clean_header = strtolower(substr($header, 5, strlen($header))); + + /* Replace underscores by the dashes, as the browser sends them */ + $clean_header = str_replace('_', '-', $clean_header); + + /* Cleanup: standard headers are first-letter uppercase */ + $clean_header = ucwords($clean_header, " \t\r\n\f\v-"); + + /* And show'm */ + echo ''. $header .': '. $value .'
'; + } +} +?> diff --git a/gcp/ilbnh-mig/scripts/webserver-startup.sh b/gcp/ilbnh-mig/scripts/webserver-startup.sh new file mode 100644 index 00000000..a19aefe9 --- /dev/null +++ b/gcp/ilbnh-mig/scripts/webserver-startup.sh @@ -0,0 +1,9 @@ +#!/bin/bash +until sudo apt-get update; do echo "Retrying"; sleep 2; done +until sudo apt-get install -y php; do echo "Retrying"; sleep 2; done +until sudo apt-get install -y apache2; do echo "Retrying"; sleep 2; done +until sudo apt-get install -y libapache2-mod-php; do echo "Retrying"; sleep 2; done +until sudo rm -f /var/www/html/index.html; do echo "Retrying"; sleep 2; done +until sudo wget -O /var/www/html/index.php https://raw.githubusercontent.com/wwce/terraform/master/gcp/adv_peering_4fw_2spoke/scripts/showheaders.php; do echo "Retrying"; sleep 2; done +until sudo systemctl restart apache2; do echo "Retrying"; sleep 2; done +until sudo apt-get autoremove -y --purge sshguard; do echo "Retrying"; sleep 2; done \ No newline at end of file diff --git a/gcp/ilbnh-mig/servers.tf b/gcp/ilbnh-mig/servers.tf new file mode 100644 index 00000000..fe563ba5 --- /dev/null +++ b/gcp/ilbnh-mig/servers.tf @@ -0,0 +1,29 @@ +#----------------------------------------------------------------------------------------------- +# Create N webservers in one subnet. N is determined by the number of hostnames in the list +module "server1" { + source = "./modules/vm/" + names = var.server1_vms + zones = [data.google_compute_zones.available.names[0]] + subnetworks = [module.vpc0.subnetwork_self_link] + server_ips = var.server1_ips + server_public_ip = var.server_public_ip + machine_type = var.server_size + image = var.server_image + ssh_key = fileexists(var.public_key_path) ? "${var.server_user}:${file(var.public_key_path)}" : "" + startup_script = file("${path.module}/scripts/webserver-startup.sh") +} + +#----------------------------------------------------------------------------------------------- +# Create X webservers in another subnet. X is determined by the number of hostnames in the list +module "server2" { + source = "./modules/vm/" + names = var.server2_vms + zones = [data.google_compute_zones.available.names[0]] + subnetworks = [module.vpc2.subnetwork_self_link] + server_ips = var.server2_ips + server_public_ip = var.server_public_ip + machine_type = var.server_size + image = var.server_image + ssh_key = fileexists(var.public_key_path) ? "${var.server_user}:${file(var.public_key_path)}" : "" + startup_script = file("${path.module}/scripts/webserver-startup.sh") +} \ No newline at end of file diff --git a/gcp/ilbnh-mig/terraform.tfvars b/gcp/ilbnh-mig/terraform.tfvars new file mode 100644 index 00000000..31dd7687 --- /dev/null +++ b/gcp/ilbnh-mig/terraform.tfvars @@ -0,0 +1,48 @@ +project_id = "" +auth_file = "" +public_key_path = "" # Your SSH Key + +#fw_panos = "byol-904" # Uncomment for PAN-OS 9.0.4 - BYOL +fw_panos = "bundle1-904" # Uncomment for PAN-OS 9.0.4 - PAYG Bundle 1 +#fw_panos = "bundle2-904" # Uncomment for PAN-OS 9.0.4 - PAYG Bundle 2 + + +#------------------------------------------------------------------- +region = "us-central1" + +vpc0 = "testing" +vpc0_subnet = "testing-subnet" +vpc0_cidr = "10.30.1.0/24" + +vpc1 = "mgmt" +vpc1_subnet = "mgmt-subnet" +vpc1_cidr = "10.60.1.0/24" + +vpc2 = "production" +vpc2_subnet = "production-subnet" +vpc2_cidr = "10.50.1.0/24" + +vpc3 = "production2" +vpc3_subnet = "production2-subnet" +vpc3_cidr = "10.40.1.0/24" + +fw_base_name = "vmseries" +fw_machine_type = "n1-standard-4" +target_size = "1" + +mgmt_sources = ["0.0.0.0/0"] +health_check_port = "22" +all_ports = true + +server_user = "demo" +server_size = "f1-micro" +server_image = "ubuntu-os-cloud/ubuntu-1604-lts" +server_public_ip = true +server1_vms = ["testing-vm"] +server1_ips = ["10.30.1.100"] + +server2_vms = ["production-vm"] +server2_ips = ["10.50.1.100"] + +ilb1_ip = "10.30.1.99" +ilb2_ip = "10.50.1.99" diff --git a/gcp/ilbnh-mig/variables.tf b/gcp/ilbnh-mig/variables.tf new file mode 100644 index 00000000..98a46495 --- /dev/null +++ b/gcp/ilbnh-mig/variables.tf @@ -0,0 +1,122 @@ +variable project_id { + description = "GCP Project ID" +} + +variable auth_file { + description = "GCP Project auth file" + default = "" +} + +variable region { +} + +variable fw_panos { + description = "VM-Series license and PAN-OS (ie: bundle1-814, bundle2-814, or byol-814)" +} + +variable fw_image { + default = "https://www.googleapis.com/compute/v1/projects/paloaltonetworksgcp-public/global/images/vmseries" +} + +variable fw_base_name { +} + +variable target_size { +} + +variable fw_machine_type { +} + +variable mgmt_sources { + type = list(string) +} + +variable health_check_port { + description = "Port the ILB will health check" + default = "22" +} + +variable all_ports { + description = "Enable all ports on the ILB" + default = true +} +variable vpc1 { +} + +variable vpc1_subnet { +} + +variable vpc1_cidr { +} + +variable vpc0 { +} + +variable vpc0_subnet { +} + +variable vpc0_cidr { +} + +variable vpc2 { +} + +variable vpc2_subnet { +} + +variable vpc2_cidr { +} + +variable vpc3 { +} + +variable vpc3_subnet { +} + +variable vpc3_cidr { +} + +variable server1_vms { + type = list(string) +} + +variable server1_ips { + type = list(string) +} + +variable server2_vms { + type = list(string) +} + +variable server_user { + description = "SSH user for Linux VM" +} + +variable server2_ips { + type = list(string) +} + +variable server_size { + description = "Machine size for the server VMs" +} + +variable server_image { + description = "OS image for server installation" +} + +variable server_public_ip { + description = "Should we assign a public IP to the server" + default = false +} + +variable public_key_path { + description = "Local path to public SSH key. If you do not have a public key, run >> ssh-keygen -f ~/.ssh/demo-key -t rsa -C admin" +} + +variable ilb1_ip { + description = "IP address for ILB1" +} + +variable ilb2_ip { + description = "IP address for ILB2" +}