Background
Palo Alto Networks firewalls support a process known as ‘bootstrapping’ which allows you create a repeatable way of provisioning your new firewalls. It allows you deploy basic configuration to the firewall upon startup.
Some of the basic configuration you can push to the firewall as part of the bootstrap include DNS servers, management interface IP address, Panorama server addresses, device group, template etc. The option to define the Panorama that the firewall should be managed by as well as the device group and template can be very useful in large environments where new firewalls constantly need to be provisioned.
At its core, the bootstrap process requires the firewall to locate a file called init-cfg.txt upon startup. In this file, the basic configuration for the firewall is defined. As a result, to successfully complete the bootstrap process, the firewall admin must provide the means for the firewall to retrieve this init-cfg.txt file.
Implementation
In this scenario, I use an S3 bucket in AWS to host my init-cfg-txt file. The different bootstrap methods support by Palo Alto Networks VM-series are documented here.
To successfully bootstrap this firewall, I need the following key resources:
- an S3 bucket to host my init-cfg.txt file and other mandatory directories
- an VM-series firewall EC2 instance
- an IAM policy defining actions that are allowed on my S3 bucket
- an IAM role that my VM-series instance can assume to access the S3 bucket
- an IAM instance profile to be applied to my VM-series instance
- a file called init-cfg.txt with my basic configuration defined
The diagram below depicts how these resources work together
Now that we’ve summarised the different resources needed, let’s take a look at the init-cfg.txt file and the terraform code. For brevity, I’ve excluded terraform code for resources such as VPC, subnets, route tables and internet gateway that were also created in order for me to provision and EC2 instance.
First, I created my init-cfg.txt file with the below basic configuration:
type=dhcp-client
hostname=bootstrap_lab_fw
dns-primary=169.254.169.253
dns-secondary=8.8.8.8
dhcp-send-hostname=yes
dhcp-send-client-id=yes
dhcp-accept-server-hostname=no
dhcp-accept-server-domain=yes
Then I created the S3 bucket and the mandatory directories for bootstrap. I also uploaded my init-cfg.txt file to the S3 bucket by creating an S3 object
### S3 Bucket and directories ###
resource "aws_s3_bucket" "bootstrap_bucket" {
bucket = "palo-bootstrap-bucket-1123"
tags = {
Name = "palo-bootstrap-bucket-1123"
Environment = "Dev"
}
}
resource "aws_s3_object" "config_object" {
bucket = aws_s3_bucket.bootstrap_bucket.id
key = "config/init-cfg.txt"
source = "./init-cfg.txt"
etag = filemd5("./init-cfg.txt")
}
resource "aws_s3_object" "content_object" {
bucket = aws_s3_bucket.bootstrap_bucket.id
key = "content/"
}
resource "aws_s3_object" "license_object" {
bucket = aws_s3_bucket.bootstrap_bucket.id
key = "license/"
}
resource "aws_s3_object" "software_object" {
bucket = aws_s3_bucket.bootstrap_bucket.id
key = "software/"
}
Following that, I created my IAM policy, IAM role and IAM instance profile
resource "aws_iam_policy" "firewall_instance_policy" {
name = "firewall_bootstrap_policy"
description = "Defines permissions that firewall being bootstrapped can carry out"
policy = jsonencode(
{
Version = "2012-10-17"
Statement = [
{
Action = "s3:ListBucket"
Effect = "Allow"
Resource = "arn:aws:s3:::${aws_s3_bucket.bootstrap_bucket.bucket}"
},
{
Action = "s3:GetObject"
Effect = "Allow"
Resource = "arn:aws:s3:::${aws_s3_bucket.bootstrap_bucket.bucket}/*"
},
]
}
)
}
data "aws_iam_policy_document" "assume_role_policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
}
}
resource "aws_iam_role" "firewall_instance_role" {
name = "firewall_instance_role"
assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json
managed_policy_arns = [aws_iam_policy.firewall_instance_policy.arn]
}
resource "aws_iam_instance_profile" "test_profile" {
name = "firewall_instance_profile"
role = aws_iam_role.firewall_instance_role.name
}
With those created, I then provisioned my VM-series EC2 instance:
resource "aws_instance" "lab_firewall_instance" {
ami = "var.ami"
instance_type = "m5.large"
network_interface {
network_interface_id = aws_network_interface.management_interface.id
device_index = 0
}
key_name = "fw_bootstrap_key_pair"
iam_instance_profile = aws_iam_instance_profile.test_profile.name
user_data = "vmseries-bootstrap-aws-s3bucket=${aws_s3_bucket.bootstrap_bucket.id}"
}
After defining all the required resources, I ran terraform apply
to provision them.
Verifying
After provisioning the resources, I accessed the firewall via SSH and ran the command show log system
to verify that bootstrap completed successfully. The following snippets from the system logs verify that bootstrap was successful:
2023/11/11 14:04:23 info general general 0 init-cfg: initial configuration processed from init cfg file
...
2023/11/11 14:04:23 info hw bootstr 0 Media detected successfully
2023/11/11 14:04:23 info hw bootstr 0 Media sanity check successful
...
2023/11/11 14:04:40 info hw bootstr 0 Bootstrap successfully completed sw-version: 10.2.4; app-version: 8638-7689; threat-version: 8638-7689
The show system bootstrap status also provides of summary of the bootstrap status:
admin@bootstrap_lab_fw> show system bootstrap status
Bootstrap Phase Status Details
=============== ====== =======
Media Detection Success Media detected successfully
Media Sanity Check Success Media sanity check successful
Parsing of Initial Config Successful
Auto-commit Successful
Additionally, I used the show system info
command to verify settings such as the hostname specified in the init-cfg.txt file were successfully applied
admin@bootstrap_lab_fw> show system info
hostname: bootstrap_lab_fw
While this lab exercise only applied the hostname and DNS servers, other configuration can be applied to the Palo Alto Networks firewall during the bootstrap process. A sample init-cfg.txt file with other parameters that can be configured can be seen on the Palo Alto Networks website here.