Skip to main content

Palo Alto Networks Panorama example

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

NOTE: Panorama will take a serveral minutes to bootup during the initial setup.

GitHub Logo Terraform Logo

Topology​

The topology consists of :

  • VPC with 2 subnets in 2 availability zones
  • 2 Panorama instances with a public IP addresses and static private IP addresses

image

PAN-OS software version​

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

Prerequisites​

  1. Prepare panorama license
  2. 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-swfw-modules
  3. Go to Panorama example: cd terraform-aws-swfw-modules/examples/panorama_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 Panorama instance(s): terraform output panorama_public_ips
  2. Connect to the Panorama instance(s) via SSH using your associated private key: ssh admin@x.x.x.x -i /PATH/TO/YOUR/KEY/id_rsa
  3. Set admin password:
> configure
# set mgt-config users admin password

Access Panorama​

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.5.0, < 2.0.0
aws~> 5.17

Providers​

NameVersion
aws~> 5.17

Modules​

NameSourceVersion
panorama../../modules/panoraman/a
subnet_sets../../modules/subnet_setn/a
vpc../../modules/vpcn/a
vpc_routes../../modules/vpc_routen/a

Resources​

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

Inputs​

NameDescriptionTypeDefaultRequired
global_tagsGlobal tags configured for all provisioned resourcesmap(any){}no
name_prefixPrefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.)string""no
panoramasA map defining Panorama instances

Following properties are available:
- instances: map of Panorama instances with attributes:
- az: name of the Availability Zone
- private_ip_address: private IP address for management interface
- panos_version: PAN-OS version used for Panorama
- network: definition of network settings in object with attributes:
- vpc: name of the VPC (needs to be one of the keys in map vpcs)
- subnet_group - key of the subnet group
- security_group: security group assigned to ENI used by Panorama
- create_public_ip: true, if public IP address for management should be created
- ebs: EBS settings defined in object with attributes:
- volumes: list of EBS volumes attached to each instance
- kms_key_alias: KMS key alias used for encrypting Panorama EBS
- iam: IAM settings in object with attrbiutes:
- create_role: enable creation of IAM role
- role_name: name of the role to create or use existing one
- enable_imdsv2: whether to enable IMDSv2 on the EC2 instance

Example:{
panorama_ha_pair = {
instances = {
"primary" = {
az = "eu-central-1a"
private_ip_address = "10.255.0.4"
}
"secondary" = {
az = "eu-central-1b"
private_ip_address = "10.255.1.4"
}
}

panos_version = "10.2.3"

network = {
vpc = "management_vpc"
subnet_group = "mgmt"
security_group = "panorama_mgmt"
create_public_ip = true
}

ebs = {
volumes = [
{
name = "ebs-1"
ebs_device_name = "/dev/sdb"
ebs_size = "2000"
ebs_encrypted = true
},
{
name = "ebs-2"
ebs_device_name = "/dev/sdc"
ebs_size = "2000"
ebs_encrypted = true
}
]
kms_key_alias = "aws/ebs"
}

iam = {
create_role = true
role_name = "panorama"
}

enable_imdsv2 = false
}
}
map(object({
instances = map(object({
az = string
private_ip_address = string
}))

panos_version = string

network = object({
vpc = string
subnet_group = string
security_group = string
create_public_ip = bool
})

ebs = object({
volumes = list(object({
name = string
ebs_device_name = string
ebs_size = string
}))
encrypted = bool
kms_key_alias = string
})

iam = object({
create_role = bool
role_name = string
})

enable_imdsv2 = bool
}))
{}no
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
vpcsA map defining VPCs with security groups and subnets.

Following properties are available:
- name: VPC name
- cidr: CIDR for VPC
- security_groups: map of security groups
- subnets: map of subnets with properties:
- az: availability zone
- subnet_group: identity of the same purpose subnets group such as management
- routes: map of routes with properties:
- vpc: key of VPC
- subnet_group - key of the subnet group
- to_cidr: destination IP range
- 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:{
security_vpc = {
name = "security-vpc"
cidr = "10.100.0.0/16"
security_groups = {
panorama_mgmt = {
name = "panorama_mgmt"
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"]
}
https = {
description = "Permit HTTPS"
type = "ingress", from_port = "443", to_port = "443", protocol = "tcp"
cidr_blocks = ["130.41.247.0/24"]
}
ssh = {
description = "Permit SSH"
type = "ingress", from_port = "22", to_port = "22", protocol = "tcp"
cidr_blocks = ["130.41.247.0/24"]
}
}
}
}
subnets = {
"10.100.0.0/24" = { az = "eu-central-1a", subnet_group = "mgmt" }
"10.100.64.0/24" = { az = "eu-central-1b", subnet_group = "mgmt" }
}
routes = {
mgmt_default = {
vpc = "security_vpc
subnet_group = "mgmt"
to_cidr = "0.0.0.0/0"
next_hop_key = "security_vpc"
next_hop_type = "internet_gateway"
}
}
}
}
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 = optional(string)
to_port = optional(string)
}))
}))
security_groups = map(object({
name = string
rules = map(object({
description = string
type = string
from_port = string
to_port = string
protocol = string
cidr_blocks = list(string)
}))
}))
subnets = map(object({
az = string
subnet_group = string
nacl = optional(string)
create_subnet = optional(bool, true)
create_route_table = optional(bool, true)
existing_route_table_id = optional(string)
associate_route_table = optional(bool, true)
route_table_name = optional(string)
local_tags = optional(map(string), {})
}))
routes = map(object({
vpc = string
subnet_group = string
to_cidr = string
next_hop_key = string
next_hop_type = string
}))
}))
{}no

Outputs​

NameDescription
panorama_private_ipsMap of private IPs for Panorama instances.
panorama_public_ipsMap of public IPs for Panorama instances.
panorama_urlsMap of URLs for Panorama instances.