# README


show_in_hub: false

Palo Alto Networks VM-Series example

A Terraform example for deploying a one or more instances of VM-Series in one or more VPCs in AWS Cloud.

This example can be used to familarize oneself with both the VM-Series NGFW and Terraform - it creates a single instance of virtualized firewall in a Security VPC with a management-only interface and lacks any traffic inspection.

For a more complex scenario of using the vmseries module - including traffic inspection, check the rest of our Examples.

NOTE 1: VM-Series will take a serveral minutes to bootup during the initial setup.

NOTE 2: The Security Group attached to the Management interface uses an inbound rule allowing traffic to port 22 and 443 from 0.0.0.0/0, which means that SSH and HTTP access to the NFGW is possible from all over the Internet. You should update the Security Group rules and limit access to the Management interface, for example - to only the public IP address from which you will connect to VM-Series.

Topology

The topology consists of :

  • VPC with 1 subnet in 1 availability zones
  • 1 VM-Series instances with a public IP address and static private IP address

PAN-OS software version

Example was prepared for PAN-OS in 10.2.3 version. For more information about recommended software versions see Support PAN-OS Software Release Guidance.

Bootstrap

Terraform example is deploying VM-Series using the User Data bootstrap method. More information about possible options, which can be configured in Uset Data, can be found in table describing the bootstrap parameters.

Prerequisites

  1. Configure the Terraform AWS provider

Usage

  1. Access AWS CloudShell or any other environment which has access to your AWS account
  2. Clone the repository: git clone https://github.com/PaloAltoNetworks/terraform-aws-vmseries-modules
  3. Go to Panorama example: cd terraform-aws-vmseries-modules/examples/vmseries_standalone
  4. Copy example.tfvars into terraform.tfvars
  5. Review terraform.tfvars file, especially with lines commented by # TODO: update here
  6. Initialize Terraform: terraform init
  7. Prepare plan: terraform plan
  8. Deploy infrastructure: terraform apply -auto-approve
  9. Destroy infrastructure if needed: terraform destroy -auto-approve

Configuration

  1. Get public IP for each VM-Series instance(s): terraform output vmseries_public_ips
  2. Connect to the Panorama instance(s) via SSH using your associated private key: ssh [email protected] -i /PATH/TO/YOUR/KEY/id_rsa
  3. Set admin password:
> configure
# set mgt-config users admin password

Access VM-Series

Use a web browser to access https://x.x.x.x and login with admin and your previously configured password

Reference

Requirements

NameVersion
terraform>= 1.0.0, < 2.0.0
aws~> 5.17

Providers

NameVersion
aws~> 5.17

Modules

NameSourceVersion
bootstrap../../modules/bootstrapn/a
subnet_sets../../modules/subnet_setn/a
vmseries../../modules/vmseriesn/a
vpc../../modules/vpcn/a
vpc_routes../../modules/vpc_routen/a

Resources

NameType
aws_iam_role_policy.thisresource
aws_caller_identity.thisdata source
aws_partition.thisdata source

Inputs

NameDescriptionTypeDefaultRequired
global_tagsGlobal tags configured for all provisioned resourcesanyn/ayes
name_prefixPrefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.)stringn/ayes
regionAWS region used to deploy whole infrastructurestringn/ayes
ssh_key_nameName of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxesstringn/ayes
vmseriesA map defining VM-Series instances
Following properties are available:
- instances: map of VM-Series instances
- bootstrap_options: VM-Seriess bootstrap options used to connect to Panorama
- panos_version: PAN-OS version used for VM-Series
- ebs_kms_id: alias for AWS KMS used for EBS encryption in VM-Series
- vpc: key of VPC
Example:
vmseries = {
vmseries = {
instances = {
"01" = { az = "eu-central-1a" }
}
# Value of panorama-server, auth-key, dgname, tplname can be taken from plugin sw_fw_license
bootstrap_options = {
mgmt-interface-swap = "enable"
plugin-op-commands = "panorama-licensing-mode-on,aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable"
dhcp-send-hostname = "yes"
dhcp-send-client-id = "yes"
dhcp-accept-server-hostname = "yes"
dhcp-accept-server-domain = "yes"
}
panos_version = "10.2.3" # TODO: update here
ebs_kms_id = "alias/aws/ebs" # TODO: update here

# Value of vpc must match key of objects stored in vpcs
vpc = "security_vpc"

interfaces = {
mgmt = {
device_index = 1
private_ip = "10.100.0.4"
security_group = "vmseries_mgmt"
vpc_subnet = "security_vpc-mgmt"
create_public_ip = true
source_dest_check = true
eip_allocation_id = null
}
}
}
}
map(object({
instances = map(object({
az = string
}))

bootstrap_options = object({
mgmt-interface-swap = string
panorama-server = string
tplname = string
dgname = string
plugin-op-commands = string
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = string
})

panos_version = string
ebs_kms_id = string

vpc = string

interfaces = map(object({
device_index = number
private_ip = map(string)
security_group = string
vpc_subnet = string
create_public_ip = bool
source_dest_check = bool
eip_allocation_id = map(string)
}))
}))
{}no
vpcsA map defining VPCs with security groups and subnets.

Following properties are available:
- name: VPC name
- cidr: CIDR for VPC
- nacls: map of network ACLs
- security_groups: map of security groups
- subnets: map of subnets with properties:
- az: availability zone
- set: internal identifier referenced by main.tf
- nacl: key of NACL (can be null)
- routes: map of routes with properties:
- vpc_subnet - built from key of VPCs concatenate with - and key of subnet in format: VPCKEY-SUBNETKEY
- next_hop_key - must match keys use to create TGW attachment, IGW, GWLB endpoint or other resources
- next_hop_type - internet_gateway, nat_gateway, transit_gateway_attachment or gwlbe_endpoint

Example:
vpcs = {
example_vpc = {
name = "example-spoke-vpc"
cidr = "10.104.0.0/16"
nacls = {
trusted_path_monitoring = {
name = "trusted-path-monitoring"
rules = {
allow_inbound = {
rule_number = 300
egress = false
protocol = "-1"
rule_action = "allow"
cidr_block = "0.0.0.0/0"
from_port = null
to_port = null
}
}
}
}
security_groups = {
example_vm = {
name = "example_vm"
rules = {
all_outbound = {
description = "Permit All traffic outbound"
type = "egress", from_port = "0", to_port = "0", protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
}
subnets = {
"10.104.0.0/24" = { az = "eu-central-1a", set = "vm", nacl = null }
}
routes = {
vm_default = {
vpc_subnet = "app1_vpc-app1_vm"
to_cidr = "0.0.0.0/0"
next_hop_key = "app1"
next_hop_type = "transit_gateway_attachment"
}
}
}
}
map(object({
name = string
cidr = string
nacls = map(object({
name = string
rules = map(object({
rule_number = number
egress = bool
protocol = string
rule_action = string
cidr_block = string
from_port = string
to_port = string
}))
}))
security_groups = any
subnets = map(object({
az = string
set = string
nacl = string
}))
routes = map(object({
vpc_subnet = string
to_cidr = string
next_hop_key = string
next_hop_type = string
}))
}))
{}no

Outputs

NameDescription
vmseries_public_ipsMap of public IPs created within vmseries module instances.