Palo Alto Networks Application Load Balancer Module for AWS
A Terraform module for deploying an Application Load Balancer in AWS cloud. This is always a public Load Balancer with Target Groups of IP
type. It is intended to be placed just in front of Next Generation Firewalls.
Usage
Example usage:
- The code below is designed to be used with
vmseries
,vpc
andsubnet_set
modules. Check these modules for information on outputs used in this code. - Firewalls' public facing interfaces are placed in a subnet set called untrust.
- There are two rules shown below:
defaults
rule shows a minimum setup that uses only default valueshttps-custom
rule shows some of the configurable properties and example values.
module "public_alb" {
source = "../../modules/alb"
lb_name = "public-alb"
region = var.region
subnets = { for k, v in module.security_subnet_sets["untrust"].subnets : k => { id = v.id } }
desync_mitigation_mode = "monitor"
vpc_id = module.security_vpc.id
configure_access_logs = true
access_logs_s3_bucket_name = "alb-logs-bucket"
security_groups = [module.security_vpc.security_group_ids["load_balancer"]]
rules = {
"defaults" = {
protocol = "HTTP"
listener_rules = {
"1" = {
target_port = 8080
target_protocol = "HTTP"
host_headers = ["default.com", "www.default.com"]
}
}
}
"https-custom" = {
protocol = "HTTPS"
port = 443
certificate_arn = "arn:aws:acm:eu-west-1:123456789012:certificate/97bd27c1-3822-4082-967d-d7084e0fe52f"
health_check_port = "80"
health_check_protocol = "HTTP"
health_check_matcher = "302"
health_check_path = "/"
health_check_interval = 10
listener_rules = {
"1" = {
target_port = 8443
target_protocol = "HTTP"
host_headers = ["www.custom.org"]
http_request_method = ["GET", "HEAD"]
}
"2" = {
target_port = 8444
target_protocol = "HTTP"
host_headers = ["api.custom.org"]
http_request_method = ["POST", "OPTIONS", "DELETE"]
}
}
}
}
targets = { for k, v in var.vmseries : k => module.vmseries[k].interfaces["untrust"].private_ip }
tags = var.global_tags
}
Reference
Requirements
Name | Version |
---|---|
terraform | >= 1.0.0, < 2.0.0 |
aws | ~> 5.17 |
Providers
Name | Version |
---|---|
aws | ~> 5.17 |
Modules
No modules.
Resources
Name | Type |
---|---|
aws_lb.this | resource |
aws_lb_listener.this | resource |
aws_lb_listener_rule.this | resource |
aws_lb_target_group.this | resource |
aws_lb_target_group_attachment.this | resource |
aws_s3_bucket.this | resource |
aws_s3_bucket_acl.this | resource |
aws_s3_bucket_policy.this | resource |
aws_s3_bucket_public_access_block.this | resource |
aws_s3_bucket_server_side_encryption_configuration.example | resource |
aws_s3_bucket_versioning.this | resource |
aws_elb_service_account.this | data source |
aws_iam_policy_document.this | data source |
aws_partition.this | data source |
aws_s3_bucket.this | data source |
Inputs
Name | Description | Type | Default | Required |
---|---|---|---|---|
access_logs_byob | Bring Your Own Bucket - in case you would like to re-use an existing S3 Bucket for Load Balancer's access logs. NOTICE. This code does not set up proper Bucket Policies for existing buckets. They have to be already in place. | bool | false | no |
access_logs_s3_bucket_name | Name of an S3 Bucket that will be used as storage for Load Balancer's access logs. When used with configure_access_logs it becomes the name of a newly created S3 Bucket.When used with access_logs_byob it is a name of an existing bucket. | string | "pantf-alb-access-logs-bucket" | no |
access_logs_s3_bucket_prefix | A path to a location inside a bucket under which access logs will be stored. When omitted defaults to the root folder of a bucket. | string | null | no |
configure_access_logs | Configure Load Balancer to store access logs in an S3 Bucket. When used with access_logs_byob set to false forces creation of a new bucket.If, however, access_logs_byob is set to true an existing bucket can be used.The name of the newly created or existing bucket is controlled via access_logs_s3_bucket_name . | bool | false | no |
desync_mitigation_mode | Determines how the Load Balancer handles requests that might pose a security risk to an application due to HTTP desync. Defaults to AWS default. For possible values and current defaults refer to documentation. | string | null | no |
drop_invalid_header_fields | Indicates whether HTTP headers with header fields that are not valid are removed by the Load Balancer or not. | bool | false | no |
enable_cross_zone_load_balancing | Enable load balancing between instances in different AZs. Defaults to true . Change to false only if absolutely necessary. By default, there is only one FW in each AZ. Turning this off means 1:1 correlation between a public IP assigned to an AZ and a FW deployed in that AZ. | bool | true | no |
idle_timeout | The time in seconds that the connection to the Load Balancer can be idle. | number | 60 | no |
lb_name | Name of the Load Balancer to be created. | string | n/a | yes |
rules | An object that contains the listener, listener_rules, target group, and health check configuration. It consists of maps of applications with their properties, like in the following example: The application_name key is valid only for letters, numbers and a dash (- ) - that's an AWS limitation.There is always one listener created per application. The listener has always a default action that responds with 503 . This should be treated as a catch-all rule. For the listener to send traffic to backends a listener rule has to be created. This is controlled via the listener_rules map. A key in this map is the priority of the listener rule. Priority can be between 1 and 50000 (AWS specifics). All properties under a particular key refer to either rule's condition(s) or the target group that should receive traffic if a rule is met. Rule conditions - at least one but not more than five of: host_headers , http_headers , http_request_method , path_pattern , query_strings or source_ip has to be set. For more information on what conditions can be set for each type refer to documentation.Target group - keep in mind that all target group attachments are always pointing to VMSeries' public interfaces. The difference between target groups for each rule is the protocol and/or port to which the traffic is being directed. And these are the only properties you can configure ( target_protocol , protocol_version and target_port respectively).The listener_rules map presents as follows:
EXAMPLE
| any | n/a | yes |
security_groups | A list of security group IDs to use with a Load Balancer. If security groups are created with a VPC module you can use output from that module like this:
load_balancer_security_group key refer to the VPC module documentation. | list(string) | n/a | yes |
subnets | Map of subnets used with a Load Balancer. Each key is the availability zone name and the value is an object that has an attributeid identifying AWS subnet.Examples: You can define the values directly: You can also use output from the subnet_sets module:
|
| n/a | yes |
tags | Map of AWS tags to apply to all the created resources. | map(string) | {} | no |
target_group_az | Availability Zones of Target Group ('all' for target group outside of VPC) | string | null | no |
targets | A list of backends accepting traffic. For Application Load Balancer all targets are of type IP . This is because this is the only option that allows a direct routing between a Load Balancer and a specific VMSeries' network interface. The Application Load Balancer is meant to be always public, therefore the VMSeries IPs should be from the public facing subnet. An example on how to feed this variable with data:
var.vmseries check the vmseries module. The key is the VM name. By using those keys, we can loop through all vmseries modules and take the private IP from the interface that is assigned to the subnet we require. The subnet can be identified by the subnet set name (like above). In other words, the for loop returns the following map:
| map(string) | n/a | yes |
vpc_id | ID of the security VPC for the Load Balancer. | string | n/a | yes |
Outputs
Name | Description |
---|---|
lb_fqdn | A FQDN for the Load Balancer. |
target_group | n/a |