{"id":19925697,"url":"https://github.com/paloaltonetworks/google-cloud-vmseries-ha-tutorial","last_synced_at":"2025-05-03T08:31:18.846Z","repository":{"id":182338143,"uuid":"628079399","full_name":"PaloAltoNetworks/google-cloud-vmseries-ha-tutorial","owner":"PaloAltoNetworks","description":"Terraform tutorial detailing how to deploy Active/Passive VM-Series with session sync in Google Cloud. ","archived":false,"fork":false,"pushed_at":"2024-07-12T00:26:42.000Z","size":3080,"stargazers_count":3,"open_issues_count":1,"forks_count":4,"subscribers_count":8,"default_branch":"main","last_synced_at":"2024-07-12T17:02:20.276Z","etag":null,"topics":["active-passive","gcp","google-cloud","google-cloud-platform","highavailability","load-balancer","pan-os","panos","terraform","vm-series","vmseries"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PaloAltoNetworks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-14T21:35:46.000Z","updated_at":"2024-07-12T00:26:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"035a1e02-98ed-4a22-bcec-6bb5dad7d0d0","html_url":"https://github.com/PaloAltoNetworks/google-cloud-vmseries-ha-tutorial","commit_stats":null,"previous_names":["paloaltonetworks/google-cloud-vmseries-ha-tutorial"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaloAltoNetworks%2Fgoogle-cloud-vmseries-ha-tutorial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaloAltoNetworks%2Fgoogle-cloud-vmseries-ha-tutorial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaloAltoNetworks%2Fgoogle-cloud-vmseries-ha-tutorial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaloAltoNetworks%2Fgoogle-cloud-vmseries-ha-tutorial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PaloAltoNetworks","download_url":"https://codeload.github.com/PaloAltoNetworks/google-cloud-vmseries-ha-tutorial/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224356176,"owners_count":17297684,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["active-passive","gcp","google-cloud","google-cloud-platform","highavailability","load-balancer","pan-os","panos","terraform","vm-series","vmseries"],"created_at":"2024-11-12T22:23:47.420Z","updated_at":"2024-11-12T22:23:47.880Z","avatar_url":"https://github.com/PaloAltoNetworks.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# VM-Series Active/Passive HA on Google Cloud\n\nThis tutorial creates a pair of Active/Passive VM-Series firewalls on Google Cloud.  This deployment model provides solutions for the following key use-cases:\n\n* Maintaining session continuity through stateful failover between the VM-Series firewalls.\n* Terminating IPsec tunnels directly to the VM-Series firewall through the external load balancer.\n* Preserving the original client IP address for internet inbound traffic to internal applications protected by the VM-Series firewalls.\n\nThe autoscale architecture is recommended in most use-cases.  Please see [VM-Series on Google Cloud](https://cloud.google.com/architecture/partners/palo-alto-networks-ngfw) for more information on VM-Series deployment models.\n\n\n## Architecture\n\nIn this model, each VM-Series firewall belongs to an unmanaged instance group. Only the primary VM-Series firewall receives network traffic from Google Cloud load balancers. The health check configured on the load balancers determines the HA state of the primary VM-Series firewall. If the health check fails on the primary VM-Series firewall, the load balancers carry the active sessions to the secondary VM-Series firewall. At that point, the secondary VM-Series firewall becomes the primary firewall.\n\n\u003e [!NOTE]\n\u003e During a failure event, sessions are carried between the firewalls via [connection tracking](https://cloud.google.com/load-balancing/docs/network/networklb-backend-service#tracking-mode) on the load balancers.\n\n\n![Overview Diagram](images/diagram.png)\n\n\n\n\u003ctable border=\"1\"\u003e \u003c!-- Adding a border for visibility --\u003e\n    \u003ctr\u003e\n        \u003ctd colspan=\"2\"\u003e\u003cb\u003eResources\u003c/b\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003eVM-Series\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003e\n            \u003cul\u003e\n                \u003cli\u003e2 x VM-Series are deployed to separate zones within a region.\u003c/li\u003e\n                \u003cli\u003eEach firewall belongs to an unmanaged instance group.\u003c/li\u003e\n                \u003cli\u003eEach instance group is a backend service of an internal load balancer.\u003c/li\u003e\n            \u003c/ul\u003e\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003eExternal LB\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003e\n            An external pass-through load balancer with two forwarding rules:\n            \u003cul\u003e\n                \u003cli\u003e\u003cb\u003eRule 1:\u003c/b\u003e Forwards internet inbound traffic to the VM-Series untrust interface.\u003c/li\u003e\n                \u003cli\u003e\u003cb\u003eRule 2:\u003c/b\u003e Forwards outbound traffic from the untrust interfaces to the internet.\u003c/li\u003e\n            \u003c/ul\u003e\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003eInternal LB\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003e\n            An internal pass-through load balancer with a single forwarding rule. Traffic from workload networks use the load balancer's forwarding rule as the next hop within their VPC route table.\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd colspan=\"2\"\u003e\u003cb\u003eVPC Networks\u003c/b\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003eMgmt VPC\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003e\n            Contains the VM-Series MGT interfaces. This interface also serves as the HA1 interface.\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003eHA2 VPC\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003e\n            Contains the VM-Series HA2 interfaces.\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003eUntrust VPC\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003e\n            Serves as the internet gateway for resources within the trust VPC.\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003eTrust VPC\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003e\n            Contains the workloads protected by the VM-Series. This VPC can also serve as a hub network with multiple VPCs peered to it.\n        \u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/table\u003e\n\n\n\n\u003e [!IMPORTANT]\n\u003e After deployment, the load balancer's health checks will only pass on the **active** VM-Series firewall.  This is because the dataplane of the passive firewall is inactive and is unable to pass the health checks.  During a failure event, the passive firewall becomes active and the health checks will pass. \n\n## Prepare for deployment\n\n1. Enable the required APIs, generate an SSH key, and clone the repository. \n\n    ```\n    gcloud services enable compute.googleapis.com\n    ssh-keygen -f ~/.ssh/vmseries-tutorial -t rsa\n    git clone https://github.com/PaloAltoNetworks/google-cloud-vmseries-ha-tutorial\n    cd google-cloud-vmseries-ha-tutorial\n    ```\n\n2. Create a `terraform.tfvars` file.\n\n    ```\n    cp terraform.tfvars.example terraform.tfvars\n    ```\n\n3. Edit the `terraform.tfvars` file and set values for the following variables:\n\n    | Variable      | Description                                    |\n    |-----------------|----------------------------------------------------------------------------------|\n    | `project_id `     | Set to your Google Cloud deployment project.                                     |\n    | `public_key_path` | Set to match the full path you created previously.                               |\n    | `mgmt_allow_ips`  | Set to a list of IPv4 ranges that can access the VM-Series management interface. |\n    | `prefix`          | (Optional) If set, this string will be prepended to the created resources.       |\n    | `vmseries_image_name`          | (Optional) Defines the VM-Series image to deploy.  A full list of images can be found [here](https://docs.paloaltonetworks.com/vm-series/11-0/vm-series-deployment/set-up-the-vm-series-firewall-on-google-cloud-platform/deploy-vm-series-on-gcp/use-custom-templates-or-the-gcloud-cli-to-deploy-the-vm-series-firewall).       |\n\n4. (Optional) If you are using BYOL image (i.e. `vmseries-flex-byol-*`), the license can be applied during deployment by adding your VM-Series authcode to `bootstrap_files/authcodes`.\n5. Save your `terraform.tfvars` file.\n\n\n## Deployment\nWhen no further changes are necessary in the configuration, deploy the resources:\n\n1. Initialize and apply the Terraform plan.  \n\n    ```\n    terraform init\n    terraform apply\n    ```\n\n2. Enter `yes` to start the deployment.\n   \n3. After all the resources are created, Terraform displays the following message:\n\n    ```\n    Apply complete!\n\n    Outputs:\n\n    EXTERNAL_LB_IP     = \"ssh paloalto@1.1.1.1 -i ~/.ssh/vmseries-tutorial\"\n    EXTERNAL_LB_URL    = \"https://1.1.1.1\"\n    VMSERIES_ACTIVE    = \"https://2.2.2.2\"\n    VMSERIES_PASSIVE   = \"https://3.3.3.3\"\n    VMSERIES_SSH       = \"ssh admin@1.1.1.1 -i ~/.ssh/vmseries-tutorial\" \n    ```\n\n## Access the Active VM-Series Firewall\n\nTo access the VM-Series user interface, a password must be set for the `admin` user.\n\n\u003e [!CAUTION]  \n\u003e After the apply completes, it may ~10 minutes for the VM-Series to become available.\n\n1. SSH to the *active* VM-Series firewall using the `VMSERIES_SSH` output value. \n\n    ```\n    ssh admin@1.1.1.1 -i ~/.ssh/vmseries-tutorial\"\n    ```\n\n2. On the *active* VM-Series, set a password for the `admin` username. \n\n    ```\n    configure\n    set mgt-config users admin password\n    ```\n\n3. Commit the changes.\n\n    ```\n    commit\n    ```\n\n4. Enter `exit` twice to terminate the session.\n\n\n## Test the Deployment\n\nYou can now test the deployment by accessing the `workload-vm` that resides in the trust VPC network.  All of the `workload-vm` traffic is routed directly through the VM-Series HA pair. \n\n1. Use the output `EXTERNAL_LB_URL` to access the web service on the `workload-vm` through the VM-Series firewall.\n\n    \u003cimg src=\"images/web.png\" width=\"500\"\u003e\n\n2. Use the output `EXTERNAL_LB_SSH` to open an SSH session through the VM-Series to the `workload-vm`.  \n    ```\n    ssh paloalto@1.1.1.1 -i ~/.ssh/vmseries-tutorial\n    ```\n\n\u003e [!NOTE]\n\u003e The address within `EXTERNAL_LB_URL` \u0026 `EXTERNAL_LB_SSH` is the `inbound` forwarding rule on the external load balancer.  The VM-Series inspects and translates the request from the `inbound` forwarding rule to the `workload-vm`. \n\n\n3. On the workload VM, run a preloaded script to test the failover mechanism across the VM-Series firewalls.\n\n    ```\n    /network-check.sh\n    ```\n\n    You will see output like this where `x.x.x.x` is the IP address is `EXTERNAL_LB_IP` address.\n    ```\n    Wed Mar 12 16:40:18 UTC 2023 -- Online -- Source IP = x.x.x.x\n    Wed Mar 12 16:40:19 UTC 2023 -- Online -- Source IP = x.x.x.x\n    Wed Mar 12 16:40:20 UTC 2023 -- Online -- Source IP = x.x.x.x\n    Wed Mar 12 16:40:21 UTC 2023 -- Online -- Source IP = x.x.x.x\n    ```\n\n\u003e [!NOTE]\n\u003e Egress traffic from the `workload-vm` is routed to the internal load balancer's forwarding rule.  The VM-Series inspects and translates the request to the `outbound` forwarding rule on the external load balancer. \n\n4. Login to the VM-Series firewalls using the `VMSERIES_ACTIVE` and `VMSERIES_PASSIVE` output values.\n\n5. After login, take note of the HA Status in the bottom right corner on each firewall.\n\n    \u003cb\u003eActive Firewall\u003c/b\u003e\u003c/br\u003e\n    \u003cimg src=\"images/image1.png\" width=\"350\"\u003e\n\n    \u003cb\u003ePassive Firewall\u003c/b\u003e\u003c/br\u003e\n    \u003cimg src=\"images/image2.png\" width=\"350\"\u003e\n\n6. Perform a user initiated failover.\n   1. On the ***Active Firewall***, go to the **Device → High Availability → Operational Commands**.\n   2. Click **Suspend local device for high availability**.\n        \u003cimg src=\"images/image3.png\" width=\"630\"\u003e\n   3. When prompted, click **OK** to initiate the failover.\u003c/br\u003e\n        \u003cimg src=\"images/image4.png\" width=\"285\"\u003e\n\n7. You should notice your SSH session to the `workload-vm` is still active.  This indicates the session successfully failed over between the VM-Series firewalls.\n    ```\n    Wed Mar 12 16:47:18 UTC 2023 -- Online -- Source IP = x.x.x.x\n    Wed Mar 12 16:47:19 UTC 2023 -- Online -- Source IP = x.x.x.x\n    Wed Mar 12 16:47:21 UTC 2023 -- Offline\n    Wed Mar 12 16:47:22 UTC 2023 -- Offline\n    Wed Mar 12 16:47:23 UTC 2023 -- Online -- Source IP = x.x.x.x\n    Wed Mar 12 16:47:24 UTC 2023 -- Online -- Source IP = x.x.x.x\n    ```\n\n## (Optional) Onboard Internet Applications\nYou can secure multiple internet facing applications through the VM-Series firewall. This is done by mapping the addreses/ports from external forwarding rules to NAT policies defined on the VM-Series firewall.\n\nIn this section, onboard a new web application by creating a forwarding rule on the external load balancer along with a corresponding NAT policy on the VM-Series. \n\n\n### Create an application VM\nIn Cloud Shell, deploy new virtual machine (`app-vm`) to a subnet within the trust VPC network.  The `app-vm` installs a simple web application through its metadata startup script (`/scripts/app_startup.sh`).\n\n1. In Cloud Shell, set environment variables for your `PROJECT_ID`, `REGION`, `ZONE`, \u0026 `SUBNET` for the application environment.\n\n    \u003cp\u003e\u003cpre\u003e\n    export \u003ci\u003e\u003cb\u003ePROJECT_ID\u003c/b\u003e=YOUR_PROJECT_ID\u003c/i\u003e\n    export \u003ci\u003e\u003cb\u003eREGION\u003c/b\u003e=YOUR_REGION\u003c/i\u003e\n    export \u003ci\u003e\u003cb\u003eZONE\u003c/b\u003e=YOUR_ZONE\u003c/i\u003e\n    export \u003ci\u003e\u003cb\u003eSUBNET\u003c/b\u003e=SUBNET_NAME\u003c/i\u003e\u003c/pre\u003e\u003c/p\u003e\n\n\u003e [!TIP]  \n\u003e The `app-vm` can be deployed to any subnet in the `trust-vpc`, or to any VPC connected \u0026 routed to the `trust-vpc` (i.e. VPC peering).\n\n\n2. Create the `app-vm` virtual machine. \n\n    ```\n    gcloud compute instances create app-vm \\\n        --project=$PROJECT_ID \\\n        --network-interface subnet=$SUBNET,no-address \\\n        --zone=$ZONE \\\n        --machine-type=n2-standard-2 \\\n        --image-project=debian-cloud \\\n        --image-family=debian-11 \\\n        --metadata startup-script-url=https://raw.githubusercontent.com/PaloAltoNetworks/google-cloud-vmseries-ha-tutorial/main/scripts/app_startup.sh\n    ```\n\n3. Record the `INTERNAL_IP` address of the new virtual machine.\n\n    **Output**\n    \u003cp\u003e\u003cpre\u003e\n    NAME: app-vm\n    ZONE: us-central1-a\n    MACHINE_TYPE: f1-micro\n    PREEMPTIBLE:\n    INTERNAL_IP: \u003ci\u003e\u003cb\u003e10.0.2.4\u003c/b\u003e\u003c/i\u003e\n    EXTERNAL_IP:\n    STATUS: RUNNING\u003c/pre\u003e\u003c/p\u003e\n\n\u003e [!NOTE]\n\u003e In the VM-Series NAT policy, the `INTERNAL_IP` will be set as the **translated packet's** destination address.  \n\n\n### Create Forwarding Rule\nCreate a forwarding rule (`fwd-rule-app-vm`) on the external load balancer.  This rule will be used to distribute internet inbound traffic destined to the `app-vm` through the VM-Series untrust interfaces. \n\n1. Assign the name of the external load balancer's backend service to an environment variable named `EXTERNAL_LB`.\n\n    ```\n    export EXTERNAL_LB=$(gcloud compute backend-services list \\\n        --filter=\"loadBalancingScheme:EXTERNAL\" \\\n        --format=\"get(name)\")\n\n    echo $EXTERNAL_LB\n    ```\n\n2. Create a new forwarding rule on the external load balancer.\n\n    ```\n    gcloud compute forwarding-rules create fwd-rule-app-vm \\\n        --load-balancing-scheme=EXTERNAL \\\n        --region=$REGION \\\n        --ip-protocol=L3_DEFAULT \\\n        --ports=ALL \\\n        --backend-service=$EXTERNAL_LB\n    ```\n\n    \n3. Retrieve the forwarding rule's address.\n\n    ```\n    gcloud compute forwarding-rules describe fwd-rule-app-vm \\\n        --region=$REGION \\\n        --format='get(IPAddress)'\n    ```\n    \n\u003e [!NOTE]\n\u003e In the firewall's NAT rule, the forwarding rule address is set as the **original packet's** destination address.  \n\n### Create NAT Policy\nOn the VM-Series, create a NAT policy to translate traffic destined the forwarding rule (`fwd-rule-app-vm`) to the internal IPv4 address of the `app-vm` IP address (i.e. `10.0.2.4`).\n\n1. On the *active* VM-Series, go to **Policies → NAT**.  \n\n2. Click **Add** and enter a name for the rule (i.e. `inbound-app-vm`). \n\n2. Configure the **Original Packet** as follows:\n\n    | Field                   | Value                                                        |\n    | ----------------------- | ------------------------------------------------------------ |\n    | **Source Zone**         | `untrust`                                                    |\n    | **Destination Zone**    | `untrust`                                                    |\n    | **Service**             | `service-http`                                               |\n    | **Destination Address** | The forwarding rule's IPv4 adddress (i.e. `34.172.143.223`). |\n\n    \u003cimg src=\"images/nat1.png\" width=\"630\"\u003e\n\n3. In the **Translated Packet** tab, configure the **Destination Address Translation** as follows:\n\n    | Field                  | Value                                               |\n    | ---------------------- | --------------------------------------------------- |\n    | **Translation Type**   | `Static IP` or `Dynamic IP`                         |\n    | **Translated Address** | The `INTERNAL_IP` of the `app-vm` (i.e. `10.0.2.4`) |\n\n    \u003cimg src=\"images/nat2.png\" width=\"630\"\u003e\n\n4. Click **OK** to create the rule.\n\n5. Click **Commit** to apply the changes.\n\n6. After the commit completes, access the sample application using the address of the forwarding rule.\n    ```\n    http://34.172.143.223\n    ```\n    \u003cimg src=\"images/image5.png\" width=\"400\"\u003e\n\n7. On the *active* VM-Series, go to **Monitor → Traffic** to view the traffic destined to the `app-vm`. \n\n\n## Clean up\n\nTo avoid incurring charges to your Google Cloud account for the resources you created in this tutorial, delete all the resources when you no longer need them.\n\n1. (Optional) If you did the **Onboard Internet Applications** section, delete the forwarding rule (`fwd-rule-app-vm`) and application VM (`app-vm`).\n    \n    ```\n    gcloud compute forwarding-rules delete fwd-rule-app-vm \\\n        --region=$REGION \\\n        --quiet\n\n    gcloud compute instances delete app-vm \\\n        --zone=$ZONE \\\n        --quiet\n    ```\n\n2. Run the following command to delete the resources.\n\n    ```\n    terraform destroy\n    ```\n    \n    Enter `yes` to delete the resources.\n\n3. After all the resources are deleted, Terraform displays the following message.\n\n    ```\n    Destroy complete!\n    ```\n\n## Additional information\n\n* Learn about the[ VM-Series on Google Cloud](https://docs.paloaltonetworks.com/vm-series/10-2/vm-series-deployment/set-up-the-vm-series-firewall-on-google-cloud-platform/about-the-vm-series-firewall-on-google-cloud-platform).\n* Getting started with [Palo Alto Networks PAN-OS](https://docs.paloaltonetworks.com/pan-os). \n* Read about [securing Google Cloud Networks with the VM-Series](https://cloud.google.com/architecture/partners/palo-alto-networks-ngfw).\n* Learn about [VM-Series licensing on all platforms](https://docs.paloaltonetworks.com/vm-series/10-2/vm-series-deployment/license-the-vm-series-firewall/vm-series-firewall-licensing.html#id8fea514c-0d85-457f-b53c-d6d6193df07c).\n* Use the [VM-Series Terraform modules for Google Cloud](https://registry.terraform.io/modules/PaloAltoNetworks/vmseries-modules/google/latest). ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaloaltonetworks%2Fgoogle-cloud-vmseries-ha-tutorial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaloaltonetworks%2Fgoogle-cloud-vmseries-ha-tutorial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaloaltonetworks%2Fgoogle-cloud-vmseries-ha-tutorial/lists"}